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 FlightPath movement generator splitting
Browse files Browse the repository at this point in the history
* up to e19bb7a
  • Loading branch information
Ovahlord committed Aug 29, 2018
1 parent 416e6b3 commit 2ead9a1
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 279 deletions.
2 changes: 1 addition & 1 deletion src/server/game/Handlers/TaxiHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
#include "Creature.h"
#include "DatabaseEnv.h"
#include "DBCStores.h"
#include "FlightPathMovementGenerator.h"
#include "Log.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "Player.h"
#include "WaypointMovementGenerator.h"
#include "WorldPacket.h"

void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData)
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Movement/MotionMaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "CreatureAISelector.h"
#include "DBCStores.h"
#include "FleeingMovementGenerator.h"
#include "FlightPathMovementGenerator.h"
#include "FormationMovementGenerator.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
* Copyright (C) 2008-2017 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 "FlightPathMovementGenerator.h"
#include "DBCStores.h"
#include "Log.h"
#include "MapManager.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
#include "ObjectMgr.h"
#include "Player.h"

//----------------------------------------------------//

#define FLIGHT_TRAVEL_UPDATE 100
#define TIMEDIFF_NEXT_WP 250
#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.f * 40.f)
#define PLAYER_FLIGHT_SPEED 32.0f

FlightPathMovementGenerator::FlightPathMovementGenerator(uint32 startNode)
{
_currentNode = startNode;
_endGridX = 0.0f;
_endGridY = 0.0f;
_endMapId = 0;
_preloadTargetNode = 0;
}

uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
{
if (_currentNode >= _path.size())
return _path.size();

uint32 curMapId = _path[_currentNode]->MapID;
for (uint32 itr = _currentNode; itr < _path.size(); ++itr)
if (_path[itr]->MapID != curMapId)
return itr;

return _path.size();
}

bool IsNodeIncludedInShortenedPath(TaxiPathNodeEntry const* p1, TaxiPathNodeEntry const* p2)
{
return p1->MapID != p2->MapID || std::pow(p1->LocX - p2->LocX, 2) + std::pow(p1->LocY - p2->LocY, 2) > SKIP_SPLINE_POINT_DISTANCE_SQ;
}

void FlightPathMovementGenerator::LoadPath(Player* player)
{
_pointsForPathSwitch.clear();
std::deque<uint32> const& taxi = player->m_taxi.GetPath();
for (uint32 src = 0, dst = 1; dst < taxi.size(); src = dst++)
{
uint32 path, cost;
sObjectMgr->GetTaxiPath(taxi[src], taxi[dst], path, cost);
if (path > sTaxiPathNodesByPath.size())
return;

TaxiPathNodeList const& nodes = sTaxiPathNodesByPath[path];
if (!nodes.empty())
{
TaxiPathNodeEntry const* start = nodes[0];
TaxiPathNodeEntry const* end = nodes[nodes.size() - 1];
bool passedPreviousSegmentProximityCheck = false;
for (uint32 i = 0; i < nodes.size(); ++i)
{
if (passedPreviousSegmentProximityCheck || !src || _path.empty() || IsNodeIncludedInShortenedPath(_path[_path.size() - 1], nodes[i]))
{
if ((!src || (IsNodeIncludedInShortenedPath(start, nodes[i]) && i >= 2)) &&
(dst == taxi.size() - 1 || (IsNodeIncludedInShortenedPath(end, nodes[i]) && i < nodes.size() - 1)))
{
passedPreviousSegmentProximityCheck = true;
_path.push_back(nodes[i]);
}
}
else
{
_path.pop_back();
--_pointsForPathSwitch.back().PathIndex;
}
}
}

_pointsForPathSwitch.push_back({ uint32(_path.size() - 1), int32(cost) });
}
}

void FlightPathMovementGenerator::DoInitialize(Player* player)
{
Reset(player);
InitEndGridInfo();
}

void FlightPathMovementGenerator::DoFinalize(Player* player)
{
// remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
player->ClearUnitState(UNIT_STATE_IN_FLIGHT);

player->Dismount();
player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_TAXI_FLIGHT);

if (player->m_taxi.empty())
{
player->getHostileRefManager().setOnlineOfflineState(true);
// update z position to ground and orientation for landing point
// this prevent cheating with landing point at lags
// when client side flight end early in comparison server side
player->StopMoving();
player->SetFallInformation(0, player->GetPositionZ());
}

player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_TAXI_BENCHMARK);
}

void FlightPathMovementGenerator::DoReset(Player* player)
{
player->getHostileRefManager().setOnlineOfflineState(false);
player->AddUnitState(UNIT_STATE_IN_FLIGHT);
player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_TAXI_FLIGHT);

