Core/Movement: implement cyclic spline database support
This commit is contained in:
1 parent
a7cd689bb8
commit
27c1fd6aee
13 files changed
+288
-37
No files matched your search
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE `creature_addon`
|
||||
CHANGE `path_id` `waypointPathId` INT(10) UNSIGNED DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN `cyclicSplinePathId` INT(10) UNSIGNED DEFAULT 0 NOT NULL AFTER `waypointPathId`;
|
||||
|
||||
ALTER TABLE `creature_template_addon`
|
||||
CHANGE `path_id` `waypointPathId` INT(10) UNSIGNED DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN `cyclicSplinePathId` INT(10) UNSIGNED DEFAULT 0 NOT NULL AFTER `waypointPathId`;
|
||||
@@ -62,8 +62,8 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, "SELECT wpguid FROM waypoint_data WHERE id = ? and wpguid <> 0", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_DATA_ACTION, "SELECT DISTINCT action FROM waypoint_data", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, "SELECT MAX(guid) FROM waypoint_scripts", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_INS_CREATURE_ADDON, "INSERT INTO creature_addon(guid, path_id) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_UPD_CREATURE_ADDON_PATH, "UPDATE creature_addon SET path_id = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_INS_CREATURE_ADDON, "INSERT INTO creature_addon(guid, waypointPathId) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_UPD_CREATURE_ADDON_PATH, "UPDATE creature_addon SET waypointPathId = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_DEL_CREATURE_ADDON, "DELETE FROM creature_addon WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_INS_WAYPOINT_SCRIPT, "INSERT INTO waypoint_scripts (guid) VALUES (?)", CONNECTION_ASYNC);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "SmartAI.h"
|
||||
#include "TotemAI.h"
|
||||
|
||||
#include "CyclicMovementGenerator.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
@@ -56,5 +57,6 @@ namespace AIRegistry
|
||||
(new IdleMovementFactory())->RegisterSelf();
|
||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature>>(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature>>(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||
(new MovementGeneratorFactory<CyclicMovementGenerator<Creature>>(CYCLIC_SPLINE_MOTION_TYPE))->RegisterSelf();
|
||||
}
|
||||
}
|
||||
@@ -603,6 +603,8 @@ void SmartAI::JustReachedHome()
|
||||
{
|
||||
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != WAYPOINT_MOTION_TYPE && me->GetWaypointPath())
|
||||
me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true);
|
||||
else if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != CYCLIC_SPLINE_MOTION_TYPE && me->GetCyclicSplinePathId())
|
||||
me->GetMotionMaster()->MoveCyclicPath(me->GetCyclicSplinePathId());
|
||||
else
|
||||
me->ResumeMovement();
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ m_lootRecipient(), m_lootRecipientGroup(0), _skinner(), _pickpocketLootRestore(0
|
||||
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
|
||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0),
|
||||
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0), _cyclicSplinePathId(0),
|
||||
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false)
|
||||
{
|
||||
m_valuesCount = UNIT_END;
|
||||
@@ -2595,9 +2595,12 @@ bool Creature::LoadCreaturesAddon()
|
||||
if (cainfo->visibilityDistanceType != VisibilityDistanceType::Normal)
|
||||
SetVisibilityDistanceOverride(cainfo->visibilityDistanceType);
|
||||
|
||||
// Load Path
|
||||
if (cainfo->path_id != 0)
|
||||
_waypointPathId = cainfo->path_id;
|
||||
// Load pathing data
|
||||
if (cainfo->waypointPathId)
|
||||
_waypointPathId = cainfo->waypointPathId;
|
||||
|
||||
if (cainfo->cyclicSplinePathId)
|
||||
_cyclicSplinePathId = cainfo->cyclicSplinePathId;
|
||||
|
||||
if (!cainfo->auras.empty())
|
||||
{
|
||||
|
||||
@@ -306,6 +306,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
uint32 GetWaypointPath() const { return _waypointPathId; }
|
||||
void LoadPath(uint32 pathid) { _waypointPathId = pathid; }
|
||||
|
||||
uint32 GetCyclicSplinePathId() const { return _cyclicSplinePathId; }
|
||||
|
||||
// nodeId, pathId
|
||||
std::pair<uint32, uint32> GetCurrentWaypointInfo() const { return _currentWaypointNodeInfo; }
|
||||
void UpdateCurrentWaypointInfo(uint32 nodeId, uint32 pathId) { _currentWaypointNodeInfo = { nodeId, pathId }; }
|
||||
@@ -426,6 +428,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
uint32 _waypointPathId;
|
||||
std::pair<uint32/*nodeId*/, uint32/*pathId*/> _currentWaypointNodeInfo;
|
||||
|
||||
// Cyclic spline path
|
||||
uint32 _cyclicSplinePathId;
|
||||
|
||||
//Formation var
|
||||
CreatureGroup* m_formation;
|
||||
|
||||
@@ -327,7 +327,8 @@ enum InhabitTypeValues
|
||||
// `creature_addon` table
|
||||
struct CreatureAddon
|
||||
{
|
||||
uint32 path_id;
|
||||
uint32 waypointPathId;
|
||||
uint32 cyclicSplinePathId;
|
||||
uint32 mount;
|
||||
uint32 bytes1;
|
||||
uint32 bytes2;
|
||||
|
||||
@@ -563,8 +563,8 @@ void ObjectMgr::LoadCreatureTemplateAddons()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
QueryResult result = WorldDatabase.Query("SELECT entry, waypointPathId, cyclicSplinePathId, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -587,17 +587,18 @@ void ObjectMgr::LoadCreatureTemplateAddons()
|
||||
|
||||
CreatureAddon& creatureAddon = _creatureTemplateAddonStore[entry];
|
||||
|
||||
creatureAddon.path_id = fields[1].GetUInt32();
|
||||
creatureAddon.mount = fields[2].GetUInt32();
|
||||
creatureAddon.bytes1 = fields[3].GetUInt32();
|
||||
creatureAddon.bytes2 = fields[4].GetUInt32();
|
||||
creatureAddon.emote = fields[5].GetUInt32();
|
||||
creatureAddon.aiAnimKit = fields[6].GetUInt16();
|
||||
creatureAddon.movementAnimKit = fields[7].GetUInt16();
|
||||
creatureAddon.meleeAnimKit = fields[8].GetUInt16();
|
||||
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
|
||||
creatureAddon.waypointPathId = fields[1].GetUInt32();
|
||||
creatureAddon.cyclicSplinePathId = fields[2].GetUInt32();
|
||||
creatureAddon.mount = fields[3].GetUInt32();
|
||||
creatureAddon.bytes1 = fields[4].GetUInt32();
|
||||
creatureAddon.bytes2 = fields[5].GetUInt32();
|
||||
creatureAddon.emote = fields[6].GetUInt32();
|
||||
creatureAddon.aiAnimKit = fields[7].GetUInt16();
|
||||
creatureAddon.movementAnimKit = fields[8].GetUInt16();
|
||||
creatureAddon.meleeAnimKit = fields[9].GetUInt16();
|
||||
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[10].GetUInt8());
|
||||
|
||||
Tokenizer tokens(fields[10].GetString(), ' ');
|
||||
Tokenizer tokens(fields[11].GetString(), ' ');
|
||||
uint8 i = 0;
|
||||
creatureAddon.auras.resize(tokens.size());
|
||||
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||
@@ -1146,8 +1147,8 @@ void ObjectMgr::LoadCreatureAddons()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, waypointPathId, cyclicSplinePathId, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -1171,23 +1172,45 @@ void ObjectMgr::LoadCreatureAddons()
|
||||
|
||||
CreatureAddon& creatureAddon = _creatureAddonStore[guid];
|
||||
|
||||
creatureAddon.path_id = fields[1].GetUInt32();
|
||||
if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.path_id)
|
||||
creatureAddon.waypointPathId = fields[1].GetUInt32();
|
||||
creatureAddon.cyclicSplinePathId = fields[2].GetUInt32();
|
||||
|
||||
if (creatureAddon.waypointPathId && creatureAddon.cyclicSplinePathId)
|
||||
{
|
||||
if (creData->movementType == WAYPOINT_MOTION_TYPE)
|
||||
{
|
||||
creatureAddon.cyclicSplinePathId = 0;
|
||||
TC_LOG_ERROR("sql.sql", "Creature (GUID %u) has a waypoint and cyclic spline path at the same time but uses WAYPOINT_MOTION_TYPE. Prefered waypoint path", guid);
|
||||
}
|
||||
else if (creData->movementType == CYCLIC_SPLINE_MOTION_TYPE)
|
||||
{
|
||||
creatureAddon.waypointPathId = 0;
|
||||
TC_LOG_ERROR("sql.sql", "Creature (GUID %u) has a waypoint and cyclic spline path at the same time but uses CYCLIC_SPLINE_MOTION_TYPE. Prefered cyclic spline path", guid);
|
||||
}
|
||||
}
|
||||
|
||||
if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.waypointPathId)
|
||||
{
|
||||
const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
|
||||
TC_LOG_ERROR("sql.sql", "Creature (GUID %u) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
|
||||
}
|
||||
|
||||
creatureAddon.mount = fields[2].GetUInt32();
|
||||
creatureAddon.bytes1 = fields[3].GetUInt32();
|
||||
creatureAddon.bytes2 = fields[4].GetUInt32();
|
||||
creatureAddon.emote = fields[5].GetUInt32();
|
||||
creatureAddon.aiAnimKit = fields[6].GetUInt16();
|
||||
creatureAddon.movementAnimKit = fields[7].GetUInt16();
|
||||
creatureAddon.meleeAnimKit = fields[8].GetUInt16();
|
||||
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
|
||||
if (creData->movementType == CYCLIC_SPLINE_MOTION_TYPE && !creatureAddon.cyclicSplinePathId)
|
||||
{
|
||||
const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
|
||||
TC_LOG_ERROR("sql.sql", "Creature (GUID %u) has movement type set to CYCLIC_SPLINE_MOTION_TYPE but no path assigned", guid);
|
||||
}
|
||||
|
||||
Tokenizer tokens(fields[10].GetString(), ' ');
|
||||
creatureAddon.mount = fields[3].GetUInt32();
|
||||
creatureAddon.bytes1 = fields[4].GetUInt32();
|
||||
creatureAddon.bytes2 = fields[5].GetUInt32();
|
||||
creatureAddon.emote = fields[6].GetUInt32();
|
||||
creatureAddon.aiAnimKit = fields[7].GetUInt16();
|
||||
creatureAddon.movementAnimKit = fields[8].GetUInt16();
|
||||
creatureAddon.meleeAnimKit = fields[9].GetUInt16();
|
||||
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[10].GetUInt8());
|
||||
|
||||
Tokenizer tokens(fields[11].GetString(), ' ');
|
||||
uint8 i = 0;
|
||||
creatureAddon.auras.resize(tokens.size());
|
||||
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "CyclicMovementGenerator.h"
|
||||
#include "DBCStores.h"
|
||||
#include "G3DPosition.hpp"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
@@ -42,6 +43,7 @@
|
||||
#include "Unit.h"
|
||||
#include "WaypointDefines.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "WaypointManager.h"
|
||||
|
||||
inline MovementGenerator* GetIdleMovementGenerator()
|
||||
{
|
||||
@@ -498,7 +500,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
|
||||
if (velocity > 0.f)
|
||||
init.SetVelocity(velocity);
|
||||
|
||||
Mutate(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, 0), MOTION_SLOT_ACTIVE);
|
||||
Mutate(new GenericMovementGenerator(std::move(init), CYCLIC_SPLINE_MOTION_TYPE, 0), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCyclicPath(Position const* pathPoints, size_t pathSize, bool walk /*= false*/, bool fly /*= false*/, float velocity /*= 0.0f*/)
|
||||
@@ -524,7 +526,13 @@ void MotionMaster::MoveCyclicPath(Position const* pathPoints, size_t pathSize, b
|
||||
init.SetSmooth();
|
||||
init.SetWalk(walk);
|
||||
init.SetCyclic();
|
||||
Mutate(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, 0), MOTION_SLOT_IDLE);
|
||||
Mutate(new GenericMovementGenerator(std::move(init), CYCLIC_SPLINE_MOTION_TYPE, 0), MOTION_SLOT_IDLE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCyclicPath(uint32 pathId)
|
||||
{
|
||||
if (WaypointPath const* splinePath = sWaypointMgr->GetPath(pathId))
|
||||
Mutate(new CyclicMovementGenerator<Creature>(splinePath), MOTION_SLOT_IDLE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk /*= false*/, bool fly /*= false*/, float velocity /*= 0.0f*/)
|
||||
|
||||
@@ -49,7 +49,8 @@ enum MovementGeneratorType : uint8
|
||||
IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h
|
||||
RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h
|
||||
WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h
|
||||
MAX_DB_MOTION_TYPE = 3, // Below motion types can't be set in DB.
|
||||
CYCLIC_SPLINE_MOTION_TYPE = 3, // CyclicMovementGenerator.h
|
||||
MAX_DB_MOTION_TYPE = 4, // Below motion types can't be set in DB.
|
||||
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
|
||||
CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
|
||||
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
|
||||
@@ -60,7 +61,7 @@ enum MovementGeneratorType : uint8
|
||||
ASSISTANCE_MOTION_TYPE = 11, // PointMovementGenerator.h
|
||||
ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h
|
||||
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h
|
||||
FOLLOW_MOTION_TYPE = 14,
|
||||
FOLLOW_MOTION_TYPE = 14, // FollowMovementGenerator.h
|
||||
ROTATE_MOTION_TYPE = 15,
|
||||
EFFECT_MOTION_TYPE = 16,
|
||||
SPLINE_CHAIN_MOTION_TYPE = 17, // SplineChainMovementGenerator.h
|
||||
@@ -182,6 +183,7 @@ class TC_GAME_API MotionMaster
|
||||
void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false);
|
||||
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, float velocity = 0.f);
|
||||
void MoveCyclicPath(Position const* pathPoints, size_t pathSize, bool walk = false, bool fly = false, float velocity = 0.f);
|
||||
void MoveCyclicPath(uint32 pathId);
|
||||
void MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk = false, bool fly = false, float velocity = 0.f);
|
||||
// Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints)
|
||||
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk);
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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 "CyclicMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "G3DPosition.hpp"
|
||||
#include "Log.h"
|
||||
#include "Map.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Transport.h"
|
||||
#include "WaypointManager.h"
|
||||
|
||||
inline bool CanMove(Creature const* creature)
|
||||
{
|
||||
return (!creature->HasUnitState(UNIT_STATE_NOT_MOVE) && !creature->IsMovementPreventedByCasting());
|
||||
}
|
||||
|
||||
CyclicMovementGenerator<Creature>::CyclicMovementGenerator(WaypointPath const* path, Optional<bool> enforceFlight, Optional<bool> enforceWalk, Optional<float> velocity) : _path(path), _moveTimer(0)
|
||||
{
|
||||
if (enforceFlight.is_initialized())
|
||||
_enforceFlight = *enforceFlight;
|
||||
|
||||
if (enforceWalk.is_initialized())
|
||||
_enforceWalk = *enforceWalk;
|
||||
|
||||
if (velocity.is_initialized())
|
||||
_velocity = *velocity;
|
||||
}
|
||||
|
||||
CyclicMovementGenerator<Creature>::CyclicMovementGenerator() : _path(nullptr), _moveTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CyclicMovementGenerator<Creature>::DoInitialize(Creature* creature)
|
||||
{
|
||||
if (!_path)
|
||||
if (uint32 pathId = creature->GetCyclicSplinePathId())
|
||||
_path = sWaypointMgr->GetPath(pathId);
|
||||
|
||||
if (_path)
|
||||
_moveTimer.Reset(1000);
|
||||
}
|
||||
|
||||
void CyclicMovementGenerator<Creature>::DoFinalize(Creature* creature)
|
||||
{
|
||||
creature->setActive(false);
|
||||
}
|
||||
|
||||
void CyclicMovementGenerator<Creature>::DoReset(Creature* creature)
|
||||
{
|
||||
if (_moveTimer.Passed() && CanMove(creature))
|
||||
StartMovement(creature);
|
||||
}
|
||||
|
||||
bool CyclicMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff)
|
||||
{
|
||||
if (!creature || !creature->IsAlive())
|
||||
return true;
|
||||
|
||||
if (!_path || _path->nodes.empty())
|
||||
return true;
|
||||
|
||||
if (!CanMove(creature))
|
||||
{
|
||||
creature->StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
// dont update wait timer while moving
|
||||
if (creature->movespline->Finalized())
|
||||
{
|
||||
_moveTimer.Update(diff);
|
||||
if (_moveTimer.Passed())
|
||||
{
|
||||
_moveTimer.Reset(0);
|
||||
StartMovement(creature);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CyclicMovementGenerator<Creature>::StartMovement(Creature* creature)
|
||||
{
|
||||
if (!creature || !creature->IsAlive() || !CanMove(creature) || !_path || _path->nodes.empty())
|
||||
return;
|
||||
|
||||
if (!CanMove(creature) || (creature->IsFormationLeader() && !creature->IsFormationLeaderMoveAllowed())) // if cannot move OR cannot move because of formation
|
||||
{
|
||||
_moveTimer.Reset(1000); // delay 1s
|
||||
return;
|
||||
}
|
||||
|
||||
// Cyclic splines get asynchronous if the serverside position is not being tracked constantly.
|
||||
creature->setActive(true);
|
||||
|
||||
bool const flying = creature->IsFlying() || creature->IsInWater(); // Swimming units also use flying and uncompressed splines
|
||||
Movement::MoveSplineInit init(creature);
|
||||
Movement::PointsArray path;
|
||||
|
||||
path.reserve(_path->nodes.size() + 1);
|
||||
path.push_back(PositionToVector3(creature->GetPosition()));
|
||||
std::transform(_path->nodes.begin(), _path->nodes.end(), std::back_inserter(path), [](WaypointNode const& node)
|
||||
{
|
||||
return G3D::Vector3(node.x, node.y, node.z);
|
||||
});
|
||||
|
||||
if (flying || (_enforceFlight.is_initialized() && *_enforceFlight))
|
||||
{
|
||||
init.SetFly();
|
||||
init.SetUncompressed();
|
||||
}
|
||||
|
||||
if (_velocity.is_initialized())
|
||||
init.SetVelocity(*_velocity);
|
||||
|
||||
if (_enforceWalk.is_initialized())
|
||||
init.SetWalk(*_enforceWalk);
|
||||
|
||||
init.MovebyPath(path);
|
||||
init.SetSmooth();
|
||||
init.SetCyclic();
|
||||
init.Launch();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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_CYCLICMOVEMENTGENERATOR_H
|
||||
#define TRINITY_CYCLICMOVEMENTGENERATOR_H
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "Timer.h"
|
||||
#include "OptionalFwd.h"
|
||||
|
||||
enum MovementGeneratorType : uint8;
|
||||
|
||||
class Creature;
|
||||
struct WaypointPath;
|
||||
|
||||
template<class T>
|
||||
class CyclicMovementGenerator;
|
||||
|
||||
template<>
|
||||
class CyclicMovementGenerator<Creature> : public MovementGeneratorMedium<Creature, CyclicMovementGenerator<Creature>>
|
||||
{
|
||||
public:
|
||||
explicit CyclicMovementGenerator(WaypointPath const* path, Optional<bool> enforceFlight = { }, Optional<bool> enforceWalk = { }, Optional<float> velocity = { });
|
||||
explicit CyclicMovementGenerator();
|
||||
|
||||
void DoInitialize(Creature*);
|
||||
void DoFinalize(Creature*);
|
||||
void DoReset(Creature*);
|
||||
bool DoUpdate(Creature*, uint32);
|
||||
|
||||
MovementGeneratorType GetMovementGeneratorType() const override { return CYCLIC_SPLINE_MOTION_TYPE; }
|
||||
|
||||
private:
|
||||
void StartMovement(Creature*);
|
||||
|
||||
WaypointPath const* _path;
|
||||
Optional<bool> _enforceFlight;
|
||||
Optional<bool> _enforceWalk;
|
||||
Optional<float> _velocity;
|
||||
|
||||
TimeTrackerSmall _moveTimer;
|
||||
};
|
||||
|
||||
#endif // TRINITY_CYCLICMOVEMENTGENERATOR_H
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
}
|
||||
|
||||
CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(guidLow);
|
||||
if (!addon || addon->path_id == 0)
|
||||
if (!addon || addon->waypointPathId == 0)
|
||||
{
|
||||
handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target does not have a loaded path.");
|
||||
return true;
|
||||
|
||||
Reference in new issue
Block a user