Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
Core/Movement: merged FormationMovementGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
Ovahlord committed Aug 2, 2018
1 parent 62efe28 commit 14cdb1a
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 18 deletions.
11 changes: 5 additions & 6 deletions src/server/game/Entities/Creature/CreatureGroups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,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)
Expand All @@ -257,12 +259,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);
}
}
2 changes: 1 addition & 1 deletion src/server/game/Entities/Creature/CreatureGroups.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,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);
};

Expand Down
10 changes: 10 additions & 0 deletions src/server/game/Movement/MotionMaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
#include "SplineChainMovementGenerator.h"
#include "FormationMovementGenerator.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"

Expand Down Expand Up @@ -692,6 +693,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 (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), id, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
Mutate(new FormationMovementGenerator(id, destination, moveType, forceRun, forceOrientation), MOTION_SLOT_ACTIVE);
}
}

/******************** Private methods ********************/

void MotionMaster::pop()
Expand Down
2 changes: 2 additions & 0 deletions src/server/game/Movement/MotionMaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,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
};

Expand Down Expand Up @@ -163,6 +164,7 @@ 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;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright (C) 2008-2018 TrinityCore <http://www.trinitycore.org/>
*
* 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);
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);
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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2008-2018 TrinityCore <http://www.trinitycore.org/>
*
* 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
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,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(_x, _y, _z);
creature->GetFormation()->LeaderMoveTo(Position(_destination), _movementId);
}

template<class T>
Expand Down Expand Up @@ -90,7 +90,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(_x, _y, _z);
creature->GetFormation()->LeaderMoveTo(Position(_destination), _movementId);
}

return !owner->movespline->Finalized();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,19 @@ 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
if (transportPath)
{
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
Expand Down Expand Up @@ -180,12 +183,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;
}
Expand Down

0 comments on commit 14cdb1a

Please sign in to comment.