aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorccrs <ccrs@users.noreply.github.com>2017-04-09 14:13:29 +0200
committerfunjoker <funjoker109@gmail.com>2020-04-27 12:25:52 +0200
commit84df2c57a385df4503fc1f8ff5dfdf445ea2e31f (patch)
tree9184d1703865b5fde64cbdbe3f185a67dda2bc9f
parentc31f875cc8e7870659a1c9bd565d37b334e5dba8 (diff)
Core/Movement: FormationMovementGenerator
Use own movement generator for creatures following on a formation. First step of implementation, huge room for improvement. Closes #19422 (cherry picked from commit 46221b6dc1272989e0de85a4563fc49dba8e7851)
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp11
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h3
-rw-r--r--src/server/game/Movement/MotionMaster.cpp10
-rw-r--r--src/server/game/Movement/MotionMaster.h3
-rw-r--r--src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp130
-rw-r--r--src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h49
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp4
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp15
9 files changed, 210 insertions, 17 deletions
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 1643a712f8e..07547ae9139 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -224,13 +224,15 @@ void CreatureGroup::FormationReset(bool dismiss)
m_Formed = !dismiss;
}
-void CreatureGroup::LeaderMoveTo(float x, float y, float z)
+void CreatureGroup::LeaderMoveTo(Position destination, uint32 id /*= 0*/, uint32 moveType /*= 0*/, bool orientation /*= false*/)
{
//! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
//! If the leader's path is known, member's path can be plotted as well using formation offsets.
if (!m_leader)
return;
+ float x = destination.GetPositionX(), y = destination.GetPositionY(), z = destination.GetPositionZ();
+
float pathangle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -256,12 +258,9 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
if (!member->IsFlying())
member->UpdateGroundPositionZ(dx, dy, dz);
- if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
- member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
- else
- member->SetWalk(false);
+ Position point(dx, dy, dz, destination.GetOrientation());
- member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
+ member->GetMotionMaster()->MoveFormation(id, point, moveType, !member->IsWithinDist(m_leader, dist + MAX_DESYNC), orientation);
member->SetHomePosition(dx, dy, dz, pathangle);
}
}
diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h
index 38e86ea4c12..85eb7454432 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.h
+++ b/src/server/game/Entities/Creature/CreatureGroups.h
@@ -19,6 +19,7 @@
#define _FORMATIONS_H
#include "Define.h"
+#include "Position.h"
#include "ObjectGuid.h"
#include <unordered_map>
#include <map>
@@ -87,7 +88,7 @@ class TC_GAME_API CreatureGroup
void RemoveMember(Creature* member);
void FormationReset(bool dismiss);
- void LeaderMoveTo(float x, float y, float z);
+ void LeaderMoveTo(Position destination, uint32 id = 0, uint32 moveType = 0, bool orientation = false);
void MemberAttackStart(Creature* member, Unit* target);
};
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index b124edb22d1..3b446733bbb 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -30,6 +30,7 @@
#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
#include "SplineChainMovementGenerator.h"
+#include "FormationMovementGenerator.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
#include "PathGenerator.h"
@@ -711,6 +712,15 @@ void MotionMaster::MoveRotate(uint32 time, RotateDirection direction)
Mutate(new RotateMovementGenerator(time, direction), MOTION_SLOT_ACTIVE);
}
+void MotionMaster::MoveFormation(uint32 id, Position destination, uint32 moveType, bool forceRun /*= false*/, bool forceOrientation /*= false*/)
+{
+ if (_owner->GetTypeId() == TYPEID_UNIT)
+ {
+ TC_LOG_DEBUG("misc", "MotionMaster::MoveFormation: Creature (Entry: %u %s) targeted point (Id: %u X: %f Y: %f Z: %f).", _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), id, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
+ Mutate(new FormationMovementGenerator(id, destination, moveType, forceRun, forceOrientation), MOTION_SLOT_ACTIVE);
+ }
+}
+
/******************** Private methods ********************/
void MotionMaster::pop()
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 8a3f8e5d0b2..7cb72c353f7 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -66,6 +66,7 @@ enum MovementGeneratorType : uint8
ROTATE_MOTION_TYPE = 15,
EFFECT_MOTION_TYPE = 16,
SPLINE_CHAIN_MOTION_TYPE = 17, // SplineChainMovementGenerator.h
+ FORMATION_MOTION_TYPE = 18, // FormationMovementGenerator.h
MAX_MOTION_TYPE // limit
};
@@ -176,6 +177,8 @@ class TC_GAME_API MotionMaster
void MovePath(uint32 path_id, bool repeatable);
void MoveRotate(uint32 time, RotateDirection direction);
+ void MoveFormation(uint32 id, Position destination, uint32 moveType, bool forceRun = false, bool forceOrientation = false);
+
private:
typedef std::vector<MovementGenerator*> MovementList;
diff --git a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp
new file mode 100644
index 00000000000..a1382ec673e
--- /dev/null
+++ b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Creature.h"
+#include "CreatureAI.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "FormationMovementGenerator.h"
+
+void FormationMovementGenerator::DoInitialize(Creature* owner)
+{
+ owner->AddUnitState(UNIT_STATE_ROAMING);
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
+ {
+ _interrupt = true;
+ owner->StopMoving();
+ return;
+ }
+
+ owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
+
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
+ if (_orientation)
+ init.SetFacing(_destination.GetOrientation());
+
+ switch (_moveType)
+ {
+ case 2: // WAYPOINT_MOVE_TYPE_LAND
+ init.SetAnimation(Movement::ToGround);
+ break;
+ case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF
+ init.SetAnimation(Movement::ToFly);
+ break;
+ case 1: // WAYPOINT_MOVE_TYPE_RUN
+ init.SetWalk(false);
+ break;
+ case 0: // WAYPOINT_MOVE_TYPE_WALK
+ init.SetWalk(true);
+ break;
+ }
+
+ if (_run)
+ init.SetWalk(false);
+
+ init.Launch();
+}
+
+bool FormationMovementGenerator::DoUpdate(Creature* owner, uint32 /*diff*/)
+{
+ if (!owner)
+ return false;
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
+ {
+ _interrupt = true;
+ owner->StopMoving();
+ return true;
+ }
+
+ if ((_interrupt && owner->movespline->Finalized()) || (_recalculateSpeed && !owner->movespline->Finalized()))
+ {
+ _recalculateSpeed = false;
+ _interrupt = false;
+
+ owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
+
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
+ if (_orientation)
+ init.SetFacing(_destination.GetOrientation());
+
+ switch (_moveType)
+ {
+ case 2: // WAYPOINT_MOVE_TYPE_LAND
+ init.SetAnimation(Movement::ToGround);
+ break;
+ case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF
+ init.SetAnimation(Movement::ToFly);
+ break;
+ case 1: // WAYPOINT_MOVE_TYPE_RUN
+ init.SetWalk(false);
+ break;
+ case 0: // WAYPOINT_MOVE_TYPE_WALK
+ init.SetWalk(true);
+ break;
+ }
+
+ if (_run)
+ init.SetWalk(false);
+ init.Launch();
+ }
+
+ return !owner->movespline->Finalized();
+}
+
+void FormationMovementGenerator::DoFinalize(Creature* owner)
+{
+ owner->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
+
+ if (owner->movespline->Finalized())
+ MovementInform(owner);
+}
+
+void FormationMovementGenerator::DoReset(Creature* owner)
+{
+ owner->StopMoving();
+ DoInitialize(owner);
+}
+
+void FormationMovementGenerator::MovementInform(Creature* owner)
+{
+ if (owner->AI())
+ owner->AI()->MovementInform(FORMATION_MOTION_TYPE, _movementId);
+}
diff --git a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h
new file mode 100644
index 00000000000..27ab7d50da5
--- /dev/null
+++ b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_FORMATIONMOVEMENTGENERATOR_H
+#define TRINITY_FORMATIONMOVEMENTGENERATOR_H
+
+#include "MovementGenerator.h"
+
+class FormationMovementGenerator : public MovementGeneratorMedium< Creature, FormationMovementGenerator >
+{
+ public:
+ explicit FormationMovementGenerator(uint32 id, Position destination, uint32 moveType, bool run, bool orientation) : _movementId(id), _destination(destination), _moveType(moveType), _run(run), _orientation(orientation), _recalculateSpeed(false), _interrupt(false) { }
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return FORMATION_MOTION_TYPE; }
+
+ void DoInitialize(Creature*);
+ void DoFinalize(Creature*);
+ void DoReset(Creature*);
+ bool DoUpdate(Creature*, uint32);
+
+ void UnitSpeedChanged() override { _recalculateSpeed = true; }
+
+ private:
+ void MovementInform(Creature*);
+
+ uint32 _movementId;
+ Position _destination;
+ uint32 _moveType;
+ bool _run;
+ bool _orientation;
+ bool _recalculateSpeed;
+ bool _interrupt;
+};
+
+#endif // TRINITY_FORMATIONMOVEMENTGENERATOR_H
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index 9c2567ad6a3..ff3a2699128 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -60,7 +60,7 @@ void PointMovementGenerator<T>::DoInitialize(T* owner)
// Call for creature group update
if (Creature* creature = owner->ToCreature())
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
+ creature->GetFormation()->LeaderMoveTo(_destination, _movementId);
}
template<class T>
@@ -95,7 +95,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/)
// Call for creature group update
if (Creature* creature = owner->ToCreature())
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
+ creature->GetFormation()->LeaderMoveTo(_destination, _movementId);
}
return !owner->movespline->Finalized();
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 4c4f8945bfd..7b0025d644f 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -116,7 +116,7 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
// Call for creature group update
if (owner->GetFormation() && owner->GetFormation()->getLeader() == owner)
- owner->GetFormation()->LeaderMoveTo(position.m_positionX, position.m_positionY, position.m_positionZ);
+ owner->GetFormation()->LeaderMoveTo(position);
}
template<class T>
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index 9f07641d74d..0a01d7f3a96 100644
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -139,7 +139,7 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- Movement::Location formationDest(node->x, node->y, node->z, 0.0f);
+ Position formationDest(node->x, node->y, node->z, (node->orientation && node->delay) ? node->orientation : 0.0f);
Movement::MoveSplineInit init(creature);
//! If creature is on transport, we assume waypoints set in DB are already transport offsets
@@ -147,7 +147,11 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
{
init.DisableTransportPathTransformations();
if (TransportBase* trans = creature->GetDirectTransport())
- trans->CalculatePassengerPosition(formationDest.x, formationDest.y, formationDest.z, &formationDest.orientation);
+ {
+ float orientation = formationDest.GetOrientation();
+ trans->CalculatePassengerPosition(formationDest.m_positionX, formationDest.m_positionY, formationDest.m_positionZ, &orientation);
+ formationDest.SetOrientation(orientation);
+ }
}
//! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
@@ -176,12 +180,9 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
init.Launch();
- //Call for creature group update
+ // Call for creature group update
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- {
- creature->SetWalk(node->move_type != WAYPOINT_MOVE_TYPE_RUN);
- creature->GetFormation()->LeaderMoveTo(formationDest.x, formationDest.y, formationDest.z);
- }
+ creature->GetFormation()->LeaderMoveTo(formationDest, node->id, node->move_type, (node->orientation && node->delay) ? true : false);
return true;
}