1. diff --git a/doc/script_commands.txt b/doc/script_commands.txt
  2. index b006040..e7fd382 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,9 @@ 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_SET_FLY * resultingSource = Creature
  21. + * datalong = bool 0=off, 1=on
  22. + * data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL set UNIT_STAT_IGNORE_PATHFINDING
  23. +
  24. +40 SCRIPT_COMMAND_DESPAWN_GO * resultingTarget = GameObject
  25. diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
  26. index 9bbb2df..9bf88ed 100644
  27. --- a/src/game/CreatureAI.h
  28. +++ b/src/game/CreatureAI.h
  29. @@ -70,10 +70,14 @@ enum AIEventType
  30. AI_EVENT_CUSTOM_EVENTAI_A = 5, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  31. AI_EVENT_CUSTOM_EVENTAI_B = 6, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  32. AI_EVENT_GOT_CCED = 7, // Sender = CCed Npc, Invoker = Caster that CCed
  33. - MAXIMAL_AI_EVENT_EVENTAI = 8,
  34. + AI_EVENT_CUSTOM_EVENTAI_C = 8, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  35. + AI_EVENT_CUSTOM_EVENTAI_D = 9, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  36. + AI_EVENT_CUSTOM_EVENTAI_E = 10, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  37. + AI_EVENT_CUSTOM_EVENTAI_F = 11, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
  38. + MAXIMAL_AI_EVENT_EVENTAI = 12,
  39. // Internal Use
  40. - AI_EVENT_CALL_ASSISTANCE = 10, // Sender = Attacked Npc, Invoker = Enemy
  41. + AI_EVENT_CALL_ASSISTANCE = 13, // Sender = Attacked Npc, Invoker = Enemy
  42. // Predefined for SD2
  43. AI_EVENT_START_ESCORT = 100, // Invoker = Escorting Player
  44. diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp
  45. index 32cf3e2..a1c9269 100644
  46. --- a/src/game/ScriptMgr.cpp
  47. +++ b/src/game/ScriptMgr.cpp
  48. @@ -691,7 +691,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
  49. }
  50. break;
  51. }
  52. - case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
  53. + case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
  54. {
  55. if (tmp.sendAIEvent.eventType >= MAXIMAL_AI_EVENT_EVENTAI)
  56. {
  57. @@ -725,6 +725,9 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
  58. }
  59. break;
  60. }
  61. + case SCRIPT_COMMAND_SET_FLY: // 39
  62. + case SCRIPT_COMMAND_DESPAWN_GO: // 40
  63. + break;
  64. default:
  65. {
  66. sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command);
  67. @@ -1864,14 +1867,19 @@ bool ScriptAction::HandleScriptStep()
  68. }
  69. return terminateResult;
  70. }
  71. - case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
  72. + case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
  73. {
  74. if (LogIfNotCreature(pSource))
  75. return false;
  76. if (LogIfNotUnit(pTarget))
  77. break;
  78. - ((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
  79. + // if radius is provided send AI event around
  80. + if (m_script->sendAIEvent.radius)
  81. + ((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
  82. + // else if no radius and target is creature send AI event to target
  83. + else if (pTarget->GetTypeId() == TYPEID_UNIT)
  84. + ((Creature*)pSource)->AI()->SendAIEvent(AIEventType(m_script->sendAIEvent.eventType), NULL, (Creature*)pTarget);
  85. break;
  86. }
  87. case SCRIPT_COMMAND_SET_FACING: // 36
  88. @@ -1952,6 +1960,38 @@ bool ScriptAction::HandleScriptStep()
  89. MailDraft(m_script->sendMail.mailTemplateId).SendMailTo(static_cast<Player*>(pTarget), sender, MAIL_CHECK_MASK_HAS_BODY, deliverDelay);
  90. break;
  91. }
  92. + case SCRIPT_COMMAND_SET_FLY: // 39
  93. + {
  94. + if (LogIfNotCreature(pSource))
  95. + break;
  96. +
  97. + // sometimes we need to ignore pathfinding for flying creatures
  98. + if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL)
  99. + {
  100. + if (m_script->fly.fly)
  101. + ((Creature*)pSource)->addUnitState(UNIT_STAT_IGNORE_PATHFINDING);
  102. + else
  103. + ((Creature*)pSource)->clearUnitState(UNIT_STAT_IGNORE_PATHFINDING);
  104. + }
  105. +
  106. + // enable / disable the fly anim flag
  107. + if (m_script->fly.fly)
  108. + pSource->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
  109. + else
  110. + pSource->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
  111. +
  112. + ((Creature*)pSource)->SetLevitate(m_script->fly.fly);
  113. + break;
  114. + }
  115. + case SCRIPT_COMMAND_DESPAWN_GO: // 40
  116. + {
  117. + if (LogIfNotGameObject(pTarget))
  118. + break;
  119. +
  120. + // ToDo: Change this to pGo->ForcedDespawn() when function is implemented!
  121. + ((GameObject*)pTarget)->SetLootState(GO_JUST_DEACTIVATED);
  122. + break;
  123. + }
  124. default:
  125. sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command);
  126. break;
  127. diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h
  128. index 9b5069c..31e4f29 100644
  129. --- a/src/game/ScriptMgr.h
  130. +++ b/src/game/ScriptMgr.h
  131. @@ -101,7 +101,7 @@ enum ScriptCommand // resSource, resTar
  132. SCRIPT_COMMAND_XP_USER = 33, // source or target with Player, datalong = bool (0=off, 1=on)
  133. 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
  134. // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL terminate when condition is false ELSE terminate when condition is true
  135. - SCRIPT_COMMAND_SEND_AI_EVENT_AROUND = 35, // resSource = Creature, resTarget = Unit
  136. + SCRIPT_COMMAND_SEND_AI_EVENT = 35, // resSource = Creature, resTarget = Unit
  137. // datalong = AIEventType
  138. // datalong2 = radius
  139. SCRIPT_COMMAND_SET_FACING = 36, // resSource = Creature, resTarget WorldObject. Turn resSource towards Taget
  140. @@ -117,6 +117,10 @@ enum ScriptCommand // resSource, resTar
  141. // datalong: Send mailTemplateId from resSource (if provided) to player resTarget
  142. // datalong2: AlternativeSenderEntry. Use as sender-Entry
  143. // dataint1: Delay (>= 0) in Seconds
  144. + SCRIPT_COMMAND_SET_FLY = 39, // resSource = Creature
  145. + // datalong = bool 0=off, 1=on
  146. + // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL set UNIT_STAT_IGNORE_PATHFINDING
  147. + SCRIPT_COMMAND_DESPAWN_GO = 40, // resTarget = GameObject
  148. };
  149. #define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK, SCRIPT_COMMAND_EMOTE, SCRIPT_COMMAND_CAST_SPELL, SCRIPT_COMMAND_TERMINATE_SCRIPT
  150. @@ -364,6 +368,14 @@ struct ScriptInfo
  151. uint32 altSender; // datalong2;
  152. } sendMail;
  153. + struct // SCRIPT_COMMAND_SET_FLY (39)
  154. + {
  155. + uint32 fly; // datalong
  156. + uint32 empty; // datalong2
  157. + } fly;
  158. +
  159. + // datalong unsed // SCRIPT_COMMAND_DESPAWN_GO (40)
  160. +
  161. struct
  162. {
  163. uint32 data[2];
  164. @@ -406,6 +418,7 @@ struct ScriptInfo
  165. case SCRIPT_COMMAND_CLOSE_DOOR:
  166. case SCRIPT_COMMAND_ACTIVATE_OBJECT:
  167. case SCRIPT_COMMAND_GO_LOCK_STATE:
  168. + case SCRIPT_COMMAND_DESPAWN_GO:
  169. return false;
  170. default:
  171. return true;
  172. @@ -427,6 +440,7 @@ struct ScriptInfo
  173. case SCRIPT_COMMAND_TERMINATE_COND:
  174. case SCRIPT_COMMAND_SET_FACING:
  175. case SCRIPT_COMMAND_MOVE_DYNAMIC:
  176. + case SCRIPT_COMMAND_SET_FLY:
  177. return true;
  178. default:
  179. return false;