Core/Movement: Add new SplineChainMovementGenerator that allows accurate replication of sniffed waypoints in static sequences, along with DB facilities that allow loading of waypoints from DB.
This commit is contained in:
1 parent
4869105623
commit
c1cc7e0a36
12 files changed
+394
-21
No files matched your search
@@ -0,0 +1,21 @@
|
||||
-- add tables for spline chain DB storage
|
||||
DROP TABLE IF EXISTS `script_spline_chain_meta`;
|
||||
CREATE TABLE `script_spline_chain_meta` (
|
||||
`entry` INT UNSIGNED NOT NULL,
|
||||
`chainId` TINYINT UNSIGNED NOT NULL,
|
||||
`splineId` TINYINT UNSIGNED NOT NULL,
|
||||
`expectedDuration` INT UNSIGNED NOT NULL,
|
||||
`msUntilNext` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY USING BTREE (`entry`,`chainId`,`splineId`)
|
||||
);
|
||||
DROP TABLE IF EXISTS `script_spline_chain_waypoints`;
|
||||
CREATE TABLE `script_spline_chain_waypoints` (
|
||||
`entry` INT UNSIGNED NOT NULL,
|
||||
`chainId` TINYINT UNSIGNED NOT NULL,
|
||||
`splineId` TINYINT UNSIGNED NOT NULL,
|
||||
`wpId` TINYINT UNSIGNED NOT NULL,
|
||||
`x` FLOAT NOT NULL,
|
||||
`y` FLOAT NOT NULL,
|
||||
`z` FLOAT NOT NULL,
|
||||
PRIMARY KEY USING BTREE (`entry`,`chainId`,`splineId`,`wpId`)
|
||||
);
|
||||
@@ -402,12 +402,11 @@ void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 wait
|
||||
|
||||
void npc_escortAI::FillPointMovementListForCreature()
|
||||
{
|
||||
ScriptPointVector const& movePoints = sScriptSystemMgr->GetPointMoveList(me->GetEntry());
|
||||
if (movePoints.empty())
|
||||
ScriptPointVector const* movePoints = sScriptSystemMgr->GetPointMoveList(me->GetEntry());
|
||||
if (!movePoints)
|
||||
return;
|
||||
|
||||
ScriptPointVector::const_iterator itrEnd = movePoints.end();
|
||||
for (ScriptPointVector::const_iterator itr = movePoints.begin(); itr != itrEnd; ++itr)
|
||||
for (ScriptPointVector::const_iterator itr = movePoints->begin(); itr != movePoints->end(); ++itr)
|
||||
{
|
||||
Escort_Waypoint point(itr->uiPointId, itr->fX, itr->fY, itr->fZ, itr->uiWaitTime);
|
||||
WaypointList.push_back(point);
|
||||
@@ -563,11 +562,11 @@ bool npc_escortAI::SetNextWaypoint(uint32 pointId, bool setPosition, bool resetW
|
||||
|
||||
bool npc_escortAI::GetWaypointPosition(uint32 pointId, float& x, float& y, float& z)
|
||||
{
|
||||
ScriptPointVector const& waypoints = sScriptSystemMgr->GetPointMoveList(me->GetEntry());
|
||||
if (waypoints.empty())
|
||||
ScriptPointVector const* waypoints = sScriptSystemMgr->GetPointMoveList(me->GetEntry());
|
||||
if (!waypoints)
|
||||
return false;
|
||||
|
||||
for (ScriptPointVector::const_iterator itr = waypoints.begin(); itr != waypoints.end(); ++itr)
|
||||
for (ScriptPointVector::const_iterator itr = waypoints->begin(); itr != waypoints->end(); ++itr)
|
||||
{
|
||||
if (itr->uiPointId == pointId)
|
||||
{
|
||||
|
||||
@@ -573,7 +573,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
}
|
||||
case SMART_EVENT_MOVEMENTINFORM:
|
||||
{
|
||||
if (e.event.movementInform.type > NULL_MOTION_TYPE)
|
||||
if (e.event.movementInform.type >= MAX_MOTION_TYPE)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type);
|
||||
return false;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "MotionMaster.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Creature.h"
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "SplineChainMovementGenerator.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
|
||||
@@ -468,6 +470,33 @@ void MotionMaster::MoveSmoothPath(uint32 pointId, Movement::PointsArray const& p
|
||||
//MovePoint(EVENT_CHARGE_PREPATH, pos, false);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint32 dbChainId, bool walk)
|
||||
{
|
||||
Creature* owner = _owner->ToCreature();
|
||||
if (!owner)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "MotionMaster::MoveAlongSplineChain: non-creature %s tried to walk along DB spline chain. Ignoring.", _owner->GetGUID().ToString().c_str());
|
||||
return;
|
||||
}
|
||||
SplineChain const* chain = sScriptSystemMgr->GetSplineChain(owner, dbChainId);
|
||||
if (!chain)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "MotionMaster::MoveAlongSplineChain: creature with entry %u tried to walk along non-existing spline chain with DB id %u.", owner->GetEntry(), dbChainId);
|
||||
return;
|
||||
}
|
||||
MoveAlongSplineChain(pointId, *chain, walk);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveAlongSplineChain(uint32 pointId, SplineChain const& chain, bool walk)
|
||||
{
|
||||
Mutate(new SplineChainMovementGenerator(pointId, chain, walk), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info)
|
||||
{
|
||||
Mutate(new SplineChainMovementGenerator(info), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveFall(uint32 id /*=0*/)
|
||||
{
|
||||
// use larger distance for vmap height search than in most other cases
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "Object.h"
|
||||
#include "MoveSplineInitArgs.h"
|
||||
#include "SplineChain.h"
|
||||
|
||||
class MovementGenerator;
|
||||
class Unit;
|
||||
@@ -53,7 +54,9 @@ enum MovementGeneratorType
|
||||
FOLLOW_MOTION_TYPE = 14,
|
||||
ROTATE_MOTION_TYPE = 15,
|
||||
EFFECT_MOTION_TYPE = 16,
|
||||
NULL_MOTION_TYPE = 17
|
||||
NULL_MOTION_TYPE = 17,
|
||||
SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h
|
||||
MAX_MOTION_TYPE // limit
|
||||
};
|
||||
|
||||
enum MovementSlot
|
||||
@@ -196,6 +199,10 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
|
||||
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount);
|
||||
void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk);
|
||||
void MoveSmoothPath(uint32 pointId, Movement::PointsArray const& points, bool walk);
|
||||
// Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints)
|
||||
void MoveAlongSplineChain(uint32 pointId, uint32 dbChainId, bool walk);
|
||||
void MoveAlongSplineChain(uint32 pointId, SplineChain const& chain, bool walk);
|
||||
void ResumeSplineChain(SplineChainResumeInfo const& info);
|
||||
void MoveFall(uint32 id = 0);
|
||||
|
||||
void MoveSeekAssistance(float x, float y, float z);
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 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 "SplineChainMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "Log.h"
|
||||
|
||||
uint32 SplineChainMovementGenerator::SendPathSpline(Unit* me, Movement::PointsArray const& wp) const
|
||||
{
|
||||
uint32 numWp = wp.size();
|
||||
ASSERT(numWp > 1 && "Every path must have source & destination");
|
||||
Movement::MoveSplineInit init(me);
|
||||
if (numWp > 2)
|
||||
init.MovebyPath(wp);
|
||||
else
|
||||
init.MoveTo(wp[1], false, true);
|
||||
init.SetWalk(_walk);
|
||||
return init.Launch();
|
||||
}
|
||||
|
||||
void SplineChainMovementGenerator::SendSplineFor(Unit* me, uint32 index, uint32& toNext)
|
||||
{
|
||||
ASSERT(index < _chainSize);
|
||||
TC_LOG_DEBUG("movement.splinechain", "%s: Sending spline for %u.", me->GetGUID().ToString().c_str(), index);
|
||||
|
||||
SplineChainLink const& thisLink = _chain[index];
|
||||
uint32 actualDuration = SendPathSpline(me, thisLink.Points);
|
||||
if (actualDuration != thisLink.ExpectedDuration)
|
||||
{
|
||||
TC_LOG_DEBUG("movement.splinechain", "%s: Sent spline for %u, duration is %u ms. Expected was %u ms (delta %d ms). Adjusting.", me->GetGUID().ToString().c_str(), index, actualDuration, thisLink.ExpectedDuration, int32(actualDuration) - int32(thisLink.ExpectedDuration));
|
||||
toNext = uint32(double(actualDuration)/double(thisLink.ExpectedDuration) * toNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("movement.splinechain", "%s: Sent spline for %u, duration is %u ms.", me->GetGUID().ToString().c_str(), index, actualDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void SplineChainMovementGenerator::Initialize(Unit* me)
|
||||
{
|
||||
if (_chainSize)
|
||||
{
|
||||
if (_nextFirstWP) // this is a resumed movegen that has to start with a partial spline
|
||||
{
|
||||
if (finished)
|
||||
return;
|
||||
SplineChainLink const& thisLink = _chain[_nextIndex];
|
||||
if (_nextFirstWP >= thisLink.Points.size())
|
||||
{
|
||||
TC_LOG_ERROR("movement.splinechain", "%s: Attempted to resume spline chain from invalid resume state (%u, %u).", me->GetGUID().ToString().c_str(), _nextIndex, _nextFirstWP);
|
||||
_nextFirstWP = thisLink.Points.size()-1;
|
||||
}
|
||||
Movement::PointsArray partial(thisLink.Points.begin() + (_nextFirstWP-1), thisLink.Points.end());
|
||||
SendPathSpline(me, partial);
|
||||
TC_LOG_DEBUG("movement.splinechain", "%s: Resumed spline chain generator from resume state.", me->GetGUID().ToString().c_str());
|
||||
++_nextIndex;
|
||||
if (!_msToNext)
|
||||
_msToNext = 1;
|
||||
_nextFirstWP = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_msToNext = std::max(_chain[_nextIndex].TimeToNext, 1u);
|
||||
SendSplineFor(me, _nextIndex, _msToNext);
|
||||
++_nextIndex;
|
||||
if (_nextIndex >= _chainSize)
|
||||
_msToNext = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR("movement", "SplineChainMovementGenerator::Initialize - empty spline chain passed for %s.", me->GetGUID().ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SplineChainMovementGenerator::Finalize(Unit* me)
|
||||
{
|
||||
if (!finished)
|
||||
return;
|
||||
Creature* cMe = me->ToCreature();
|
||||
if (cMe && cMe->IsAIEnabled)
|
||||
cMe->AI()->MovementInform(SPLINE_CHAIN_MOTION_TYPE, _id);
|
||||
}
|
||||
|
||||
bool SplineChainMovementGenerator::Update(Unit* me, uint32 diff)
|
||||
{
|
||||
if (finished)
|
||||
return false;
|
||||
|
||||
// _msToNext being zero here means we're on the final spline
|
||||
if (!_msToNext)
|
||||
{
|
||||
finished = me->movespline->Finalized();
|
||||
return !finished;
|
||||
}
|
||||
|
||||
if (_msToNext <= diff)
|
||||
{
|
||||
// Send next spline
|
||||
TC_LOG_DEBUG("movement.splinechain", "%s: Should send spline %u (%u ms late).", me->GetGUID().ToString().c_str(), _nextIndex, diff - _msToNext);
|
||||
_msToNext = std::max(_chain[_nextIndex].TimeToNext, 1u);
|
||||
SendSplineFor(me, _nextIndex, _msToNext);
|
||||
++_nextIndex;
|
||||
if (_nextIndex >= _chainSize)
|
||||
{
|
||||
// We have reached the final spline, once it finalizes we should also finalize the movegen (start checking on next update)
|
||||
_msToNext = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
_msToNext -= diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
SplineChainResumeInfo SplineChainMovementGenerator::GetResumeInfo(Unit const* me) const
|
||||
{
|
||||
if (!_nextIndex)
|
||||
return SplineChainResumeInfo(_id, &_chain, _walk, 0, 0, _msToNext);
|
||||
if (me->movespline->Finalized())
|
||||
return SplineChainResumeInfo(_id, &_chain, _walk, _nextIndex, 0, 1u);
|
||||
return SplineChainResumeInfo(_id, &_chain, _walk, uint8(_nextIndex - 1), uint8(me->movespline->_currentSplineIdx()), _msToNext);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 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_SPLINECHAINMOVEMENTGENERATOR_H
|
||||
#define TRINITY_SPLINECHAINMOVEMENTGENERATOR_H
|
||||
|
||||
#include "SplineChain.h"
|
||||
#include "MovementGenerator.h"
|
||||
|
||||
class TC_GAME_API SplineChainMovementGenerator : public MovementGenerator
|
||||
{
|
||||
public:
|
||||
explicit SplineChainMovementGenerator(uint32 id, SplineChain const& chain, bool walk = false) : _id(id), _chain(chain), _chainSize(chain.size()), _walk(walk), finished(false), _nextIndex(0), _nextFirstWP(0), _msToNext(0) { }
|
||||
explicit SplineChainMovementGenerator(SplineChainResumeInfo const& info) : _id(info.PointID), _chain(*info.Chain), _chainSize(info.Chain->size()), _walk(info.IsWalkMode), finished(info.SplineIndex >= info.Chain->size()), _nextIndex(info.SplineIndex), _nextFirstWP(info.PointIndex), _msToNext(info.TimeToNext) { }
|
||||
void Initialize(Unit* me) override;
|
||||
void Finalize(Unit* me) override;
|
||||
void Reset(Unit* /*me*/) override { };
|
||||
bool Update(Unit* me, uint32 diff) override;
|
||||
MovementGeneratorType GetMovementGeneratorType() const override { return SPLINE_CHAIN_MOTION_TYPE; }
|
||||
// Builds info that can later be used to resume this spline chain movement at the current position
|
||||
SplineChainResumeInfo GetResumeInfo(Unit const* me) const;
|
||||
|
||||
private:
|
||||
void SendSplineFor(Unit* me, uint32 index, uint32& toNext);
|
||||
uint32 SendPathSpline(Unit* me, Movement::PointsArray const& wp) const;
|
||||
uint32 const _id;
|
||||
SplineChain const& _chain;
|
||||
uint8 const _chainSize;
|
||||
bool const _walk;
|
||||
bool finished;
|
||||
uint8 _nextIndex;
|
||||
uint8 _nextFirstWP; // only used for resuming
|
||||
uint32 _msToNext;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 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_SPLINECHAIN_H
|
||||
#define TRINITY_SPLINECHAIN_H
|
||||
|
||||
#include "MoveSplineInitArgs.h"
|
||||
|
||||
struct TC_GAME_API SplineChainLink
|
||||
{
|
||||
SplineChainLink(Movement::PointsArray const& points, uint32 expectedDuration, uint32 msToNext) : Points(points), ExpectedDuration(expectedDuration), TimeToNext(msToNext) { }
|
||||
template <typename iteratorType> SplineChainLink(iteratorType begin, iteratorType end, uint32 expectedDuration, uint32 msToNext) : Points(begin, end), ExpectedDuration(expectedDuration), TimeToNext(msToNext) { }
|
||||
SplineChainLink(uint32 expectedDuration, uint32 msToNext) : Points(), ExpectedDuration(expectedDuration), TimeToNext(msToNext) { }
|
||||
Movement::PointsArray Points;
|
||||
uint32 ExpectedDuration;
|
||||
uint32 TimeToNext;
|
||||
};
|
||||
typedef std::vector<SplineChainLink> SplineChain;
|
||||
|
||||
struct TC_GAME_API SplineChainResumeInfo
|
||||
{
|
||||
SplineChainResumeInfo(uint32 id, SplineChain const* chain, bool walk, uint8 splineIndex, uint8 wpIndex, uint32 msToNext) :
|
||||
PointID(id), Chain(chain), IsWalkMode(walk), SplineIndex(splineIndex), PointIndex(wpIndex), TimeToNext(msToNext) { }
|
||||
uint32 PointID;
|
||||
SplineChain const* Chain;
|
||||
bool IsWalkMode;
|
||||
uint8 SplineIndex;
|
||||
uint8 PointIndex;
|
||||
uint32 TimeToNext;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1113,6 +1113,7 @@ void ScriptMgr::Unload()
|
||||
void ScriptMgr::LoadDatabase()
|
||||
{
|
||||
sScriptSystemMgr->LoadScriptWaypoints();
|
||||
sScriptSystemMgr->LoadScriptSplineChains();
|
||||
}
|
||||
|
||||
void ScriptMgr::FillSpellSummary()
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
TC_GAME_API ScriptPointVector const SystemMgr::_empty;
|
||||
|
||||
SystemMgr* SystemMgr::instance()
|
||||
{
|
||||
static SystemMgr instance;
|
||||
@@ -53,7 +51,6 @@ void SystemMgr::LoadScriptWaypoints()
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 Script Waypoints. DB table `script_waypoint` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
@@ -62,7 +59,7 @@ void SystemMgr::LoadScriptWaypoints()
|
||||
ScriptPointMove temp;
|
||||
|
||||
temp.uiCreatureEntry = pFields[0].GetUInt32();
|
||||
uint32 uiEntry = temp.uiCreatureEntry;
|
||||
uint32 uiEntry = temp.uiCreatureEntry;
|
||||
temp.uiPointId = pFields[1].GetUInt32();
|
||||
temp.fX = pFields[2].GetFloat();
|
||||
temp.fY = pFields[3].GetFloat();
|
||||
@@ -82,8 +79,77 @@ void SystemMgr::LoadScriptWaypoints()
|
||||
|
||||
m_mPointMoveMap[uiEntry].push_back(temp);
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u Script Waypoint nodes in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void SystemMgr::LoadScriptSplineChains()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
m_mSplineChainsMap.clear();
|
||||
|
||||
// 0 1 2 3 4
|
||||
QueryResult resultMeta = WorldDatabase.Query("SELECT entry, chainId, splineId, expectedDuration, msUntilNext FROM script_spline_chain_meta ORDER BY entry asc, chainId asc, splineId asc");
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult resultWP = WorldDatabase.Query("SELECT entry, chainId, splineId, wpId, x, y, z FROM script_spline_chain_waypoints ORDER BY entry asc, chainId asc, splineId asc, wpId asc");
|
||||
if (!resultMeta || !resultWP)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded spline chain data for 0 chains, consisting of 0 splines with 0 waypoints. DB tables `script_spline_chain_meta` and `script_spline_chain_waypoints` are empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 chainCount = 0, splineCount = 0, wpCount = 0;
|
||||
do
|
||||
{
|
||||
Field* fieldsMeta = resultMeta->Fetch();
|
||||
uint32 entry = fieldsMeta[0].GetUInt32();
|
||||
uint8 chainId = fieldsMeta[1].GetUInt8(), splineId = fieldsMeta[2].GetUInt8();
|
||||
SplineChain& chain = m_mSplineChainsMap[{entry,chainId}];
|
||||
|
||||
if (splineId != chain.size())
|
||||
{
|
||||
TC_LOG_WARN("server.loading", "Creature #%u: Chain %u has orphaned spline %u, skipped.", entry, chainId, splineId);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 expectedDuration = fieldsMeta[3].GetUInt32(), msUntilNext = fieldsMeta[4].GetUInt32();
|
||||
chain.push_back(SplineChainLink(expectedDuration, msUntilNext));
|
||||
|
||||
if (splineId == 0)
|
||||
++chainCount;
|
||||
++splineCount;
|
||||
} while (resultMeta->NextRow());
|
||||
|
||||
do
|
||||
{
|
||||
Field* fieldsWP = resultWP->Fetch();
|
||||
uint32 entry = fieldsWP[0].GetUInt32();
|
||||
uint8 chainId = fieldsWP[1].GetUInt8(), splineId = fieldsWP[2].GetUInt8(), wpId = fieldsWP[3].GetUInt8();
|
||||
float posX = fieldsWP[4].GetFloat(), posY = fieldsWP[5].GetFloat(), posZ = fieldsWP[6].GetFloat();
|
||||
auto it = m_mSplineChainsMap.find({entry,chainId});
|
||||
if (it == m_mSplineChainsMap.end())
|
||||
{
|
||||
TC_LOG_WARN("server.loading", "Creature #%u has waypoint data for spline chain %u. No such chain exists - entry skipped.", entry, chainId);
|
||||
continue;
|
||||
}
|
||||
SplineChain& chain = it->second;
|
||||
if (splineId >= chain.size())
|
||||
{
|
||||
TC_LOG_WARN("server.loading", "Creature #%u has waypoint data for spline (%u,%u). The specified chain does not have a spline with this index - entry skipped.", entry, chainId, splineId);
|
||||
continue;
|
||||
}
|
||||
SplineChainLink& spline = chain[splineId];
|
||||
if (wpId != spline.Points.size())
|
||||
{
|
||||
TC_LOG_WARN("server.loading", "Creature #%u has orphaned waypoint data in spline (%u,%u) at index %u. Skipped.", entry, chainId, splineId, wpId);
|
||||
continue;
|
||||
}
|
||||
spline.Points.emplace_back(posX, posY, posZ);
|
||||
++wpCount;
|
||||
} while (resultWP->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded spline chain data for %u chains, consisting of %u splines with %u waypoints in %u ms", chainCount, splineCount, wpCount, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
}
|
||||
@@ -58,22 +58,35 @@ class TC_GAME_API SystemMgr
|
||||
|
||||
//Database
|
||||
void LoadScriptWaypoints();
|
||||
void LoadScriptSplineChains();
|
||||
|
||||
ScriptPointVector const& GetPointMoveList(uint32 creatureEntry) const
|
||||
ScriptPointVector const* GetPointMoveList(uint32 creatureEntry) const
|
||||
{
|
||||
PointMoveMap::const_iterator itr = m_mPointMoveMap.find(creatureEntry);
|
||||
|
||||
if (itr == m_mPointMoveMap.end())
|
||||
return _empty;
|
||||
return nullptr;
|
||||
|
||||
return itr->second;
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
SplineChain const* GetSplineChain(uint32 entry, uint8 id) const
|
||||
{
|
||||
auto it = m_mSplineChainsMap.find({ entry, id });
|
||||
if (it == m_mSplineChainsMap.end())
|
||||
return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
SplineChain const* GetSplineChain(Creature const* who, uint8 id) const
|
||||
{
|
||||
return GetSplineChain(who->GetEntry(), id);
|
||||
}
|
||||
|
||||
protected:
|
||||
PointMoveMap m_mPointMoveMap; //coordinates for waypoints
|
||||
|
||||
private:
|
||||
static ScriptPointVector const _empty;
|
||||
typedef std::pair<uint32, uint8> ChainKeyType; // creature entry + chain ID
|
||||
std::unordered_map<ChainKeyType, SplineChain> m_mSplineChainsMap; // spline chains
|
||||
};
|
||||
|
||||
#define sScriptSystemMgr SystemMgr::instance()
|
||||
|
||||
+1
@@ -1272,6 +1272,7 @@ class npc_crate_helper : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void AddSC_culling_of_stratholme()
|
||||
{
|
||||
new npc_arthas();
|
||||
|
||||
Reference in new issue
Block a user