Movement::MoveSplineInit init(player);
uint32 end = GetPathAtMapEnd();
for (uint32 i = GetCurrentNode(); i != end; ++i)
{
G3D::Vector3 vertice(_path[i]->LocX, _path[i]->LocY, _path[i]->LocZ);
init.Path().push_back(vertice);
}
init.SetFirstPointId(GetCurrentNode());
init.SetFly();
init.SetVelocity(PLAYER_FLIGHT_SPEED);
init.Launch();
}

bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
{
uint32 pointId = (uint32)player->movespline->currentPathIdx();
if (pointId > _currentNode)
{
bool departureEvent = true;
do
{
DoEventIfAny(player, _path[_currentNode], departureEvent);
while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= _currentNode)
{
_pointsForPathSwitch.pop_front();
player->m_taxi.NextTaxiDestination();
if (!_pointsForPathSwitch.empty())
{
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, _pointsForPathSwitch.front().Cost);
player->ModifyMoney(-_pointsForPathSwitch.front().Cost);
}
}

if (pointId == _currentNode)
break;

if (_currentNode == _preloadTargetNode)
PreloadEndGrid();
_currentNode += departureEvent ? 1 : 0;
departureEvent = !departureEvent;
} while (true);
}

return _currentNode < (_path.size() - 1);
}

void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
{
if (_path.empty() || _currentNode >= _path.size())
return;

uint32 map0 = _path[_currentNode]->MapID;
for (size_t i = _currentNode + 1; i < _path.size(); ++i)
{
if (_path[i]->MapID != map0)
{
_currentNode = i;
return;
}
}
}

void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure)
{
if (uint32 eventid = departure ? node->DepartureEventID : node->ArrivalEventID)
{
TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node->NodeIndex, node->PathID, player->GetName().c_str());
player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player);
}
}

bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z)
{
TaxiPathNodeEntry const* node = _path[_currentNode];
x = node->LocX;
y = node->LocY;
z = node->LocZ;
return true;
}

void FlightPathMovementGenerator::InitEndGridInfo()
{
/*! Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. */
uint32 nodeCount = _path.size(); //! Number of nodes in path.
_endMapId = _path[nodeCount - 1]->MapID; //! MapId of last node
_preloadTargetNode = nodeCount - 3;
_endGridX = _path[nodeCount - 1]->LocX;
_endGridY = _path[nodeCount - 1]->LocY;
}

void FlightPathMovementGenerator::PreloadEndGrid()
{
// used to preload the final grid where the flightmaster is
Map* endMap = sMapMgr->FindBaseNonInstanceMap(_endMapId);

// Load the grid
if (endMap)
{
TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(_path.size() - 1));
endMap->LoadGrid(_endGridX, _endGridY);
}
else
TC_LOG_DEBUG("misc", "Unable to determine map to preload flightmaster grid");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2008-2017 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 FlightPathMovementGenerator_h__
#define FlightPathMovementGenerator_h__

#include "DBCStructure.h"
#include "MovementGenerator.h"
#include "PathMovementBase.h"

class Player;

/**
* FlightPathMovementGenerator generates movement of the player for the paths
* and hence generates ground and activities for the player.
*/
class FlightPathMovementGenerator : public MovementGeneratorMedium<Player, FlightPathMovementGenerator>, public PathMovementBase<Player, TaxiPathNodeList>
{
public:
explicit FlightPathMovementGenerator(uint32 startNode = 0);

void LoadPath(Player* player);
void DoInitialize(Player*);
void DoReset(Player*);
void DoFinalize(Player*);
bool DoUpdate(Player*, uint32);
MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; }

TaxiPathNodeList const& GetPath() { return _path; }
uint32 GetPathAtMapEnd() const;
bool HasArrived() const { return (_currentNode >= _path.size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++_currentNode; }
void DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure);

bool GetResetPos(Player*, float& x, float& y, float& z);
void InitEndGridInfo();
void PreloadEndGrid();

private:

float _endGridX; //! X coord of last node location
float _endGridY; //! Y coord of last node location
uint32 _endMapId; //! map Id of last node location
uint32 _preloadTargetNode; //! node index where preloading starts

struct TaxiNodeChangeInfo
{
uint32 PathIndex;
int32 Cost;
};

std::deque<TaxiNodeChangeInfo> _pointsForPathSwitch; //! node indexes and costs where TaxiPath changes
};

#endif // FlightPathMovementGenerator_h__
37 changes: 37 additions & 0 deletions src/server/game/Movement/MovementGenerators/PathMovementBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2008-2017 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 PathMovementBase_h__
#define PathMovementBase_h__

#include "Define.h"

template<class Entity, class BasePath>
class PathMovementBase
{
public:
PathMovementBase() : _path(), _currentNode(0) { }
virtual ~PathMovementBase() { };

uint32 GetCurrentNode() const { return _currentNode; }

protected:
BasePath _path;
uint32 _currentNode;
};

#endif // PathMovementBase_h__
Loading

0 comments on commit 2ead9a1

Please sign in to comment.