diff --git a/doc/script_commands.txt b/doc/script_commands.txt index a5a854cd5..c2cf9cf4b 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -220,6 +220,8 @@ Where "A -> B" means that the command is executed from A with B as target. 20 SCRIPT_COMMAND_MOVEMENT resultingSource = Creature * datalong = MovementType (0:idle, 1:random or 2:waypoint) + * datalong2 = wanderDistance (for random movement) + * data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL: RandomMovement around current position 21 SCRIPT_COMMAND_SET_ACTIVEOBJECT resultingSource = Creature * datalong=bool 0=off, 1=on diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index 183bac227..f28b88de6 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -222,7 +222,7 @@ void MotionMaster::MoveIdle() push(&si_idleMovement); } -void MotionMaster::MoveRandom() +void MotionMaster::MoveRandomAroundPoint(float x, float y, float z, float radius, float verticalZ) { if (m_owner->GetTypeId() == TYPEID_PLAYER) { @@ -231,9 +231,9 @@ void MotionMaster::MoveRandom() else { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s move random.", m_owner->GetGuidStr().c_str()); - Mutate(new RandomMovementGenerator(*m_owner)); - } -} + Mutate(new RandomMovementGenerator(x, y, z, radius, verticalZ)); + } + } void MotionMaster::MoveTargetedHome() { diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h index f238f28f3..e06f0059e 100644 --- a/src/game/MotionMaster.h +++ b/src/game/MotionMaster.h @@ -96,7 +96,7 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack } void MoveIdle(); - void MoveRandom(); + void MoveRandomAroundPoint(float x, float y, float z, float radius, float verticalZ = 0.0f); void MoveTargetedHome(); void MoveFollow(Unit* target, float dist, float angle); void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f); diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 40684d1b1..9c8a28253 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -25,17 +25,28 @@ #include "movement/MoveSpline.h" template<> -void RandomMovementGenerator::_setRandomLocation(Creature &creature) +RandomMovementGenerator::RandomMovementGenerator(const Creature & creature) { float respX, respY, respZ, respO, wander_distance; creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance); + i_nextMoveTime = ShortTimeTracker(0); + i_x = respX; + i_y = respY; + i_z = respZ; + i_radius = wander_distance; + // TODO - add support for flying mobs using some distance + i_verticalZ = 0.0f; +} +template<> +void RandomMovementGenerator::_setRandomLocation(Creature &creature) +{ const float angle = rand_norm_f() * (M_PI_F*2.0f); - const float range = rand_norm_f() * wander_distance; + const float range = rand_norm_f() * i_radius; - float destX = respX + range * cos(angle); - float destY = respY + range * sin(angle); - float destZ = creature.GetPositionZ(); + float destX = i_x + range * cos(angle); + float destY = i_y + range * sin(angle); + float destZ = i_z + frand(-1,1) * i_verticalZ; creature.UpdateAllowedPositionZ(destX, destY, destZ); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); @@ -99,16 +110,3 @@ bool RandomMovementGenerator::Update(Creature &creature, const uint32 } return true; } - -template<> -bool RandomMovementGenerator::GetResetPosition(Creature& c, float& x, float& y, float& z) -{ - float radius; - c.GetRespawnCoord(x, y, z, NULL, &radius); - - // use current if in range - if (c.IsWithinDist2d(x,y,radius)) - c.GetPosition(x,y,z); - - return true; -} diff --git a/src/game/RandomMovementGenerator.h b/src/game/RandomMovementGenerator.h index ec1ac076d..928b50e0f 100644 --- a/src/game/RandomMovementGenerator.h +++ b/src/game/RandomMovementGenerator.h @@ -26,7 +26,9 @@ class MANGOS_DLL_SPEC RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovementGenerator > { public: - explicit RandomMovementGenerator(const Unit &) : i_nextMoveTime(0) {} + explicit RandomMovementGenerator(const Creature &); + explicit RandomMovementGenerator(float x, float y, float z, float radius, float verticalZ = 0.0f) : + i_nextMoveTime(0), i_x(x), i_y(y), i_z(z), i_radius(radius), i_verticalZ(verticalZ) {} void _setRandomLocation(T &); void Initialize(T &); @@ -35,11 +37,11 @@ class MANGOS_DLL_SPEC RandomMovementGenerator void Reset(T &); bool Update(T &, const uint32 &); MovementGeneratorType GetMovementGeneratorType() const { return RANDOM_MOTION_TYPE; } - - bool GetResetPosition(T&, float& x, float& y, float& z); private: ShortTimeTracker i_nextMoveTime; - uint32 i_nextMove; + float i_x, i_y, i_z; + float i_radius; + float i_verticalZ; }; #endif diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index ba40d341f..fa3e78852 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -1477,7 +1477,15 @@ void ScriptAction::HandleScriptStep() ((Creature*)pSource)->GetMotionMaster()->MoveIdle(); break; case RANDOM_MOTION_TYPE: - ((Creature*)pSource)->GetMotionMaster()->MoveRandom(); + if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) + ((Creature*)pSource)->GetMotionMaster()->MoveRandomAroundPoint(pSource->GetPositionX(), pSource->GetPositionY(), pSource->GetPositionZ(), float(m_script->movement.wanderDistance)); + else + { + float respX, respY, respZ, respO, wander_distance; + ((Creature*)pSource)->GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance); + wander_distance = m_script->movement.wanderDistance ? m_script->movement.wanderDistance : wander_distance; + ((Creature*)pSource)->GetMotionMaster()->MoveRandomAroundPoint(respX, respY, respZ, wander_distance); + } break; case WAYPOINT_MOTION_TYPE: ((Creature*)pSource)->GetMotionMaster()->MoveWaypoint(); diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 53dc05734..f0cb4df96 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -70,7 +70,8 @@ enum ScriptCommand // resSource, resTar SCRIPT_COMMAND_CREATE_ITEM = 17, // source or target must be player, datalong = item entry, datalong2 = amount SCRIPT_COMMAND_DESPAWN_SELF = 18, // resSource = Creature, datalong = despawn delay SCRIPT_COMMAND_PLAY_MOVIE = 19, // target can only be a player, datalog = movie id - SCRIPT_COMMAND_MOVEMENT = 20, // resSource = Creature. datalong = MovementType (0:idle, 1:random or 2:waypoint) + SCRIPT_COMMAND_MOVEMENT = 20, // resSource = Creature. datalong = MovementType (0:idle, 1:random or 2:waypoint), datalong2 = wander-distance + // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL = Random-movement around current position SCRIPT_COMMAND_SET_ACTIVEOBJECT = 21, // resSource = Creature // datalong=bool 0=off, 1=on SCRIPT_COMMAND_SET_FACTION = 22, // resSource = Creature @@ -228,7 +229,7 @@ struct ScriptInfo struct // SCRIPT_COMMAND_MOVEMENT (20) { uint32 movementType; // datalong - uint32 empty; // datalong2 + uint32 wanderDistance; // datalong2 } movement; struct // SCRIPT_COMMAND_SET_ACTIVEOBJECT (21) @@ -346,6 +347,7 @@ struct ScriptInfo case SCRIPT_COMMAND_MOVE_TO: case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: case SCRIPT_COMMAND_CAST_SPELL: + case SCRIPT_COMMAND_MOVEMENT: case SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL: case SCRIPT_COMMAND_MOUNT_TO_ENTRY_OR_MODEL: return true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9080b8020..818be4811 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12029" + #define REVISION_NR "12030" #endif // __REVISION_NR_H__