diff --git a/doc/EventAI.txt b/doc/EventAI.txt index 5e8af39ea9..91a149f881 100644 --- a/doc/EventAI.txt +++ b/doc/EventAI.txt @@ -154,7 +154,7 @@ For all ACTION_T_RANDOM Actions, When a Particular Param is selected for the Eve 46 ACTION_T_SET_THROW_MASK EventTypeMask Marks for which AIEvents the npc will throw AIEvents on its own. 47 ACTION_T_SET_STAND_STATE StandState Set the unit stand state (Param1) of the current creature. 48 ACTION_T_CHANGE_MOVEMENT MovementType, WanderDistance Change the unit movement type (Param1). If the movement type is Random Movement (1), the WanderDistance (Param2) must be provided. - +49 ACTION_T_FOLLOW_TARGET Distance, Angle, Target Add the unit follow movement type on target. * = Use -1 where the param is expected to do nothing. Random constant is generated for each event, so if you have a random yell and a random sound, they will be linked up with each other (ie. param2 with param2). @@ -916,6 +916,12 @@ Parameter 1: StandState - Stand state id to be used by the creature as defined i Parameter 1: MovementType - Movement type id to be used by the creature. Can be 0 = Idle, 1 = Random, 2 = Waypoint. Parameter 2: WanderDistance - Wander distance to be used in case the movement type is 1 (Random). +------------------------------ +49 = ACTION_T_FOLLOW_TARGET: +------------------------------ +Parameter 1: Distance - The distance at which the creature will follow on target. +Parameter 2: Angle - The angle at which the creature will follow target. +Parameter 3: Target - Preferably ACTION_INVOKER and EVENT_SENDER, but can use any other except TARGET_SELF. ========================================= Target Types ========================================= diff --git a/doc/script_commands.txt b/doc/script_commands.txt index b006040941..c4676d6b9b 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -319,3 +319,7 @@ Where "A -> B" means that the command is executed from A with B as target. * datalong = mailTemplateId * datalong2: AlternativeSenderEntry. Use as sender-Entry of the sent mail * dataint1: Delay (>= 0) in Seconds + +39 SCRIPT_COMMAND_FOLLOW Move Follow resultingSource = Creature, resultingTarget = Unit + * datalong = distance + * datalong2 = angle diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index a95c14cac1..c63904111d 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1019,6 +1019,24 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } break; } + case ACTION_T_FOLLOW_TARGET: + m_followDistance = (float)action.follow_movement.distance; + m_followAngle = action.follow_movement.angle.angle; + Unit* target = GetTargetByType(action.follow_movement, pActionInvoker, pAIEventSender, reportTargetError); + if (!target) + { + if (reportTargetError) + sLog.outErrorEventAI("NULL target for ACTION_T_FOLLOW_TARGET creature entry %u follow target %u", m_creature->GetEntry(), action.follow_movement); + return; + } + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + { + // Drop current movement gen + m_creature->GetMotionMaster()->Clear; + m_creature->GetMotionMaster()->MoveFollow(target, m_followDistance, m_followAngle); + } + } + break; } } diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 7623622cb6..5345ac9532 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -120,6 +120,7 @@ enum EventAI_ActionType ACTION_T_SET_THROW_MASK = 46, // EventTypeMask, unused, unused ACTION_T_SET_STAND_STATE = 47, // StandState, unused, unused ACTION_T_CHANGE_MOVEMENT = 48, // MovementType, WanderDistance, unused + ACTION_T_FOLLOW_TARGET = 49, // Distance, Angle, Target. ACTION_T_END, }; @@ -414,6 +415,13 @@ struct CreatureEventAI_Action uint32 wanderDistance; uint32 unused1; } changeMovement; + // ACTION_T_FOLLOW_TARGET = 49 + struct + { + uint32 distance; + uint32 angle; + uint32 target; + } follow_movement; // RAW struct { diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index 90a1662fa5..048098fdcc 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -881,7 +881,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() continue; } break; - + case ACTION_T_FOLLOW_TARGET: + if (action.follow_movement == TARGET_T_SELF) + { + sLog.outErrorEventAI("Event %u Action %u uses invalid target_type %u.", i, j + 1, action.follow_movement.follow); + continue; + } default: sLog.outErrorEventAI("Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j + 1, temp.action[j].type); break; diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index 622516d5fa..c82e4d411d 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -738,6 +738,8 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename) sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command); continue; } + case SCRIPT_COMMAND_FOLLOW: // 39 + break; } if (scripts.second.find(tmp.id) == scripts.second.end()) @@ -1962,6 +1964,15 @@ bool ScriptAction::HandleScriptStep() default: sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command); break; + case SCRIPT_COMMAND_FOLLOW: // 39 + { + if (LogIfNotCreature(pSource)) + return false; + if (LogIfNotUnit(pTarget)) + return false; + ((Creature*)pSource)->GetMotionMaster()->MoveFollow(pTarget, distance, angle); + break; + } } return false; diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 9b5069ca2e..c45a4d18c7 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -117,6 +117,9 @@ enum ScriptCommand // resSource, resTar // datalong: Send mailTemplateId from resSource (if provided) to player resTarget // datalong2: AlternativeSenderEntry. Use as sender-Entry // dataint1: Delay (>= 0) in Seconds + SCRIPT_COMMAND_FOLLOW = 39, // resSource Creature, resTarget Creature/Player. Move Follow towards Target. + // datalong = distance + // datalong2 = angle }; #define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK, SCRIPT_COMMAND_EMOTE, SCRIPT_COMMAND_CAST_SPELL, SCRIPT_COMMAND_TERMINATE_SCRIPT @@ -363,6 +366,12 @@ struct ScriptInfo uint32 mailTemplateId; // datalong uint32 altSender; // datalong2; } sendMail; + + struct // SCRIPT_COMMAND_FOLLOW (39) + { + uint32 Distance; //datalong + uint32 Angle; //datalong2; + } moveFollow; struct {