1. diff --git a/doc/script_commands.txt b/doc/script_commands.txt
  2. index b006040..8e8cada 100644
  3. --- a/doc/script_commands.txt
  4. +++ b/doc/script_commands.txt
  5. @@ -296,9 +296,9 @@ Where "A -> B" means that the command is executed from A with B as target.
  6. * !(data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL): terminate when condition is true
  7. data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL: terminate when condition is false
  8. -35 SCRIPT_COMMAND_SEND_AI_EVENT_AROUND * resultingSource = Creature, resultingTarget = Unit
  9. +35 SCRIPT_COMMAND_SEND_AI_EVENT * resultingSource = Creature, resultingTarget = Unit
  10. * datalong = AIEventType - limited only to EventAI supported events
  11. - * datalong2 = radius
  12. + * datalong2 = radius. If radius isn't provided and the target is a creature, then send AIEvent to target
  13. 36 SCRIPT_COMMAND_SET_FACING Turn resultingSource towards resultingTarget
  14. * resultingSource = Creature, resultingTarget WorldObject
  15. @@ -319,3 +319,11 @@ Where "A -> B" means that the command is executed from A with B as target.
  16. * datalong = mailTemplateId
  17. * datalong2: AlternativeSenderEntry. Use as sender-Entry of the sent mail
  18. * dataint1: Delay (>= 0) in Seconds
  19. +
  20. +39 SCRIPT_COMMAND_RESPAWN_SELF * resultingTarget = Creature
  21. +
  22. +40 SCRIPT_COMMAND_SET_FLY * resultingSource = Creature
  23. + * datalong = bool 0=off, 1=on
  24. + * data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL use SetCanFly() instead of SetLevitate() move flag
  25. +
  26. +41 SCRIPT_COMMAND_DESPAWN_GO * resultingTarget = GameObject
  27. diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
  28. index 9bbb2df..9bf88ed 100644
  29. --- a/src/game/CreatureAI.h
  30. +++ b/src/game/CreatureAI.h
  31. @@ -70,10 +70,14 @@ enum AIEventType
  32. AI_EVENT_CUSTOM_EVENTAI_A = 5, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  33. AI_EVENT_CUSTOM_EVENTAI_B = 6, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  34. AI_EVENT_GOT_CCED = 7, // Sender = CCed Npc, Invoker = Caster that CCed
  35. - MAXIMAL_AI_EVENT_EVENTAI = 8,
  36. + AI_EVENT_CUSTOM_EVENTAI_C = 8, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  37. + AI_EVENT_CUSTOM_EVENTAI_D = 9, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  38. + AI_EVENT_CUSTOM_EVENTAI_E = 10, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  39. + AI_EVENT_CUSTOM_EVENTAI_F = 11, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  40. + MAXIMAL_AI_EVENT_EVENTAI = 12,
  41. // Internal Use
  42. - AI_EVENT_CALL_ASSISTANCE = 10, // Sender = Attacked Npc, Invoker = Enemy
  43. + AI_EVENT_CALL_ASSISTANCE = 13, // Sender = Attacked Npc, Invoker = Enemy
  44. // Predefined for SD2
  45. AI_EVENT_START_ESCORT = 100, // Invoker = Escorting Player
  46. diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp
  47. index 32cf3e2..c95bbd0 100644
  48. --- a/src/game/ScriptMgr.cpp
  49. +++ b/src/game/ScriptMgr.cpp
  50. @@ -691,7 +691,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
  51. }
  52. break;
  53. }
  54. - case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
  55. + case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
  56. {
  57. if (tmp.sendAIEvent.eventType >= MAXIMAL_AI_EVENT_EVENTAI)
  58. {
  59. @@ -725,6 +725,10 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
  60. }
  61. break;
  62. }
  63. + case SCRIPT_COMMAND_RESPAWN_SELF: // 39
  64. + case SCRIPT_COMMAND_SET_FLY: // 40
  65. + case SCRIPT_COMMAND_DESPAWN_GO: // 41
  66. + break;
  67. default:
  68. {
  69. sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command);
  70. @@ -1864,14 +1868,19 @@ bool ScriptAction::HandleScriptStep()
  71. }
  72. return terminateResult;
  73. }
  74. - case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
  75. + case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
  76. {
  77. if (LogIfNotCreature(pSource))
  78. return false;
  79. if (LogIfNotUnit(pTarget))
  80. break;
  81. - ((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
  82. + // if radius is provided send AI event around
  83. + if (m_script->sendAIEvent.radius)
  84. + ((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
  85. + // else if no radius and target is creature send AI event to target
  86. + else if (pTarget->GetTypeId() == TYPEID_UNIT)
  87. + ((Creature*)pSource)->AI()->SendAIEvent(AIEventType(m_script->sendAIEvent.eventType), NULL, (Creature*)pTarget);
  88. break;
  89. }
  90. case SCRIPT_COMMAND_SET_FACING: // 36
  91. @@ -1952,6 +1961,43 @@ bool ScriptAction::HandleScriptStep()
  92. MailDraft(m_script->sendMail.mailTemplateId).SendMailTo(static_cast<Player*>(pTarget), sender, MAIL_CHECK_MASK_HAS_BODY, deliverDelay);
  93. break;
  94. }
  95. + case SCRIPT_COMMAND_RESPAWN_SELF: // 39
  96. + {
  97. + // TODO - Remove this check after a while
  98. + if (pTarget && pTarget->GetTypeId() != TYPEID_UNIT && pSource && pSource->GetTypeId() == TYPEID_UNIT)
  99. + {
  100. + sLog.outErrorDb("DB-SCRIPTS: Process table `%s` id %u, command %u target must be creature, but (only) source is, use data_flags to fix", m_table, m_script->id, m_script->command);
  101. + pTarget = pSource;
  102. + }
  103. +
  104. + if (LogIfNotCreature(pTarget))
  105. + break;
  106. +
  107. + ((Creature*)pTarget)->Respawn();
  108. +
  109. + break;
  110. + }
  111. + case SCRIPT_COMMAND_SET_FLY: // 40
  112. + {
  113. + if (LogIfNotCreature(pSource))
  114. + break;
  115. +
  116. + if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL)
  117. + ((Creature*)pSource)->SetCanFly(!m_script->fly.fly);
  118. + else
  119. + ((Creature*)pSource)->SetLevitate(!m_script->fly.fly);
  120. +
  121. + break;
  122. + }
  123. + case SCRIPT_COMMAND_DESPAWN_GO: // 41
  124. + {
  125. + if (LogIfNotGameObject(pTarget))
  126. + break;
  127. +
  128. + // ToDo: Change this to pGo->ForcedDespawn() when function is implemented!
  129. + ((GameObject*)pTarget)->SetLootState(GO_JUST_DEACTIVATED);
  130. + break;
  131. + }
  132. default:
  133. sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command);
  134. break;
  135. diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h
  136. index 9b5069c..a4a4f40 100644
  137. --- a/src/game/ScriptMgr.h
  138. +++ b/src/game/ScriptMgr.h
  139. @@ -101,7 +101,7 @@ enum ScriptCommand // resSource, resTar
  140. SCRIPT_COMMAND_XP_USER = 33, // source or target with Player, datalong = bool (0=off, 1=on)
  141. SCRIPT_COMMAND_TERMINATE_COND = 34, // datalong = condition_id, datalong2 = if != 0 then quest_id of quest that will be failed for player's group if the script is terminated
  142. // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL terminate when condition is false ELSE terminate when condition is true
  143. - SCRIPT_COMMAND_SEND_AI_EVENT_AROUND = 35, // resSource = Creature, resTarget = Unit
  144. + SCRIPT_COMMAND_SEND_AI_EVENT = 35, // resSource = Creature, resTarget = Unit
  145. // datalong = AIEventType
  146. // datalong2 = radius
  147. SCRIPT_COMMAND_SET_FACING = 36, // resSource = Creature, resTarget WorldObject. Turn resSource towards Taget
  148. @@ -117,6 +117,11 @@ enum ScriptCommand // resSource, resTar
  149. // datalong: Send mailTemplateId from resSource (if provided) to player resTarget
  150. // datalong2: AlternativeSenderEntry. Use as sender-Entry
  151. // dataint1: Delay (>= 0) in Seconds
  152. + SCRIPT_COMMAND_RESPAWN_SELF = 39, // resSource = Creature
  153. + SCRIPT_COMMAND_SET_FLY = 40, // resSource = Creature
  154. + // datalong = bool 0=off, 1=on
  155. + // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL use SetCanFly() instead of SetLevitate() move flag
  156. + SCRIPT_COMMAND_DESPAWN_GO = 41, // resTarget = GameObject
  157. };
  158. #define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK, SCRIPT_COMMAND_EMOTE, SCRIPT_COMMAND_CAST_SPELL, SCRIPT_COMMAND_TERMINATE_SCRIPT
  159. @@ -364,6 +369,16 @@ struct ScriptInfo
  160. uint32 altSender; // datalong2;
  161. } sendMail;
  162. + // datalong unused // SCRIPT_COMMAND_RESPAWN_SELF (39)
  163. +
  164. + struct // SCRIPT_COMMAND_SET_FLY (40)
  165. + {
  166. + uint32 fly; // datalong
  167. + uint32 empty; // datalong2
  168. + } fly;
  169. +
  170. + // datalong unsed // SCRIPT_COMMAND_DESPAWN_GO (41)
  171. +
  172. struct
  173. {
  174. uint32 data[2];
  175. @@ -406,6 +421,7 @@ struct ScriptInfo
  176. case SCRIPT_COMMAND_CLOSE_DOOR:
  177. case SCRIPT_COMMAND_ACTIVATE_OBJECT:
  178. case SCRIPT_COMMAND_GO_LOCK_STATE:
  179. + case SCRIPT_COMMAND_DESPAWN_GO:
  180. return false;
  181. default:
  182. return true;
  183. @@ -427,6 +443,7 @@ struct ScriptInfo
  184. case SCRIPT_COMMAND_TERMINATE_COND:
  185. case SCRIPT_COMMAND_SET_FACING:
  186. case SCRIPT_COMMAND_MOVE_DYNAMIC:
  187. + case SCRIPT_COMMAND_SET_FLY:
  188. return true;
  189. default:
  190. return false;