Core/Transports: undo all custom transport changes as preparation for cherry picks

This commit is contained in:
Ovahlord committed 2022-06-18 18:37:14 +02:00
1 parent 74c60fa456
commit 6e9ec1a4bf
46 files changed
+618 -1469

No files matched your search

@@ -65,7 +65,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, power4, power5, instance_id, talentGroupsCount, activeTalentGroup, "
"exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, fishingSteps, trans_spawn_id "
"exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, fishingSteps "
"FROM characters c LEFT JOIN character_fishingsteps cfs ON c.guid = cfs.guid WHERE c.guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -379,16 +379,16 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// Player saving
PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, "
"map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, trans_spawn_id, "
"map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, "
"taximask, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, "
"extra_flags, stable_slots, at_login, zone, "
"death_expire_time, taxi_path, totalKills, "
"todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, "
"power4, power5, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, achievementPoints) VALUES "
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,bankSlots=?,restState=?,playerFlags=?,"
"map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?, trans_spawn_id=?,taximask=?,cinematic=?,"
"map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,"
"totaltime=?,leveltime=?,rest_bonus=?,logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
"watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,exploredZones=?,"
+6 -22
View File
@@ -32,7 +32,6 @@
#include "MiscPackets.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Transport.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include <G3D/g3dmath.h>
@@ -787,28 +786,13 @@ Creature* Battlefield::SpawnCreature(uint32 entry, Position const& pos)
GameObject* Battlefield::SpawnGameObject(uint32 entry, Position const& pos, QuaternionData const& rot)
{
// Create gameobject
GameObject* go = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(entry) == GAMEOBJECT_TYPE_TRANSPORT)
GameObject* go = new GameObject;
if (!go->Create(m_Map->GenerateLowGuid<HighGuid::GameObject>(), entry, m_Map, pos, rot, 255, GO_STATE_READY))
{
go = new Transport();
if (!go->Create(m_Map->GenerateLowGuid<HighGuid::Transport>(), entry, m_Map, pos, rot, 255, GO_STATE_READY))
{
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u could not be found in the database! Battlefield has not been created!", entry);
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Could not create gameobject template %u! Battlefield has not been created!", entry);
delete go;
return nullptr;
}
}
else
{
go = new GameObject();
if (!go->Create(m_Map->GenerateLowGuid<HighGuid::GameObject>(), entry, m_Map, pos, rot, 255, GO_STATE_READY))
{
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u could not be found in the database! Battlefield has not been created!", entry);
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Could not create gameobject template %u! Battlefield has not been created!", entry);
delete go;
return nullptr;
}
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u could not be found in the database! Battlefield has not been created!", entry);
TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Could not create gameobject template %u! Battlefield has not been created!", entry);
delete go;
return nullptr;
}
// Add to world
+8 -23
View File
@@ -1457,28 +1457,13 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float
// Must be created this way, adding to godatamap would add it to the base map of the instance
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
// So we must create it specific for this instance
GameObject* go = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(entry) == GAMEOBJECT_TYPE_TRANSPORT)
GameObject* go = new GameObject;
if (!go->Create(GetBgMap()->GenerateLowGuid<HighGuid::GameObject>(), entry, GetBgMap(), Position(x, y, z, o), rot, 255, goState))
{
go = new Transport();
if (!go->Create(GetBgMap()->GenerateLowGuid<HighGuid::Transport>(), entry, GetBgMap(), Position(x, y, z, o), rot, 255, goState))
{
TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create transport (entry: %u) for BG (map: %u, instance id: %u)!",
entry, m_MapId, m_InstanceID);
delete go;
return false;
}
}
else
{
go = new GameObject();
if (!go->Create(GetBgMap()->GenerateLowGuid<HighGuid::GameObject>(), entry, GetBgMap(), Position(x, y, z, o), rot, 255, goState))
{
TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!",
entry, m_MapId, m_InstanceID);
delete go;
return false;
}
TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!",
entry, m_MapId, m_InstanceID);
delete go;
return false;
}
/*
@@ -1594,7 +1579,7 @@ void Battleground::SpawnBGObject(uint32 type, uint32 respawntime)
}
}
Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, MapTransport* transport)
Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)
{
// If the assert is called, means that BgCreatures must be resized!
ASSERT(type < BgCreatures.size());
@@ -1648,7 +1633,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y,
return creature;
}
Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, MapTransport* transport)
Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)
{
return AddCreature(entry, type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId, respawntime, transport);
}
+3 -3
View File
@@ -30,7 +30,7 @@ class Creature;
class GameObject;
class Group;
class Player;
class MapTransport;
class Transport;
class Unit;
class WorldObject;
class WorldPacket;
@@ -465,8 +465,8 @@ class TC_GAME_API Battleground
void SpawnBGObject(uint32 type, uint32 respawntime);
virtual bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY);
bool AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY);
virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, MapTransport* transport = nullptr);
Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, MapTransport* transport = nullptr);
virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = nullptr);
Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = nullptr);
bool DelCreature(uint32 type);
bool DelObject(uint32 type);
virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL);
@@ -992,8 +992,8 @@ class BattlegroundIC : public Battleground
BG_IC_GateState GateStatus[6];
ICNodePoint nodePoint[7];
MapTransport* gunshipAlliance;
MapTransport* gunshipHorde;
Transport* gunshipAlliance;
Transport* gunshipHorde;
uint32 GetNextBanner(ICNodePoint* node, uint32 team, bool returnDefinitve);
@@ -25,7 +25,6 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "Transport.h"
#include "UpdateData.h"
#include "WorldPacket.h"
#include "WorldStatePackets.h"
@@ -282,9 +281,10 @@ bool BattlegroundSA::ResetObjs()
UpdateWorldState(BG_SA_YELLOW_GATEWS, 1);
UpdateWorldState(BG_SA_ANCIENT_GATEWS, 1);
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
SendTransportInit(player);
for (int i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; i++)
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
SendTransportInit(player);
// set status manually so preparation is cast correctly in 2nd round too
SetStatus(STATUS_WAIT_JOIN);
@@ -298,27 +298,23 @@ void BattlegroundSA::StartShips()
if (ShipsStarted)
return;
for (uint8 i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; ++i)
if (GameObject* obj = GetBGObject(i))
if (Transport* transport = obj->ToTransport())
transport->SetTransportState(GO_STATE_TRANSPORT_STOPPED, 1);
DoorOpen(BG_SA_BOAT_ONE);
DoorOpen(BG_SA_BOAT_TWO);
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
for (int i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; i++)
{
if (Player* p = ObjectAccessor::FindPlayer(itr->first))
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
{
UpdateData data(GetMapId());
for (uint8 i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; ++i)
if (GameObject* obj = GetBGObject(i))
obj->BuildValuesUpdateBlockForPlayer(&data, p);
WorldPacket pkt;
data.BuildPacket(&pkt);
p->SendDirectMessage(&pkt);
if (Player* p = ObjectAccessor::FindPlayer(itr->first))
{
UpdateData data(p->GetMapId());
WorldPacket pkt;
GetBGObject(i)->BuildValuesUpdateBlockForPlayer(&data, p);
data.BuildPacket(&pkt);
p->SendDirectMessage(&pkt);
}
}
}
ShipsStarted = true;
}
@@ -153,6 +153,8 @@ GameObject::~GameObject()
{
delete m_AI;
delete m_model;
if (m_goInfo && m_goInfo->type == GAMEOBJECT_TYPE_TRANSPORT)
delete m_goValue.Transport.StopFrames;
//if (m_uint32Values) // field array can be not exist if GameOBject not loaded
// CleanupsBeforeDelete();
}
@@ -224,7 +226,7 @@ void GameObject::AddToWorld()
bool toggledState = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : (GetGoState() == GO_STATE_READY || IsTransport());
if (m_model)
{
if (MapTransport* trans = ToMapTransport())
if (Transport* trans = ToTransport())
trans->SetDelayedAddModelToMap();
else
GetMap()->InsertGameObjectModel(*m_model);
@@ -300,6 +302,9 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, P
return false;
}
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
m_updateFlag |= UPDATEFLAG_TRANSPORT;
Object::_Create(guidlow, goinfo->entry, HighGuid::GameObject);
m_goInfo = goinfo;
@@ -356,6 +361,36 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, P
SetGoAnimProgress(255);
SetUInt32Value(GAMEOBJECT_PARENTROTATION, m_goInfo->building.destructibleData);
break;
case GAMEOBJECT_TYPE_TRANSPORT:
{
m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goinfo->entry);
m_goValue.Transport.PathProgress = getMSTime();
if (m_goValue.Transport.AnimationInfo)
m_goValue.Transport.PathProgress -= m_goValue.Transport.PathProgress % GetTransportPeriod(); // align to period
m_goValue.Transport.CurrentSeg = 0;
m_goValue.Transport.StateUpdateTimer = 0;
m_goValue.Transport.StopFrames = new std::vector<uint32>();
if (goinfo->transport.Timeto2ndfloor > 0)
{
if (!goinfo->transport.startOpen)
m_goValue.Transport.StopFrames->push_back(0);
m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto2ndfloor);
}
if (goinfo->transport.Timeto3rdfloor > 0)
m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto3rdfloor);
if (goinfo->transport.Timeto4thfloor > 0)
m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto4thfloor);
if (goinfo->transport.Timeto5thfloor > 0)
m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto5thfloor);
if (goinfo->transport.startOpen)
SetTransportState(GO_STATE_TRANSPORT_STOPPED, goinfo->transport.startOpen - 1);
else
SetTransportState(GO_STATE_TRANSPORT_ACTIVE);
SetGoAnimProgress(animprogress);
break;
}
case GAMEOBJECT_TYPE_FISHINGNODE:
SetGoAnimProgress(0);
break;
@@ -461,6 +496,53 @@ void GameObject::Update(uint32 diff)
SetLootState(GO_READY);
break;
}
case GAMEOBJECT_TYPE_TRANSPORT:
{
if (!m_goValue.Transport.AnimationInfo)
break;
if (GetGoState() == GO_STATE_TRANSPORT_ACTIVE)
{
m_goValue.Transport.PathProgress += diff;
/* TODO: Fix movement in unloaded grid - currently GO will just disappear
uint32 timer = m_goValue.Transport.PathProgress % GetTransportPeriod();
TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo->GetAnimNode(timer);
if (node && m_goValue.Transport.CurrentSeg != node->TimeSeg)
{
m_goValue.Transport.CurrentSeg = node->TimeSeg;
G3D::Quat rotation;
if (TransportRotationEntry const* rot = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer))
rotation = G3D::Quat(rot->X, rot->Y, rot->Z, rot->W);
G3D::Vector3 pos = rotation.toRotationMatrix()
* G3D::Matrix3::fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f)
* G3D::Vector3(node->X, node->Y, node->Z);
pos += G3D::Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
G3D::Vector3 src(GetPositionX(), GetPositionY(), GetPositionZ());
TC_LOG_DEBUG("misc", "Src: %s Dest: %s", src.toString().c_str(), pos.toString().c_str());
GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
}
*/
if (!m_goValue.Transport.StopFrames->empty())
{
uint32 visualStateBefore = (m_goValue.Transport.StateUpdateTimer / 20000) & 1;
m_goValue.Transport.StateUpdateTimer += diff;
uint32 visualStateAfter = (m_goValue.Transport.StateUpdateTimer / 20000) & 1;
if (visualStateBefore != visualStateAfter)
{
ForceValuesUpdateAtIndex(GAMEOBJECT_LEVEL);
ForceValuesUpdateAtIndex(GAMEOBJECT_BYTES_1);
}
}
}
break;
}
case GAMEOBJECT_TYPE_FISHINGNODE:
{
// fishing code (bobber ready)
@@ -1009,11 +1091,7 @@ bool GameObject::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap
m_spawnId = spawnId;
m_respawnCompatibilityMode = ((data->spawnGroupData->flags & SPAWNGROUP_FLAG_COMPATIBILITY_MODE) != 0);
uint32 gameObjectType = sObjectMgr->GetGameObjectTypeByEntry(entry);
ObjectGuid::LowType lowGuid = gameObjectType == GAMEOBJECT_TYPE_TRANSPORT ? map->GenerateLowGuid<HighGuid::Transport>() : map->GenerateLowGuid<HighGuid::GameObject>();
if (!Create(lowGuid, entry, map, data->spawnPoint, data->rotation, animprogress, go_state, artKit, !m_respawnCompatibilityMode))
if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, data->spawnPoint, data->rotation, animprogress, go_state, artKit, !m_respawnCompatibilityMode))
return false;
PhasingHandler::InitDbPhaseShift(GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup);
@@ -2421,6 +2499,48 @@ void GameObject::SetGoState(GOState state)
}
}
uint32 GameObject::GetTransportPeriod() const
{
ASSERT(GetGOInfo()->type == GAMEOBJECT_TYPE_TRANSPORT);
if (m_goValue.Transport.AnimationInfo)
return m_goValue.Transport.AnimationInfo->TotalTime;
// return something that will nicely divide for GAMEOBJECT_DYNAMIC value calculation
return m_goValue.Transport.PathProgress;
}
void GameObject::SetTransportState(GOState state, uint32 stopFrame /*= 0*/)
{
if (GetGoState() == state)
return;
ASSERT(GetGOInfo()->type == GAMEOBJECT_TYPE_TRANSPORT);
ASSERT(state >= GO_STATE_TRANSPORT_ACTIVE);
if (state == GO_STATE_TRANSPORT_ACTIVE)
{
m_goValue.Transport.StateUpdateTimer = 0;
m_goValue.Transport.PathProgress = getMSTime();
if (GetGoState() >= GO_STATE_TRANSPORT_STOPPED)
m_goValue.Transport.PathProgress += m_goValue.Transport.StopFrames->at(GetGoState() - GO_STATE_TRANSPORT_STOPPED);
SetGoState(GO_STATE_TRANSPORT_ACTIVE);
}
else
{
ASSERT(state < GOState(GO_STATE_TRANSPORT_STOPPED + MAX_GO_STATE_TRANSPORT_STOP_FRAMES));
ASSERT(stopFrame < m_goValue.Transport.StopFrames->size());
uint32 stopFrameTime = m_goValue.Transport.StopFrames->at(stopFrame);
if (!stopFrameTime) // returning to a previous stop frame that has no travel time (e.g. stop frame at 0ms)
stopFrameTime = m_goValue.Transport.StopFrames->at(stopFrame + 1);
m_goValue.Transport.PathProgress = getMSTime() + stopFrameTime;
SetGoState(GOState(GO_STATE_TRANSPORT_STOPPED + stopFrame));
}
ForceValuesUpdateAtIndex(GAMEOBJECT_LEVEL);
ForceValuesUpdateAtIndex(GAMEOBJECT_BYTES_1);
}
void GameObject::SetDisplayId(uint32 displayid)
{
SetUInt32Value(GAMEOBJECT_DISPLAYID, displayid);
@@ -2519,6 +2639,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
if (!target)
return;
bool isStoppableTransport = GetGoType() == GAMEOBJECT_TYPE_TRANSPORT && !m_goValue.Transport.StopFrames->empty();
bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.groupLootRules && HasLootRecipient();
bool targetIsGM = target->IsGameMaster();
@@ -2561,12 +2682,16 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
dynFlags |= GO_DYNFLAG_LO_SPARKLE;
break;
case GAMEOBJECT_TYPE_TRANSPORT:
{
float timer = float(m_goValue.Transport.PathProgress % GetTransportPeriod());
pathProgress = int16(timer / float(GetTransportPeriod()) * 65535.0f);
break;
}
case GAMEOBJECT_TYPE_MO_TRANSPORT:
{
Transport const* transport = ToTransport();
if (uint32 transportPeriod = transport->GetTransportPeriod())
if (uint32 transportPeriod = GetTransportPeriod())
{
float timer = float(transport->GetTimer() % transportPeriod);
float timer = float(m_goValue.Transport.PathProgress % transportPeriod);
pathProgress = int16(timer / float(transportPeriod) * 65535.0f);
}
break;
@@ -2587,6 +2712,27 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
fieldBuffer << goFlags;
}
else if (index == GAMEOBJECT_LEVEL)
{
if (isStoppableTransport)
fieldBuffer << uint32(m_goValue.Transport.PathProgress);
else
fieldBuffer << m_uint32Values[index];
}
else if (index == GAMEOBJECT_BYTES_1)
{
uint32 bytes1 = m_uint32Values[index];
if (isStoppableTransport && GetGoState() == GO_STATE_TRANSPORT_ACTIVE)
{
if ((m_goValue.Transport.StateUpdateTimer / 20000) & 1)
{
bytes1 &= 0xFFFFFF00;
bytes1 |= GO_STATE_TRANSPORT_STOPPED;
}
}
fieldBuffer << bytes1;
}
else
fieldBuffer << m_uint32Values[index]; // other cases
}
@@ -2687,75 +2833,6 @@ GameObjectModel* GameObject::CreateModel()
return GameObjectModel::Create(Trinity::make_unique<GameObjectModelOwnerImpl>(this), sWorld->GetDataPath());
}
float GameObject::GetStationaryX() const
{
if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT)
return GetPositionX();
return m_stationaryPosition.GetPositionX();
}
float GameObject::GetStationaryY() const
{
if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT)
return GetPositionY();
return m_stationaryPosition.GetPositionY();
}
float GameObject::GetStationaryZ() const
{
if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT)
return GetPositionZ();
return m_stationaryPosition.GetPositionZ();
}
float GameObject::GetStationaryO() const
{
if (IsTransport())
return GetOrientation();
return m_stationaryPosition.GetOrientation();
}
void GameObject::RelocateStationaryPosition(float x, float y, float z, float o)
{
m_stationaryPosition.Relocate(x, y, z, o);
}
Transport* GameObject::ToTransport()
{
if (IsTransport())
return reinterpret_cast<Transport*>(this);
return nullptr;
}
Transport const* GameObject::ToTransport() const
{
if (IsTransport())
return reinterpret_cast<Transport const*>(this);
return nullptr;
}
MapTransport* GameObject::ToMapTransport()
{
if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT)
return reinterpret_cast<MapTransport*>(this);
return nullptr;
}
MapTransport const* GameObject::ToMapTransport() const
{
if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT)
return reinterpret_cast<MapTransport const*>(this);
return nullptr;
}
bool GameObject::IsAtInteractDistance(Player const* player, SpellInfo const* spell) const
{
if (spell || (spell = GetSpellForLock(player)))
@@ -42,7 +42,9 @@ union GameObjectValue
{
uint32 PathProgress;
TransportAnimation const* AnimationInfo;
uint32 CurrentSeg;
std::vector<uint32>* StopFrames;
uint32 StateUpdateTimer;
} Transport;
//25 GAMEOBJECT_TYPE_FISHINGHOLE
struct
@@ -89,7 +91,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void RemoveFromWorld() override;
void CleanupsBeforeDelete(bool finalCleanup = true) override;
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0, bool dynamic = false, ObjectGuid::LowType spawnid = 0);
bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0, bool dynamic = false, ObjectGuid::LowType spawnid = 0);
void Update(uint32 p_time) override;
GameObjectTemplate const* GetGOInfo() const { return m_goInfo; }
GameObjectTemplateAddon const* GetTemplateAddon() const { return m_goTemplateAddon; }
@@ -163,6 +165,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
void SetGoState(GOState state);
virtual uint32 GetTransportPeriod() const;
void SetTransportState(GOState state, uint32 stopFrame = 0);
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
void SetGoArtKit(uint8 artkit);
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
@@ -275,17 +279,14 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
GameObjectModel* m_model;
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr) const;
Transport* ToTransport();
Transport const* ToTransport() const;
Transport* ToTransport() { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport*>(this); else return nullptr; }
Transport const* ToTransport() const { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport const*>(this); else return nullptr; }
MapTransport* ToMapTransport();
MapTransport const* ToMapTransport() const;
float GetStationaryX() const override;
float GetStationaryY() const override;
float GetStationaryZ() const override;
float GetStationaryO() const override;
void RelocateStationaryPosition(float x, float y, float z, float o);
float GetStationaryX() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionX(); return GetPositionX(); }
float GetStationaryY() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); }
float GetStationaryZ() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); }
float GetStationaryO() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); }
void RelocateStationaryPosition(float x, float y, float z, float o) { m_stationaryPosition.Relocate(x, y, z, o); }
float GetInteractionDistance() const;
@@ -302,8 +303,6 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void AIM_Destroy();
bool AIM_Initialize();
void SetSpawnId(uint32 spawnId) { m_spawnId = spawnId; }
protected:
GameObjectModel* CreateModel();
void UpdateModel(); // updates model in case displayId were changed
+14 -59
View File
@@ -659,15 +659,16 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint32 flags) const
if (flags & UPDATEFLAG_TRANSPORT)
{
if (GameObject const* go = ToGameObject())
{
if (MapTransport const* transport = go->ToMapTransport())
*data << uint32(transport->GetTimer());
else if (Transport const* transport = go->ToTransport())
*data << uint32(transport->IsDynamicTransport() ? transport->GetTimer() : getMSTime());
else
*data << uint32(getMSTime());
}
GameObject const* go = ToGameObject();
/** @TODO Use IsTransport() to also handle type 11 (TRANSPORT)
Currently grid objects are not updated if there are no nearby players,
this causes clients to receive different PathProgress
resulting in players seeing the object in a different position
*/
if (go && go->ToTransport())
*data << uint32(go->GetGOValue()->Transport.PathProgress);
else
*data << uint32(GameTime::GetGameTimeMS());
}
}
@@ -2094,20 +2095,6 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonCreatur
return nullptr;
}
// Add summon to transport if summoner is on a transport as well
if (summon->GetTransGUID().IsEmpty() && summonArgs.Summoner)
{
if (Transport* transport = summonArgs.Summoner->GetTransport())
{
float x, y, z, o;
pos.GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
summon->m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(summon);
}
}
// Inherit summoner's Phaseshift
if (summonArgs.Summoner)
PhasingHandler::InheritPhaseShift(summon, summonArgs.Summoner);
@@ -2221,24 +2208,11 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, Qua
}
Map* map = GetMap();
GameObject* go = nullptr;
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
GameObject* go = new GameObject();
if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, pos, rot, 255, GO_STATE_READY))
{
go = new Transport();
if (!go->Create(map->GenerateLowGuid<HighGuid::Transport>(), entry, map, pos, rot, 255, GO_STATE_READY))
{
delete go;
return nullptr;
}
}
else
{
go = new GameObject();
if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, pos, rot, 255, GO_STATE_READY))
{
delete go;
return nullptr;
}
delete go;
return nullptr;
}
PhasingHandler::InheritPhaseShift(go, this);
@@ -2249,17 +2223,6 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, Qua
else
go->SetSpawnedByDefault(false);
Transport* transport = GetTransGUID().IsEmpty() ? GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
go->GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
go->m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(go);
}
map->AddToMap(go);
return go;
}
@@ -2789,14 +2752,6 @@ ObjectGuid WorldObject::GetTransGUID() const
return ObjectGuid::Empty;
}
MapTransport* WorldObject::GetMapTransport() const
{
if (GetTransport())
return GetTransport()->ToMapTransport();
return nullptr;
}
float WorldObject::GetFloorZ() const
{
if (!IsInWorld())
-3
View File
@@ -47,7 +47,6 @@ class Map;
class Player;
class TempSummon;
class Transport;
class MapTransport;
class Unit;
class UpdateData;
class WorldObject;
@@ -468,8 +467,6 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
virtual ObjectGuid GetTransGUID() const;
void SetTransport(Transport* t) { m_transport = t; }
MapTransport* GetMapTransport() const;
MovementInfo m_movementInfo;
virtual float GetStationaryX() const { return GetPositionX(); }
@@ -52,6 +52,7 @@ char const* ObjectGuid::GetTypeName(HighGuid high)
case HighGuid::Corpse: return "Corpse";
case HighGuid::AreaTrigger: return "AreaTrigger";
case HighGuid::BattleGround: return "Battleground";
case HighGuid::Mo_Transport: return "MoTransport";
case HighGuid::Instance: return "InstanceID";
case HighGuid::Group: return "Group";
case HighGuid::Guild: return "Guild";
@@ -131,5 +132,6 @@ GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Unit)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Pet)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vehicle)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Mo_Transport)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Instance)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Group)
+10 -17
View File
@@ -63,6 +63,7 @@ enum class HighGuid
Container = 0x400, // blizz 4000
Player = 0x000, // blizz 0000
GameObject = 0xF11, // blizz F110
Transport = 0xF12, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
Unit = 0xF13, // blizz F130
Pet = 0xF14, // blizz F140
Vehicle = 0xF15, // blizz F550
@@ -70,7 +71,7 @@ enum class HighGuid
Corpse = 0xF101, // blizz F100
AreaTrigger = 0xF102,
BattleGround = 0x1F1,
Transport = 0x1FC, // blizz 1FC0
Mo_Transport = 0x1FC, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
Instance = 0x1F4, // blizz 1F40
Group = 0x1F5,
Guild = 0x1FF
@@ -97,11 +98,13 @@ struct ObjectGuidTraits
static bool const MapSpecific = true; \
}
GUID_TRAIT_GLOBAL(HighGuid::Mo_Transport);
GUID_TRAIT_GLOBAL(HighGuid::Group);
GUID_TRAIT_GLOBAL(HighGuid::Instance);
GUID_TRAIT_GLOBAL(HighGuid::BattleGround);
GUID_TRAIT_GLOBAL(HighGuid::Player);
GUID_TRAIT_GLOBAL(HighGuid::Item);
GUID_TRAIT_GLOBAL(HighGuid::Transport);
GUID_TRAIT_GLOBAL(HighGuid::Guild);
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Unit);
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vehicle);
@@ -115,18 +118,6 @@ GUID_TRAIT_MAP_SPECIFIC(HighGuid::AreaTrigger);
#undef GUID_TRAIT_REALM_SPECIFIC
#undef GUID_TRAIT_MAP_SPECIFIC
// Special case
// Global transports are loaded from `transports` table, Global part is used for them.
// after worldserver finishes loading, no more global transports can be created, only the ones existing within instances that never change maps
// here is where MapSpecific comes into play - each map takes over the responsibility to generate transport guids
// on top of this, regular elevators (GAMEOBJECT_TYPE_TRANSPORT) must also use Transport highguid type, otherwise client will reject seeing other players on them
template<>
struct ObjectGuidTraits<HighGuid::Transport>
{
static bool const Global = true;
static bool const MapSpecific = true;
};
class ObjectGuid;
class PackedGuid;
@@ -147,7 +138,7 @@ class TC_GAME_API ObjectGuid
static typename std::enable_if<ObjectGuidTraits<type>::Global, ObjectGuid>::type Create(LowType counter) { return Global(type, counter); }
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific && type != HighGuid::Transport, ObjectGuid>::type Create(uint32 entry, LowType counter) { return MapSpecific(type, entry, counter); }
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific, ObjectGuid>::type Create(uint32 entry, LowType counter) { return MapSpecific(type, entry, counter); }
ObjectGuid() { _data._guid = UI64LIT(0); }
explicit ObjectGuid(uint64 guid) { _data._guid = guid; }
@@ -205,7 +196,8 @@ class TC_GAME_API ObjectGuid
bool IsAreaTrigger() const { return GetHigh() == HighGuid::AreaTrigger; }
bool IsBattleground() const { return GetHigh() == HighGuid::BattleGround; }
bool IsTransport() const { return GetHigh() == HighGuid::Transport; }
bool IsAnyTypeGameObject() const { return IsGameObject() || IsTransport(); }
bool IsMOTransport() const { return GetHigh() == HighGuid::Mo_Transport; }
bool IsAnyTypeGameObject() const { return IsGameObject() || IsTransport() || IsMOTransport(); }
bool IsInstance() const { return GetHigh() == HighGuid::Instance; }
bool IsGroup() const { return GetHigh() == HighGuid::Group; }
bool IsGuild() const { return GetHigh() == HighGuid::Guild; }
@@ -223,7 +215,7 @@ class TC_GAME_API ObjectGuid
case HighGuid::DynamicObject: return TYPEID_DYNAMICOBJECT;
case HighGuid::Corpse: return TYPEID_CORPSE;
case HighGuid::AreaTrigger: return TYPEID_AREATRIGGER;
case HighGuid::Transport: return TYPEID_GAMEOBJECT;
case HighGuid::Mo_Transport: return TYPEID_GAMEOBJECT;
case HighGuid::Vehicle: return TYPEID_UNIT;
// unknown
case HighGuid::Instance:
@@ -254,11 +246,12 @@ class TC_GAME_API ObjectGuid
case HighGuid::Player:
case HighGuid::DynamicObject:
case HighGuid::Corpse:
case HighGuid::Transport:
case HighGuid::Mo_Transport:
case HighGuid::Instance:
case HighGuid::Group:
return false;
case HighGuid::GameObject:
case HighGuid::Transport:
case HighGuid::Unit:
case HighGuid::Pet:
case HighGuid::Vehicle:
-45
View File
@@ -27,7 +27,6 @@
#include "SpellHistory.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "Transport.h"
#include "Unit.h"
#include "Util.h"
#include "Group.h"
@@ -184,17 +183,6 @@ bool Pet::LoadPetData(Player* owner, uint32 petEntry, uint32 petnumber, bool cur
return false;
}
Transport* transport = GetTransGUID().IsEmpty() ? owner->GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(this);
}
map->AddToMap(this->ToCreature());
return true;
}
@@ -282,17 +270,6 @@ bool Pet::LoadPetData(Player* owner, uint32 petEntry, uint32 petnumber, bool cur
owner->SendMessageToSet(&data, true);
}
Transport* transport = GetTransGUID().IsEmpty() ? owner->GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(this);
}
owner->SetMinion(this, true);
map->AddToMap(ToCreature());
@@ -689,17 +666,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
else
SetName(creature->GetNameForLocaleIdx(sObjectMgr->GetDBCLocaleIndex()));
Transport* transport = GetTransGUID().IsEmpty() ? creature->GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(this);
}
return true;
}
@@ -713,17 +679,6 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner)
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
Transport* transport = GetTransGUID().IsEmpty() ? owner->GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(this);
}
return true;
}
+47 -142
View File
@@ -211,7 +211,6 @@ Player::Player(WorldSession* session): Unit(true)
m_bCanDelayTeleport = false;
m_bHasDelayedTeleport = false;
m_teleport_options = 0;
m_teleport_transport = nullptr;
m_trade = nullptr;
@@ -372,8 +371,6 @@ Player::Player(WorldSession* session): Unit(true)
_archaeology = new Archaeology(this);
m_petScalingSynchTimer.Reset(1000);
m_groupUpdateTimer.Reset(5000);
_transportSpawnID = 0;
}
Player::~Player()
@@ -1337,7 +1334,7 @@ void Player::Update(uint32 p_time)
//we should execute delayed teleports only for alive(!) players
//because we don't want player's ghost teleported from graveyard
if (IsHasDelayedTeleport() && IsAlive())
TeleportTo(m_teleport_dest, m_teleport_options, m_teleport_transport);
TeleportTo(m_teleport_dest, m_teleport_options);
}
@@ -1420,7 +1417,7 @@ uint8 Player::GetChatTag() const
return tag;
}
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options, Transport* transport)
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options)
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
{
@@ -1499,7 +1496,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
//lets save teleport destination for player
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
m_teleport_options = options;
m_teleport_transport = transport;
return true;
}
@@ -1517,12 +1513,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
m_teleport_options = options;
SetFallInformation(0, GetPositionZ());
m_teleport_transport = transport;
// code for finish transfer called in WorldSession::HandleMovementOpcodes()
// at client packet CMSG_MOVE_TELEPORT_ACK
if (!GetTransport())
SetSemaphoreTeleportNear(true);
// near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing
if (!GetSession()->PlayerLogout())
{
@@ -1563,7 +1556,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
//lets save teleport destination for player
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
m_teleport_options = options;
m_teleport_transport = transport;
return true;
}
@@ -1631,7 +1623,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
PurgeAndApplyPendingMovementChanges(false);
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
m_teleport_transport = transport;
m_teleport_options = options;
SetFallInformation(0, GetPositionZ());
// if the player is saved before worldportack (at logout for example)
@@ -1655,9 +1646,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
return true;
}
bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/, Transport* transport /*=nullptr*/)
bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/)
{
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, transport);
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options);
}
bool Player::TeleportToBGEntryPoint()
@@ -17059,8 +17050,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
//"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
// 51 52 53 54 55 56 57 58 59 60 61
//"health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, "
// 62 63 64 65 66
//"knownTitles, actionBars, grantableLevels, fishing_steps, trans_spawn_id FROM characters WHERE guid = '%u'", guid);
// 62 63 64 65
//"knownTitles, actionBars, grantableLevels, fishing_steps FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
@@ -17203,7 +17194,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
// init saved position, and fix it later if problematic
ObjectGuid::LowType transLowGUID = fields[36].GetUInt32();
uint32 transSpawnId = fields[66].GetUInt32();
Relocate(fields[17].GetFloat(), fields[18].GetFloat(), fields[19].GetFloat(), fields[21].GetFloat());
@@ -17318,120 +17308,45 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
// currently we do not support transport in bg
else if (transLowGUID)
{
// if transSpawnId presents, then search for static transport (e.g. elevator)
// else - needs motiontransport
if (transSpawnId)
ObjectGuid transGUID(HighGuid::Mo_Transport, transLowGUID);
Transport* transport = nullptr;
if (Transport* go = HashMapHolder<Transport>::Find(transGUID))
transport = go;
if (transport)
{
map = sMapMgr->CreateMap(mapId, this, instanceId);
if (map)
float x = fields[32].GetFloat(), y = fields[33].GetFloat(), z = fields[34].GetFloat(), o = fields[35].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->CalculatePassengerPosition(x, y, z, &o);
if (!Trinity::IsValidMapCoord(x, y, z, o) ||
// transport size limited
std::fabs(m_movementInfo.transport.pos.GetPositionX()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
auto bounds = map->GetGameObjectBySpawnIdStore().equal_range(transSpawnId);
if (bounds.first != bounds.second)
m_transport = bounds.first->second->ToTransport();
}
TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
if (m_transport)
{
float x = fields[32].GetFloat(), y = fields[33].GetFloat(), z = fields[34].GetFloat(), o = fields[35].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
m_transport->CalculatePassengerPosition(x, y, z, &o);
m_movementInfo.transport.Reset();
if (!Trinity::IsValidMapCoord(x, y, z, o) ||
// transport size limited
std::fabs(m_movementInfo.transport.pos.GetPositionX()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
m_transport = nullptr;
m_movementInfo.transport.Reset();
RelocateToHomebind();
}
else
{
Relocate(x, y, z, o);
mapId = m_transport->GetMapId();
m_transport->AddPassenger(this);
}
RelocateToHomebind();
}
else
{
// transport not presents in world - just take go position from db
if (GameObjectData const* data = sObjectMgr->GetGameObjectData(transSpawnId))
{
float dataX = data->spawnPoint.GetPositionX();
float dataY = data->spawnPoint.GetPositionY();
float dataZ = data->spawnPoint.GetPositionZ();
float dataOrient = data->spawnPoint.GetOrientation();
Relocate(x, y, z, o);
mapId = transport->GetMapId();
float x = fields[32].GetFloat(), y = fields[33].GetFloat(), z = fields[34].GetFloat(), o = fields[35].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
TransportBase::CalculatePassengerPosition(x, y, z, &o, dataX, dataY, dataZ, dataOrient);
if (!Trinity::IsValidMapCoord(x, y, z, o) ||
// transport size limited
std::fabs(m_movementInfo.transport.pos.GetPositionX()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
TC_LOG_ERROR("entities.player", "Player (%s) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
m_movementInfo.transport.Reset();
RelocateToHomebind();
}
else
{
Relocate(x, y, z, o);
SetTransportSpawnID(transSpawnId);
}
}
transport->AddPassenger(this);
}
}
else
{
ObjectGuid transGUID = ObjectGuid::Create<HighGuid::Transport>(transLowGUID);
TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has problems with transport guid (%u). Teleport to bind location.",
guid.ToString().c_str(), transLowGUID);
if (MapTransport* go = ObjectAccessor::GetMapTransport(transGUID))
m_transport = go;
if (m_transport)
{
float x = fields[32].GetFloat(), y = fields[33].GetFloat(), z = fields[34].GetFloat(), o = fields[35].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
m_transport->CalculatePassengerPosition(x, y, z, &o);
if (!Trinity::IsValidMapCoord(x, y, z, o) ||
// transport size limited
std::fabs(m_movementInfo.transport.pos.GetPositionX()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
TC_LOG_ERROR("entities.player", "Player (%s) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
m_transport = nullptr;
m_movementInfo.transport.Reset();
RelocateToHomebind();
}
else
{
Relocate(x, y, z, o);
mapId = m_transport->GetMapId();
m_transport->AddPassenger(this);
}
}
else
{
TC_LOG_ERROR("entities.player", "Player (%s) have problems with transport guid (%u). Teleport to bind location.",
guid.ToString().c_str(), transLowGUID);
RelocateToHomebind();
}
RelocateToHomebind();
}
}
// currently we do not support taxi in instance
@@ -19610,14 +19525,9 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false
stmt->setFloat(index++, finiteAlways(GetTransOffsetZ()));
stmt->setFloat(index++, finiteAlways(GetTransOffsetO()));
ObjectGuid::LowType transLowGUID = 0;
uint32 transSpawnId = 0;
if (Transport* transport = GetTransport())
{
transLowGUID = transport->GetGUID().GetCounter();
transSpawnId = transport->GetSpawnId();
}
if (GetTransport())
transLowGUID = GetTransport()->GetGUID().GetCounter();
stmt->setUInt32(index++, transLowGUID);
stmt->setUInt32(index++, transSpawnId);
std::ostringstream ss;
ss << m_taxi;
@@ -19750,14 +19660,9 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false
stmt->setFloat(index++, finiteAlways(GetTransOffsetZ()));
stmt->setFloat(index++, finiteAlways(GetTransOffsetO()));
ObjectGuid::LowType transLowGUID = 0;
uint32 transSpawnId = 0;
if (Transport* transport = GetTransport())
{
transLowGUID = transport->GetGUID().GetCounter();
transSpawnId = transport->GetSpawnId();
}
if (GetTransport())
transLowGUID = GetTransport()->GetGUID().GetCounter();
stmt->setUInt32(index++, transLowGUID);
stmt->setUInt32(index++, transSpawnId);
std::ostringstream ss;
ss << m_taxi;
@@ -23123,6 +23028,17 @@ inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target, std::set
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target, std::set<Unit*>& /*v*/)
{
// @HACK: This is to prevent objects like deeprun tram from disappearing when player moves far from its spawn point while riding it
// But exclude stoppable elevators from this hack - they would be teleporting from one end to another
// if affected transports move so far horizontally that it causes them to run out of visibility range then you are out of luck
// fix visibility instead of adding hacks here
if (!target->IsDynTransport())
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target, std::set<Unit*>& v)
{
@@ -27935,17 +27851,6 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
SetMinion(pet, true);
Transport* transport = GetTransGUID().IsEmpty() ? GetTransport() : nullptr;
if (transport)
{
float x, y, z, o;
pet->GetPosition(x, y, z, o);
transport->CalculatePassengerOffset(x, y, z, &o);
pet->m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(pet);
}
switch (petType)
{
case SUMMON_PET:
+2 -10
View File
@@ -1019,8 +1019,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetObjectScale(float scale) override;
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Transport* transport = nullptr);
bool TeleportTo(WorldLocation const& loc, uint32 options = 0, Transport* transport = nullptr);
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
bool TeleportTo(WorldLocation const& loc, uint32 options = 0);
bool TeleportToBGEntryPoint();
bool HasSummonPending() const;
@@ -1924,8 +1924,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetSkillPermBonus(uint8 pos, uint16 value);
WorldLocation& GetTeleportDest() { return m_teleport_dest; }
Transport* GetTeleportTransport() const { return m_teleport_transport; }
void ResetTeleportTransport() { m_teleport_transport = nullptr; }
bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; }
bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; }
bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; }
@@ -2390,9 +2388,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void DeleteFromPlayerPetDataStore(uint32 petNumber);
void AddToPlayerPetDataStore(PlayerPetData* playerPetData);
uint32 GetTransportSpawnID() const { return _transportSpawnID; }
void SetTransportSpawnID(uint32 spawnId) { _transportSpawnID = spawnId; }
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
@@ -2728,7 +2723,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
// Current teleport data
WorldLocation m_teleport_dest;
uint32 m_teleport_options;
Transport* m_teleport_transport;
bool mSemaphoreTeleport_Near;
bool mSemaphoreTeleport_Far;
@@ -2766,8 +2760,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
TimeTrackerSmall m_petScalingSynchTimer;
TimeTrackerSmall m_groupUpdateTimer;
uint32 _transportSpawnID;
};
TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
+142 -527
View File
@@ -30,526 +30,48 @@
#include "Totem.h"
#include "UpdateData.h"
#include "Vehicle.h"
#include "ZoneScript.h"
Transport::Transport() : GameObject(),
_passengerTeleportItr(_passengers.begin()), _destinationStopFrameTime(0), _currentTransportTime(0),
_lastStopFrameTime(0), _finalStopFrameTime(0), _isDynamicTransport(false), _initialRelocate(false)
_transportInfo(nullptr), _isMoving(true), _pendingStop(false),
_triggeredArrivalEvent(false), _triggeredDepartureEvent(false),
_passengerTeleportItr(_passengers.begin()), _delayedAddModel(false), _delayedTeleport(false)
{
m_updateFlag |= UPDATEFLAG_TRANSPORT | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION;
m_updateFlag = UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION;
}
Transport::~Transport()
{
ASSERT(_passengers.empty());
if (m_goInfo && m_goInfo->type == GAMEOBJECT_TYPE_TRANSPORT)
delete m_goValue.Transport.StopFrames;
UnloadStaticPassengers();
}
void Transport::CleanupsBeforeDelete(bool finalCleanup /*= true*/)
bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress)
{
while (!_passengers.empty())
{
WorldObject* obj = *_passengers.begin();
RemovePassenger(obj);
}
GameObject::CleanupsBeforeDelete(finalCleanup);
}
void Transport::AddPassenger(WorldObject* passenger)
{
if (!IsInWorld())
return;
if (_passengers.insert(passenger).second)
{
passenger->SetTransport(this);
passenger->m_movementInfo.transport.guid = GetGUID();
passenger->m_movementInfo.transport.time = GetTimer();
if (passenger->GetTypeId() == TYPEID_UNIT)
{
float x, y, z, o;
passenger->GetPosition(x, y, z, o);
TransportBase::CalculatePassengerOffset(x, y, z, &o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
passenger->m_movementInfo.transport.pos.Relocate(x, y, z, o);
if (IsInWorld() && passenger->IsInWorld())
UpdatePositionForPassenger(passenger);
}
TC_LOG_DEBUG("entities.transport", "Object %s boarded transport %s.", passenger->GetName().c_str(), GetName().c_str());
if (Unit* unit = passenger->ToUnit())
{
if (Guardian* guardian = unit->GetGuardianPet())
{
if (!guardian->IsPet() || guardian->GetCharmInfo()->GetCommandState() == COMMAND_FOLLOW)
{
if (Transport* oldTransport = guardian->GetTransport())
oldTransport->RemovePassenger(guardian);
AddPassenger(guardian);
/// @HACK - transport models are not added to map's dynamic LoS calculations
/// because the current GameObjectModel cannot be moved without recreating
guardian->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);
}
}
}
if (Player* plr = passenger->ToPlayer())
{
sScriptMgr->OnAddPassenger(this, plr);
if (GetGoType() == GAMEOBJECT_TYPE_TRANSPORT)
plr->SetTransportSpawnID(GetSpawnId());
}
}
}
void Transport::RemovePassenger(WorldObject* passenger)
{
bool erased = false;
if (_passengerTeleportItr != _passengers.end())
{
PassengerSet::iterator itr = _passengers.find(passenger);
if (itr != _passengers.end())
{
if (itr == _passengerTeleportItr)
++_passengerTeleportItr;
_passengers.erase(itr);
erased = true;
}
}
else
erased = _passengers.erase(passenger) > 0;
if (erased)
{
passenger->SetTransport(nullptr);
passenger->m_movementInfo.transport.Reset();
TC_LOG_DEBUG("entities.transport", "Object %s removed from transport %s.", passenger->GetName().c_str(), GetName().c_str());
if (Unit* unit = passenger->ToUnit())
{
if (Guardian* guardian = unit->GetGuardianPet())
if (!guardian->IsPet() || guardian->GetCharmInfo()->GetCommandState() == COMMAND_FOLLOW)
{
if (guardian->GetTransGUID() == GetGUID())
{
RemovePassenger(guardian);
/// @HACK - transport models are not added to map's dynamic LoS calculations
/// because the current GameObjectModel cannot be moved without recreating
guardian->ClearUnitState(UNIT_STATE_IGNORE_PATHFINDING);
}
}
}
if (Player* plr = passenger->ToPlayer())
{
sScriptMgr->OnRemovePassenger(this, plr);
plr->SetTransportSpawnID(0);
}
}
}
bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState /*go_state*/, uint32 artKit /*= 0*/, bool dynamic, ObjectGuid::LowType spawnid)
{
ASSERT(map);
SetMap(map);
UpdatePositionData();
SetZoneScript();
if (GetZoneScript())
{
entry = GetZoneScript()->GetGameObjectEntry(m_spawnId, entry);
if (!entry)
return false;
}
// Set if this object can handle dynamic spawns
if (!dynamic)
SetRespawnCompatibilityMode();
if (!Transport::CreateTransport(guidlow, entry, map->GetId(), pos, animprogress))
return false;
if (m_goInfo->type != GAMEOBJECT_TYPE_TRANSPORT)
{
TC_LOG_ERROR("entities.transport", "Transport (Spawn id: %u Entry: %u) not created.", GetSpawnId(), entry);
return false;
}
m_stationaryPosition.Relocate(pos);
GameObjectAddon const* gameObjectAddon = sObjectMgr->GetGameObjectAddon(GetSpawnId());
SetLocalRotation(rotation.x, rotation.y, rotation.z, rotation.w);
// For most of gameobjects is (0, 0, 0, 1) quaternion, there are only some transports with not standard rotation
QuaternionData parentRotation;
if (gameObjectAddon)
parentRotation = gameObjectAddon->ParentRotation;
SetParentRotation(parentRotation);
SetGoArtKit(artKit);
m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(entry);
m_goValue.Transport.StopFrames = new std::vector<uint32>();
if (m_goInfo->transport.Timeto2ndfloor > 0)
m_goValue.Transport.StopFrames->push_back(m_goInfo->transport.Timeto2ndfloor);
if (m_goInfo->transport.Timeto3rdfloor > 0)
m_goValue.Transport.StopFrames->push_back(m_goInfo->transport.Timeto3rdfloor);
if (m_goInfo->transport.Timeto4thfloor > 0)
m_goValue.Transport.StopFrames->push_back(m_goInfo->transport.Timeto4thfloor);
if (m_goInfo->transport.Timeto5thfloor > 0)
m_goValue.Transport.StopFrames->push_back(m_goInfo->transport.Timeto5thfloor);
// Picking the final stop frame from transport animation store for return server side movement
uint32 finalStopFrameTime = 0;
for (TransportAnimationEntry const* animation : sTransportAnimationStore)
{
if (animation->TransportID != entry)
continue;
if (animation->TimeIndex > finalStopFrameTime)
finalStopFrameTime = animation->TimeIndex;
}
_finalStopFrameTime = finalStopFrameTime;
_isDynamicTransport = m_goValue.Transport.StopFrames->empty();
uint32 stopTimer = 0;
if (m_goInfo->transport.startOpen)
{
SetGoState(GO_STATE_TRANSPORT_STOPPED);
stopTimer = m_goValue.Transport.StopFrames->at(0);
_currentTransportTime = stopTimer;
_initialRelocate = true;
}
else
SetGoState(GO_STATE_TRANSPORT_ACTIVE);
if (_isDynamicTransport)
{
m_goValue.Transport.PathProgress = getMSTime();
if (m_goValue.Transport.AnimationInfo)
{
SetPeriod(m_goValue.Transport.AnimationInfo->TotalTime);
m_goValue.Transport.PathProgress -= m_goValue.Transport.PathProgress % GetTransportPeriod(); // align to period
}
}
else
{
SetPeriod(getMSTime() + stopTimer);
m_goValue.Transport.PathProgress = getMSTime() + stopTimer;
}
SetDestinationStopFrameTime(stopTimer);
SetCurrentTransportTime(stopTimer);
if (gameObjectAddon && gameObjectAddon->InvisibilityValue)
{
m_invisibility.AddFlag(gameObjectAddon->invisibilityType);
m_invisibility.AddValue(gameObjectAddon->invisibilityType, gameObjectAddon->InvisibilityValue);
}
LastUsedScriptID = GetGOInfo()->ScriptId;
AIM_Initialize();
if (spawnid)
m_spawnId = spawnid;
return true;
}
bool Transport::CreateTransport(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, Position const& pos, uint32 animprogress)
{
Relocate(pos);
Relocate(x, y, z, ang);
if (!IsPositionValid())
{
TC_LOG_ERROR("entities.transport", "Transport (GUID: %u) not created. Suggested coordinates isn't valid %s",
guidlow, pos.ToString().c_str());
TC_LOG_ERROR("entities.transport", "Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
guidlow, x, y);
return false;
}
Object::_Create(guidlow, 0, HighGuid::Transport);
Object::_Create(guidlow, 0, HighGuid::Mo_Transport);
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry);
if (!goinfo)
{
TC_LOG_ERROR("sql.sql", "Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
TC_LOG_ERROR("sql.sql", "Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang);
return false;
}
m_goInfo = goinfo;
m_goTemplateAddon = sObjectMgr->GetGameObjectTemplateAddon(entry);
if (m_goTemplateAddon)
{
SetFaction(m_goTemplateAddon->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags);
}
SetObjectScale(goinfo->size);
SetEntry(goinfo->entry);
SetDisplayId(goinfo->displayId);
SetGoType(GameobjectTypes(goinfo->type));
SetGoAnimProgress(animprogress);
SetName(goinfo->name);
m_model = CreateModel();
return true;
}
void Transport::Update(uint32 diff)
{
GameObject::Update(diff);
if (!IsInWorld())
return;
if (!m_goValue.Transport.AnimationInfo)
return;
if (_initialRelocate)
{
RelocateToProgress(GetCurrentTransportTime());
_initialRelocate = false;
}
if (IsDynamicTransport())
{
m_goValue.Transport.PathProgress += diff;
SetCurrentTransportTime(GetCurrentTransportTime() + diff);
if (GetCurrentTransportTime() >= GetTransportPeriod())
SetCurrentTransportTime(GetCurrentTransportTime() % GetTransportPeriod());
}
else
{
// Waiting at our last destination. Do nothing.
if (GetCurrentTransportTime() == GetDestinationStopFrameTime())
return;
uint32 lastStopFrameTime = GetLastStopFrameTime();
uint32 currentTransportTime = GetCurrentTransportTime();
uint32 destinationStopFrameTime = GetDestinationStopFrameTime();
switch (GetGoState())
{
case GO_STATE_ACTIVE:
case GO_STATE_READY:
case GO_STATE_ACTIVE_ALTERNATIVE:
break;
default:
{
/*
These states handle the stop frame movement of transports
Transports with GO_STATE_TRANSPORT_ACTIVE move to stop frame 0 clientside while using a special travel path
Transports with GO_STATE_TRANSPORT_STOPPED + frame index move to the provided stop frame using time diffs between
the last frame and the target frame to reach their destination
*/
bool backwardsMovement = destinationStopFrameTime < lastStopFrameTime;
uint32 transportTime = backwardsMovement ?
std::max<int32>(destinationStopFrameTime, currentTransportTime - diff) :
std::min<int32>(destinationStopFrameTime, currentTransportTime + diff);
SetCurrentTransportTime(transportTime);
break;
}
}
}
RelocateToProgress(GetCurrentTransportTime());
}
void Transport::RelocateToProgress(uint32 progress)
{
TransportAnimationEntry const* curr = nullptr;
TransportAnimationEntry const* next = nullptr;
float percPos = 0.0f;
if (m_goValue.Transport.AnimationInfo->GetAnimNode(progress, curr, next, percPos))
{
// curr node offset
G3D::Vector3 pos = G3D::Vector3(curr->Pos.X, curr->Pos.Y, curr->Pos.Z);
// move by percentage of segment already passed
pos += G3D::Vector3(percPos * (next->Pos.X - curr->Pos.X), percPos * (next->Pos.Y - curr->Pos.Y), percPos * (next->Pos.Z - curr->Pos.Z));
// rotate path by PathRotation
// PathRotation in db is only simple orientation rotation, so don't use sophisticated and not working code
// reminder: WorldRotation only influences model rotation, not the path
float sign = GetFloatValue(GAMEOBJECT_PARENTROTATION + 2) >= 0.0f ? 1.0f : -1.0f;
float pathRotAngle = sign * 2.0f * acos(GetFloatValue(GAMEOBJECT_PARENTROTATION + 3));
float cs = cos(pathRotAngle), sn = sin(pathRotAngle);
float nx = pos.x * cs - pos.y * sn;
float ny = pos.x * sn + pos.y * cs;
pos.x = nx;
pos.y = ny;
// add stationary position to the calculated offset
pos += G3D::Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
// rotate by AnimRotation at current segment
// AnimRotation in dbc is only simple orientation rotation, so don't use sophisticated and not working code
QuaternionData currRot = QuaternionData();
QuaternionData nextRot = QuaternionData();
float percRot = 0.0f;
m_goValue.Transport.AnimationInfo->GetAnimRotation(progress, currRot, nextRot, percRot);
float signCurr = currRot.z >= 0.0f ? 1.0f : -1.0f;
float oriRotAngleCurr = signCurr * 2.0f * acos(currRot.w);
float signNext = nextRot.z >= 0.0f ? 1.0f : -1.0f;
float oriRotAngleNext = signNext * 2.0f * acos(nextRot.w);
float oriRotAngle = oriRotAngleCurr + percRot * (oriRotAngleNext - oriRotAngleCurr);
// check if position is valid
if (!Trinity::IsValidMapCoord(pos.x, pos.y, pos.z))
return;
GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, NormalizeOrientation(GetStationaryO() + oriRotAngle));
UpdatePassengerPositions(_passengers);
}
}
void Transport::UpdatePassengerPositions(PassengerSet& passengers)
{
for (PassengerSet::iterator itr = passengers.begin(); itr != passengers.end(); ++itr)
UpdatePositionForPassenger(*itr);
}
void Transport::UpdatePositionForPassenger(WorldObject* passenger)
{
// transport teleported but passenger not yet (can happen for players)
if (passenger->GetMap() != GetMap())
return;
// if passenger is on vehicle we have to assume the vehicle is also on transport
// and its the vehicle that will be updating its passengers
if (Unit* unit = passenger->ToUnit())
{
if (unit->GetVehicle())
return;
// if spline enabled, position will be updated in Unit::UpdateSplinePosition
if (unit->IsSplineEnabled())
return;
}
// Do not use Unit::UpdatePosition here, we don't want to remove auras
// as if regular movement occurred
float x, y, z, o;
passenger->m_movementInfo.transport.pos.GetPosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
switch (passenger->GetTypeId())
{
case TYPEID_UNIT:
{
Creature* creature = passenger->ToCreature();
GetMap()->CreatureRelocation(creature, x, y, z, o, false);
creature->GetTransportHomePosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
creature->SetHomePosition(x, y, z, o);
break;
}
case TYPEID_PLAYER:
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
break;
case TYPEID_GAMEOBJECT:
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
passenger->ToGameObject()->RelocateStationaryPosition(x, y, z, o);
break;
case TYPEID_DYNAMICOBJECT:
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
break;
default:
break;
}
if (Unit* unit = passenger->ToUnit())
if (Vehicle* vehicle = unit->GetVehicleKit())
vehicle->RelocatePassengers(); // transport teleported but passenger not yet (can happen for players)
}
void Transport::SetTransportState(GOState state, uint32 stopFrame /*= 0*/)
{
// Do not change the transport state before reaching the last selected destination
if (GetCurrentTransportTime() != GetDestinationStopFrameTime())
return;
ASSERT(m_goInfo->type == GAMEOBJECT_TYPE_TRANSPORT);
uint32 stopTimer = 0;
uint32 currentStopFrameTime = GetCurrentTransportTime();
if (GetGoState() == GO_STATE_TRANSPORT_ACTIVE)
{
currentStopFrameTime = 0;
SetCurrentTransportTime(currentStopFrameTime);
}
if (state == GO_STATE_TRANSPORT_ACTIVE)
{
if (currentStopFrameTime)
{
// Returning to stop frame 0. Client expects travel time, server expects animation timestamp for special return movement
uint32 transportTravelTime = _finalStopFrameTime - currentStopFrameTime;
SetPeriod(getMSTime() + transportTravelTime);
SetDestinationStopFrameTime(_finalStopFrameTime);
}
}
else
{
ASSERT(state < GOState(GO_STATE_TRANSPORT_STOPPED + MAX_GO_STATE_TRANSPORT_STOP_FRAMES));
ASSERT(stopFrame <= m_goValue.Transport.StopFrames->size());
// Moving between given stop frames
stopTimer = stopFrame ? m_goValue.Transport.StopFrames->at(stopFrame - 1) : 0;
bool backwards = stopTimer < currentStopFrameTime;
uint32 transportTravelTime = backwards ? currentStopFrameTime - stopTimer : stopTimer - currentStopFrameTime;
SetPeriod(getMSTime() + transportTravelTime);
SetDestinationStopFrameTime(stopTimer);
state = GOState(GO_STATE_TRANSPORT_ACTIVE + stopFrame);
}
m_goValue.Transport.PathProgress = getMSTime() + stopTimer;
SetLastStopFrameTime(currentStopFrameTime);
SetGoState(state);
}
MapTransport::MapTransport() : Transport(),
_transportInfo(nullptr), _isMoving(true), _pendingStop(false),
_triggeredArrivalEvent(false), _triggeredDepartureEvent(false),
_delayedAddModel(false), _delayedTeleport(false)
{
}
MapTransport::~MapTransport()
{
UnloadStaticPassengers();
}
bool MapTransport::CreateMapTransport(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress)
{
if (!Transport::CreateTransport(guidlow, entry, mapid, Position(x, y, z, ang), animprogress))
return false;
TransportTemplate const* tInfo = sTransportMgr->GetTransportTemplate(entry);
if (!tInfo)
{
TC_LOG_ERROR("sql.sql", "Transport %u (name: %s) will not be created, missing `transport_template` entry.", entry, m_goInfo->name.c_str());
TC_LOG_ERROR("sql.sql", "Transport %u (name: %s) will not be created, missing `transport_template` entry.", entry, goinfo->name.c_str());
return false;
}
@@ -561,9 +83,21 @@ bool MapTransport::CreateMapTransport(ObjectGuid::LowType guidlow, uint32 entry,
_triggeredArrivalEvent = false;
_triggeredDepartureEvent = false;
if (m_goTemplateAddon)
{
SetFaction(m_goTemplateAddon->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags);
}
m_goValue.Transport.PathProgress = 0;
SetObjectScale(goinfo->size);
SetPeriod(tInfo->pathTime);
SetGoState(!m_goInfo->moTransport.canBeStopped ? GO_STATE_READY : GO_STATE_ACTIVE);
SetEntry(goinfo->entry);
SetDisplayId(goinfo->displayId);
SetGoState(!goinfo->moTransport.canBeStopped ? GO_STATE_READY : GO_STATE_ACTIVE);
SetGoType(GAMEOBJECT_TYPE_MO_TRANSPORT);
SetGoAnimProgress(animprogress);
SetName(goinfo->name);
SetLocalRotation(0.0f, 0.0f, 0.0f, 1.0f);
SetParentRotation(QuaternionData());
@@ -571,14 +105,19 @@ bool MapTransport::CreateMapTransport(ObjectGuid::LowType guidlow, uint32 entry,
return true;
}
void MapTransport::CleanupsBeforeDelete(bool finalCleanup /*= true*/)
void Transport::CleanupsBeforeDelete(bool finalCleanup /*= true*/)
{
UnloadStaticPassengers();
while (!_passengers.empty())
{
WorldObject* obj = *_passengers.begin();
RemovePassenger(obj);
}
Transport::CleanupsBeforeDelete(finalCleanup);
GameObject::CleanupsBeforeDelete(finalCleanup);
}
void MapTransport::Update(uint32 diff)
void Transport::Update(uint32 diff)
{
uint32 const positionUpdateDelay = 200;
@@ -698,7 +237,7 @@ void MapTransport::Update(uint32 diff)
sScriptMgr->OnTransportUpdate(this, diff);
}
void MapTransport::DelayedUpdate(uint32 /*diff*/)
void Transport::DelayedUpdate(uint32 /*diff*/)
{
if (GetKeyFrames().size() <= 1)
return;
@@ -706,7 +245,23 @@ void MapTransport::DelayedUpdate(uint32 /*diff*/)
DelayedTeleportTransport();
}
void MapTransport::RemovePassenger(WorldObject* passenger)
void Transport::AddPassenger(WorldObject* passenger)
{
if (!IsInWorld())
return;
if (_passengers.insert(passenger).second)
{
passenger->SetTransport(this);
passenger->m_movementInfo.transport.guid = GetGUID();
TC_LOG_DEBUG("entities.transport", "Object %s boarded transport %s.", passenger->GetName().c_str(), GetName().c_str());
if (Player* plr = passenger->ToPlayer())
sScriptMgr->OnAddPassenger(this, plr);
}
}
void Transport::RemovePassenger(WorldObject* passenger)
{
bool erased = false;
if (_passengerTeleportItr != _passengers.end())
@@ -730,12 +285,6 @@ void MapTransport::RemovePassenger(WorldObject* passenger)
passenger->m_movementInfo.transport.Reset();
TC_LOG_DEBUG("entities.transport", "Object %s removed from transport %s.", passenger->GetName().c_str(), GetName().c_str());
if (Unit* unit = passenger->ToUnit())
if (Guardian* guardian = unit->GetGuardianPet())
if (!guardian->IsPet() || guardian->GetCharmInfo()->GetCommandState() == COMMAND_FOLLOW)
if (guardian->GetTransGUID() == GetGUID())
RemovePassenger(guardian);
if (Player* plr = passenger->ToPlayer())
{
sScriptMgr->OnRemovePassenger(this, plr);
@@ -744,7 +293,7 @@ void MapTransport::RemovePassenger(WorldObject* passenger)
}
}
Creature* MapTransport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data)
Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data)
{
Map* map = GetMap();
if (map->GetCreatureRespawnTime(guid))
@@ -763,7 +312,6 @@ Creature* MapTransport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureDat
creature->SetTransport(this);
creature->m_movementInfo.transport.guid = GetGUID();
creature->m_movementInfo.transport.time = GetTimer();
creature->m_movementInfo.transport.pos.Relocate(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
creature->Relocate(x, y, z, o);
@@ -795,19 +343,13 @@ Creature* MapTransport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureDat
return creature;
}
GameObject* MapTransport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data)
GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data)
{
ASSERT(data);
Map* map = GetMap();
if (map->GetGORespawnTime(guid))
return nullptr;
GameObject* go = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(data->id) == GAMEOBJECT_TYPE_TRANSPORT)
go = new Transport();
else
go = new GameObject();
GameObject* go = new GameObject();
if (!go->LoadFromDB(guid, map, false))
{
@@ -822,7 +364,6 @@ GameObject* MapTransport::CreateGOPassenger(ObjectGuid::LowType guid, GameObject
go->SetTransport(this);
go->m_movementInfo.transport.guid = GetGUID();
go->m_movementInfo.transport.time = GetTimer();
go->m_movementInfo.transport.pos.Relocate(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
go->Relocate(x, y, z, o);
@@ -848,7 +389,7 @@ GameObject* MapTransport::CreateGOPassenger(ObjectGuid::LowType guid, GameObject
return go;
}
TempSummon* MapTransport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
{
Map* map = FindMap();
if (!map)
@@ -937,7 +478,6 @@ TempSummon* MapTransport::SummonPassenger(uint32 entry, Position const& pos, Tem
summon->SetTransport(this);
summon->m_movementInfo.transport.guid = GetGUID();
summon->m_movementInfo.transport.pos.Relocate(pos);
summon->m_movementInfo.transport.time = GetTimer();
summon->Relocate(x, y, z, o);
summon->SetHomePosition(x, y, z, o);
summon->SetTransportHomePosition(pos);
@@ -962,7 +502,7 @@ TempSummon* MapTransport::SummonPassenger(uint32 entry, Position const& pos, Tem
return summon;
}
void MapTransport::UpdatePosition(float x, float y, float z, float o)
void Transport::UpdatePosition(float x, float y, float z, float o)
{
bool newActive = GetMap()->IsGridLoaded(x, y);
Cell oldCell(GetPositionX(), GetPositionY());
@@ -988,7 +528,7 @@ void MapTransport::UpdatePosition(float x, float y, float z, float o)
// 4. is handed by grid unload
}
void MapTransport::LoadStaticPassengers()
void Transport::LoadStaticPassengers()
{
if (uint32 mapId = GetGOInfo()->moTransport.mapID)
{
@@ -1009,7 +549,7 @@ void MapTransport::LoadStaticPassengers()
}
}
void MapTransport::UnloadStaticPassengers()
void Transport::UnloadStaticPassengers()
{
while (!_staticPassengers.empty())
{
@@ -1018,7 +558,7 @@ void MapTransport::UnloadStaticPassengers()
}
}
void MapTransport::EnableMovement(bool enabled)
void Transport::EnableMovement(bool enabled)
{
if (!GetGOInfo()->moTransport.canBeStopped)
return;
@@ -1026,7 +566,7 @@ void MapTransport::EnableMovement(bool enabled)
_pendingStop = !enabled;
}
void MapTransport::MoveToNextWaypoint()
void Transport::MoveToNextWaypoint()
{
// Clear events flagging
_triggeredArrivalEvent = false;
@@ -1038,7 +578,7 @@ void MapTransport::MoveToNextWaypoint()
_nextFrame = GetKeyFrames().begin();
}
float MapTransport::CalculateSegmentPos(float now)
float Transport::CalculateSegmentPos(float now)
{
KeyFrame const& frame = *_currentFrame;
const float speed = float(m_goInfo->moTransport.moveSpeed);
@@ -1069,7 +609,7 @@ float MapTransport::CalculateSegmentPos(float now)
return segmentPos / frame.NextDistFromPrev;
}
bool MapTransport::TeleportTransport(uint32 newMapid, float x, float y, float z, float o)
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, float o)
{
Map const* oldMap = GetMap();
@@ -1082,18 +622,37 @@ bool MapTransport::TeleportTransport(uint32 newMapid, float x, float y, float z,
else
{
UpdatePosition(x, y, z, o);
// Teleport players, they need to know it
for (PassengerSet::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr)
{
if ((*itr)->GetTypeId() == TYPEID_PLAYER)
{
// will be relocated in UpdatePosition of the vehicle
if (Unit* veh = (*itr)->ToUnit()->GetVehicleBase())
if (veh->GetTransport() == this)
continue;
float destX, destY, destZ, destO;
(*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, o);
(*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO);
}
}
return false;
}
}
void MapTransport::DelayedTeleportTransport()
void Transport::DelayedTeleportTransport()
{
if (!_delayedTeleport)
return;
_delayedTeleport = false;
Map* newMap = sMapMgr->CreateBaseMap(_nextFrame->Node->ContinentID);
GetMap()->RemoveFromMap<MapTransport>(this, false);
GetMap()->RemoveFromMap<Transport>(this, false);
SetMap(newMap);
float x = _nextFrame->Node->Loc.X,
@@ -1125,10 +684,66 @@ void MapTransport::DelayedTeleportTransport()
}
Relocate(x, y, z, o);
GetMap()->AddToMap<MapTransport>(this);
GetMap()->AddToMap<Transport>(this);
}
void MapTransport::DoEventIfAny(KeyFrame const& node, bool departure)
void Transport::UpdatePassengerPositions(PassengerSet& passengers)
{
for (PassengerSet::iterator itr = passengers.begin(); itr != passengers.end(); ++itr)
{
WorldObject* passenger = *itr;
// transport teleported but passenger not yet (can happen for players)
if (passenger->GetMap() != GetMap())
continue;
// if passenger is on vehicle we have to assume the vehicle is also on transport
// and its the vehicle that will be updating its passengers
if (Unit* unit = passenger->ToUnit())
if (unit->GetVehicle())
continue;
// Do not use Unit::UpdatePosition here, we don't want to remove auras
// as if regular movement occurred
float x, y, z, o;
passenger->m_movementInfo.transport.pos.GetPosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
switch (passenger->GetTypeId())
{
case TYPEID_UNIT:
{
Creature* creature = passenger->ToCreature();
GetMap()->CreatureRelocation(creature, x, y, z, o, false);
creature->GetTransportHomePosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
creature->SetHomePosition(x, y, z, o);
break;
}
case TYPEID_PLAYER:
//relocate only passengers in world and skip any player that might be still logging in/teleporting
if (passenger->IsInWorld() && !passenger->ToPlayer()->IsBeingTeleported())
{
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
passenger->ToPlayer()->SetFallInformation(0, passenger->GetPositionZ());
}
break;
case TYPEID_GAMEOBJECT:
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
passenger->ToGameObject()->RelocateStationaryPosition(x, y, z, o);
break;
case TYPEID_DYNAMICOBJECT:
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
break;
default:
break;
}
if (Unit* unit = passenger->ToUnit())
if (Vehicle* vehicle = unit->GetVehicleKit())
vehicle->RelocatePassengers();
}
}
void Transport::DoEventIfAny(KeyFrame const& node, bool departure)
{
if (uint32 eventid = departure ? node.Node->DepartureEventID : node.Node->ArrivalEventID)
{
@@ -1138,7 +753,7 @@ void MapTransport::DoEventIfAny(KeyFrame const& node, bool departure)
}
}
void MapTransport::BuildUpdate(UpdateDataMapType& data_map)
void Transport::BuildUpdate(UpdateDataMapType& data_map)
{
Map::PlayerList const& players = GetMap()->GetPlayers();
if (players.isEmpty())
+29 -70
View File
@@ -1,5 +1,6 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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
@@ -26,78 +27,15 @@ struct CreatureData;
class TC_GAME_API Transport : public GameObject, public TransportBase
{
friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint8, uint32, uint32);
Transport();
public:
typedef std::set<WorldObject*> PassengerSet;
Transport();
~Transport();
bool Create(ObjectGuid::LowType guidlow, uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0, bool dynamic = false, ObjectGuid::LowType spawnid = 0) override;
bool CreateTransport(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, Position const& pos, uint32 animprogress);
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void AddPassenger(WorldObject* passenger);
virtual void RemovePassenger(WorldObject* passenger);
PassengerSet const& GetPassengers() const { return _passengers; }
/// This method transforms supplied transport offsets into global coordinates
void CalculatePassengerPosition(float& x, float& y, float& z, float* o = nullptr) const override
{
TransportBase::CalculatePassengerPosition(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
}
/// This method transforms supplied global coordinates into local offsets
void CalculatePassengerOffset(float& x, float& y, float& z, float* o = nullptr) const override
{
TransportBase::CalculatePassengerOffset(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
}
void Update(uint32 diff) override;
bool IsDynamicTransport() const { return _isDynamicTransport; }
uint32 GetTransportPeriod() const { return GetUInt32Value(GAMEOBJECT_LEVEL); }
void SetPeriod(uint32 period) { SetUInt32Value(GAMEOBJECT_LEVEL, period); }
uint32 GetTimer() const { return GetGOValue()->Transport.PathProgress; }
void SetTransportState(GOState state, uint32 stopFrame = 0);
void RelocateToProgress(uint32 progress);
void SetDestinationStopFrameTime(uint32 time) { _destinationStopFrameTime = time; }
uint32 GetDestinationStopFrameTime() const { return _destinationStopFrameTime; }
void SetCurrentTransportTime(uint32 time) { _currentTransportTime = time; }
uint32 GetCurrentTransportTime() const { return _currentTransportTime; }
void SetLastStopFrameTime(uint32 time) { _lastStopFrameTime = time; }
uint32 GetLastStopFrameTime() const { return _lastStopFrameTime; }
protected:
void UpdatePassengerPositions(PassengerSet& passengers);
void UpdatePositionForPassenger(WorldObject* passenger);
PassengerSet _passengers;
PassengerSet::iterator _passengerTeleportItr;
uint32 _destinationStopFrameTime;
uint32 _currentTransportTime;
uint32 _lastStopFrameTime;
uint32 _finalStopFrameTime;
bool _isDynamicTransport;
bool _initialRelocate;
};
class TC_GAME_API MapTransport : public Transport
{
friend MapTransport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint8, uint32, uint32);
MapTransport();
public:
~MapTransport();
bool CreateMapTransport(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress);
bool Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress);
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void Update(uint32 diff) override;
@@ -105,13 +43,15 @@ class TC_GAME_API MapTransport : public Transport
void BuildUpdate(UpdateDataMapType& data_map) override;
void RemovePassenger(WorldObject* passenger) override;
void AddPassenger(WorldObject* passenger);
void RemovePassenger(WorldObject* passenger);
PassengerSet const& GetPassengers() const { return _passengers; }
Creature* CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data);
GameObject* CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data);
/**
* @fn bool Transport::SummonPassenger(uint32, Position const&, TempSummonType, SummonPropertiesEntry const*, uint32, Unit*, uint32, uint32)
* @fn bool Transport::SummonPassenger(uint64, Position const&, TempSummonType, SummonPropertiesEntry const*, uint32, Unit*, uint32, uint32)
*
* @brief Temporarily summons a creature as passenger on this transport.
*
@@ -128,6 +68,22 @@ class TC_GAME_API MapTransport : public Transport
*/
TempSummon* SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0);
/// This method transforms supplied transport offsets into global coordinates
void CalculatePassengerPosition(float& x, float& y, float& z, float* o = nullptr) const override
{
TransportBase::CalculatePassengerPosition(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
}
/// This method transforms supplied global coordinates into local offsets
void CalculatePassengerOffset(float& x, float& y, float& z, float* o = nullptr) const override
{
TransportBase::CalculatePassengerOffset(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
}
uint32 GetTransportPeriod() const override { return GetUInt32Value(GAMEOBJECT_LEVEL); }
void SetPeriod(uint32 period) { SetUInt32Value(GAMEOBJECT_LEVEL, period); }
uint32 GetTimer() const { return GetGOValue()->Transport.PathProgress; }
KeyFrameVec const& GetKeyFrames() const { return _transportInfo->keyFrames; }
void UpdatePosition(float x, float y, float z, float o);
@@ -149,6 +105,7 @@ class TC_GAME_API MapTransport : public Transport
float CalculateSegmentPos(float perc);
bool TeleportTransport(uint32 newMapid, float x, float y, float z, float o);
void DelayedTeleportTransport();
void UpdatePassengerPositions(PassengerSet& passengers);
void DoEventIfAny(KeyFrame const& node, bool departure);
//! Helpers to know if stop frame was reached
@@ -167,6 +124,8 @@ class TC_GAME_API MapTransport : public Transport
bool _triggeredArrivalEvent;
bool _triggeredDepartureEvent;
PassengerSet _passengers;
PassengerSet::iterator _passengerTeleportItr;
PassengerSet _staticPassengers;
bool _delayedAddModel;
@@ -157,6 +157,7 @@ public:
/// This method transforms supplied global coordinates into local offsets
virtual void CalculatePassengerOffset(float& x, float& y, float& z, float* o = nullptr) const = 0;
protected:
static void CalculatePassengerPosition(float& x, float& y, float& z, float* o, float transX, float transY, float transZ, float transO)
{
float inx = x, iny = y, inz = z;
+1 -6
View File
@@ -28,7 +28,6 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "PoolMgr.h"
#include "Transport.h"
#include "UnitAI.h"
#include "World.h"
#include "WorldPacket.h"
@@ -1302,11 +1301,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
// We use current coords to unspawn, not spawn coords since creature can have changed grid
if (!map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
{
GameObject* pGameobject = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(data->id) == GAMEOBJECT_TYPE_TRANSPORT)
pGameobject = new Transport();
else
pGameobject = new GameObject();
GameObject* pGameobject = new GameObject;
//TC_LOG_DEBUG("misc", "Spawning gameobject %u", *itr);
/// @todo find out when it is add to map
if (!pGameobject->LoadFromDB(*itr, map, false))
+6 -14
View File
@@ -34,8 +34,8 @@ template<class T>
void HashMapHolder<T>::Insert(T* o)
{
static_assert(std::is_same<Player, T>::value
|| std::is_same<MapTransport, T>::value,
"Only Player and MapTransport can be registered in global HashMapHolder");
|| std::is_same<Transport, T>::value,
"Only Player and Transport can be registered in global HashMapHolder");
std::unique_lock<std::shared_mutex> lock(*GetLock());
@@ -79,7 +79,7 @@ HashMapHolder<Player>::MapType const& ObjectAccessor::GetPlayers()
}
template class TC_GAME_API HashMapHolder<Player>;
template class TC_GAME_API HashMapHolder<MapTransport>;
template class TC_GAME_API HashMapHolder<Transport>;
namespace PlayerNameMapHolder
{
@@ -113,6 +113,7 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid con
{
case HighGuid::Player: return GetPlayer(p, guid);
case HighGuid::Transport:
case HighGuid::Mo_Transport:
case HighGuid::GameObject: return GetGameObject(p, guid);
case HighGuid::Vehicle:
case HighGuid::Unit: return GetCreature(p, guid);
@@ -137,6 +138,7 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid con
return GetPlayer(p, guid);
break;
case HighGuid::Transport:
case HighGuid::Mo_Transport:
case HighGuid::GameObject:
if (typemask & TYPEMASK_GAMEOBJECT)
return GetGameObject(p, guid);
@@ -177,21 +179,11 @@ GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid const
return u.GetMap()->GetGameObject(guid);
}
Transport* ObjectAccessor::GetTransportOnMap(WorldObject const& u, ObjectGuid const& guid)
Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid const& guid)
{
return u.GetMap()->GetTransport(guid);
}
MapTransport* ObjectAccessor::GetMapTransportOnMap(WorldObject const& u, ObjectGuid const& guid)
{
return u.GetMap()->GetMapTransport(guid);
}
MapTransport* ObjectAccessor::GetMapTransport(ObjectGuid const& guid)
{
return HashMapHolder<MapTransport>::Find(guid);
}
DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid const& guid)
{
return u.GetMap()->GetDynamicObject(guid);
+1 -3
View File
@@ -63,9 +63,7 @@ namespace ObjectAccessor
TC_GAME_API Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask);
TC_GAME_API Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API Transport* GetTransportOnMap(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API MapTransport* GetMapTransportOnMap(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API MapTransport* GetMapTransport(ObjectGuid const& guid);
TC_GAME_API Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
+2 -15
View File
@@ -55,7 +55,6 @@
#include "SpellMgr.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
#include "Transport.h"
#include "UpdateMask.h"
#include "Util.h"
#include "Vehicle.h"
@@ -2279,11 +2278,7 @@ ObjectGuid::LowType ObjectMgr::AddGameObjectData(uint32 entry, uint32 mapId, Pos
// We use spawn coords to spawn
if (!map->Instanceable() && map->IsGridLoaded(data.spawnPoint))
{
GameObject* go = nullptr;
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
go = new Transport();
else
go = new GameObject();
GameObject* go = new GameObject;
if (!go->LoadFromDB(spawnId, map, true))
{
@@ -6909,7 +6904,7 @@ void ObjectMgr::SetHighestGuids()
result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
if (result)
GetGuidSequenceGenerator<HighGuid::Transport>().Set((*result)[0].GetUInt32() + 1);
GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].GetUInt32() + 1);
result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
if (result)
@@ -10212,14 +10207,6 @@ void ObjectMgr::LoadTaxiNodeLevelData()
TC_LOG_INFO("server.loading", ">> Loaded %u taxi node level definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
uint32 ObjectMgr::GetGameObjectTypeByEntry(uint32 entry) const
{
if (GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry))
return goinfo->type;
return MAX_GAMEOBJECT_TYPE;
}
void ObjectMgr::InitializeQueriesData(QueryDataGroup mask)
{
uint32 oldMSTime = getMSTime();
-2
View File
@@ -1603,8 +1603,6 @@ class TC_GAME_API ObjectMgr
bool IsTransportMap(uint32 mapId) const { return _transportMaps.count(mapId) != 0; }
uint32 GetGameObjectTypeByEntry(uint32 entry) const;
VehicleSeatAddon const* GetVehicleSeatAddon(uint32 seatId) const
{
VehicleSeatAddonContainer::const_iterator itr = _vehicleSeatAddonStore.find(seatId);
@@ -30,7 +30,7 @@ void VisibleNotifier::SendToSelf()
{
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
// but exist one case when this possible and object not out of range: transports
if (MapTransport* transport = i_player.GetMapTransport())
if (Transport* transport = i_player.GetTransport())
{
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
{
@@ -26,7 +26,6 @@
#include "GameObject.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Transport.h"
#include "World.h"
#include "ScriptMgr.h"
@@ -136,33 +135,6 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
}
}
template <>
void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefManager<GameObject>& m, uint32& count, Map* map)
{
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{
// Don't spawn at all if there's a respawn timer
ObjectGuid::LowType guid = *i_guid;
if (!map->ShouldBeSpawnedOnGridLoad<GameObject>(guid))
continue;
GameObject* obj = nullptr;
GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
if (data && sObjectMgr->GetGameObjectTypeByEntry(data->id) == GAMEOBJECT_TYPE_TRANSPORT)
obj = new Transport();
else
obj = new GameObject();
//TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
if (!obj->LoadFromDB(guid, map, false, false))
{
delete obj;
continue;
}
AddObjectHelper(cell, m, count, map, obj);
}
}
void ObjectGridLoader::Visit(GameObjectMapType &m)
{
CellCoord cellCoord = i_cell.GetCellCoord();
@@ -54,7 +54,6 @@
#include "SharedDefines.h"
#include "SocialMgr.h"
#include "SystemPackets.h"
#include "Transport.h"
#include "World.h"
#include "WorldPacket.h"
#include "boost/asio/ip/address.hpp"
@@ -931,26 +930,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder)
loginVerifyWorld.Pos = pCurrChar->GetPosition();
SendPacket(loginVerifyWorld.Write());
// check if player is on transport and not added earlier to transport
// e.g. in case of loading transport on grid load
if (pCurrChar->GetTransportSpawnID() && !pCurrChar->GetTransport())
{
Transport* transport = nullptr;
auto bounds = pCurrChar->GetMap()->GetGameObjectBySpawnIdStore().equal_range(pCurrChar->GetTransportSpawnID());
if (bounds.first != bounds.second)
transport = bounds.first->second->ToTransport();
if (transport)
transport->AddPassenger(pCurrChar);
else
{
pCurrChar->SetTransport(nullptr);
pCurrChar->m_movementInfo.transport.Reset();
pCurrChar->SetTransportSpawnID(0);
}
}
pCurrChar->UpdatePositionData();
pCurrChar->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Login);
pCurrChar->SendInitialPacketsAfterAddToMap();
+6 -15
View File
@@ -93,12 +93,9 @@ void WorldSession::HandleMoveWorldportAck()
return;
}
float x = loc.GetPositionX();
float y = loc.GetPositionY();
float o = loc.GetOrientation();
float z = loc.GetPositionZ() + GetPlayer()->GetHoverOffset();
GetPlayer()->Relocate(x, y, z, o);
GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
GetPlayer()->ResetMap();
@@ -115,16 +112,6 @@ void WorldSession::HandleMoveWorldportAck()
return;
}
if (Transport* transport = _player->GetTeleportTransport())
{
transport->CalculatePassengerOffset(x, y, z, &o);
_player->m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->AddPassenger(_player);
_player->ResetTeleportTransport();
}
// battleground state prepare (in case join to BG), at relogin/tele player not invited
// only add to bg group and object, if the player was invited (else he entered through command)
if (_player->InBattleground())
@@ -366,7 +353,11 @@ void WorldSession::HandleMovementOpcode(uint16 opcode, MovementInfo& movementInf
}
if (!mover->GetTransport() && !mover->GetVehicle())
movementInfo.transport.Reset();
{
GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
movementInfo.transport.guid.Clear();
}
}
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
plrMover->m_transport->RemovePassenger(plrMover);
+12 -23
View File
@@ -362,8 +362,6 @@ i_scriptLock(false), _respawnCheckTimer(0)
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
GetGuidSequenceGenerator<HighGuid::Transport>().Set(sObjectMgr->GetGenerator<HighGuid::Transport>().GetNextAfterMaxUsed());
_weatherUpdateTimer.SetInterval(time_t(1 * IN_MILLISECONDS));
MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId);
@@ -549,7 +547,7 @@ void Map::DeleteFromWorld(Player* player)
}
template<>
void Map::DeleteFromWorld(MapTransport* transport)
void Map::DeleteFromWorld(Transport* transport)
{
ObjectAccessor::RemoveObject(transport);
delete transport;
@@ -763,7 +761,7 @@ bool Map::AddToMap(T* obj)
}
template<>
bool Map::AddToMap(MapTransport* obj)
bool Map::AddToMap(Transport* obj)
{
//TODO: Needs clean up. An object should not be added to map twice.
if (obj->IsInWorld())
@@ -784,7 +782,7 @@ bool Map::AddToMap(MapTransport* obj)
{
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
{
if (itr->GetSource()->GetMapTransport() != obj)
if (itr->GetSource()->GetTransport() != obj)
{
UpdateData data(GetId());
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
@@ -1123,7 +1121,7 @@ void Map::RemoveFromMap(T *obj, bool remove)
}
template<>
void Map::RemoveFromMap(MapTransport* obj, bool remove)
void Map::RemoveFromMap(Transport* obj, bool remove)
{
obj->RemoveFromWorld();
@@ -1735,10 +1733,10 @@ void Map::UnloadAll()
for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();)
{
MapTransport* transport = *itr;
Transport* transport = *itr;
++itr;
RemoveFromMap<MapTransport>(transport, true);
RemoveFromMap<Transport>(transport, true);
}
for (auto& cellCorpsePair : _corpsesByCell)
@@ -2872,7 +2870,7 @@ void Map::SendInitSelf(Player* player)
player->BuildCreateUpdateBlockForPlayer(&data, player);
// build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
if (MapTransport* transport = player->GetMapTransport())
if (Transport* transport = player->GetTransport())
for (WorldObject* passenger : transport->GetPassengers())
if (player != passenger && player->HaveAtClient(passenger))
passenger->BuildCreateUpdateBlockForPlayer(&data, player);
@@ -2888,7 +2886,7 @@ void Map::SendInitTransports(Player* player)
UpdateData transData(player->GetMapId());
for (Transport* transport : _transports)
{
if (transport != player->GetMapTransport() && player->IsInPhase(transport))
if (transport != player->GetTransport() && player->IsInPhase(transport))
{
transport->BuildCreateUpdateBlockForPlayer(&transData, player);
player->m_visibleTransports.insert(transport->GetGUID());
@@ -2906,7 +2904,7 @@ void Map::SendRemoveTransports(Player* player)
UpdateData transData(player->GetMapId());
for (Transport* transport : _transports)
{
if (transport != player->GetMapTransport())
if (transport != player->GetTransport())
{
transport->BuildOutOfRangeUpdateBlock(&transData);
player->m_visibleTransports.erase(transport->GetGUID());
@@ -3459,7 +3457,7 @@ void Map::DelayedUpdate(uint32 t_diff)
{
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
{
MapTransport* transport = *_transportsUpdateIter;
Transport* transport = *_transportsUpdateIter;
++_transportsUpdateIter;
if (!transport->IsInWorld())
@@ -3564,7 +3562,7 @@ void Map::RemoveAllObjectsInRemoveList()
case TYPEID_GAMEOBJECT:
{
GameObject* go = obj->ToGameObject();
if (MapTransport* transport = go->ToMapTransport())
if (Transport* transport = go->ToTransport())
RemoveFromMap(transport, true);
else
RemoveFromMap(go, true);
@@ -4340,22 +4338,13 @@ Pet* Map::GetPet(ObjectGuid const& guid)
Transport* Map::GetTransport(ObjectGuid const& guid)
{
if (!guid.IsTransport())
if (!guid.IsMOTransport())
return nullptr;
GameObject* go = GetGameObject(guid);
return go ? go->ToTransport() : nullptr;
}
MapTransport* Map::GetMapTransport(ObjectGuid const& guid)
{
if (!guid.IsTransport())
return nullptr;
GameObject* go = GetGameObject(guid);
return go ? go->ToMapTransport() : nullptr;
}
void Map::UpdateIteratorBack(Player* player)
{
if (m_mapRefIter == player->GetMapRef())
+1 -3
View File
@@ -46,7 +46,6 @@ class InstanceMap;
class InstanceSave;
class InstanceScript;
class MapInstanced;
class MapTransport;
class Object;
class PhaseShift;
class Player;
@@ -582,7 +581,6 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
}
Pet* GetPet(ObjectGuid const& guid);
Transport* GetTransport(ObjectGuid const& guid);
MapTransport* GetMapTransport(ObjectGuid const& guid);
MapStoredObjectTypesContainer& GetObjectsStore() { return _objectsStore; }
@@ -788,7 +786,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
ActiveNonPlayers::iterator m_activeNonPlayersIter;
// Objects that must update even in inactive grids without activating them
typedef std::set<MapTransport*> TransportsContainer;
typedef std::set<Transport*> TransportsContainer;
TransportsContainer _transports;
TransportsContainer::iterator _transportsUpdateIter;
+6
View File
@@ -315,6 +315,9 @@ void Map::ScriptsProcess()
case HighGuid::Corpse:
source = GetCorpse(step.sourceGUID);
break;
case HighGuid::Mo_Transport:
source = GetTransport(step.sourceGUID);
break;
default:
TC_LOG_ERROR("scripts", "%s source with unsupported high guid %s.",
step.script->GetDebugInfo().c_str(), step.sourceGUID.ToString().c_str());
@@ -344,6 +347,9 @@ void Map::ScriptsProcess()
case HighGuid::Corpse:
target = GetCorpse(step.targetGUID);
break;
case HighGuid::Mo_Transport:
target = GetTransport(step.targetGUID);
break;
default:
TC_LOG_ERROR("scripts", "%s target with unsupported high guid %s.",
step.script->GetDebugInfo().c_str(), step.targetGUID.ToString().c_str());
+17 -60
View File
@@ -363,7 +363,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg,
animNode.Path[timeSeg] = node;
}
MapTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/, uint8 phaseUseFlags /*= 0*/, uint32 phaseId /*= 0*/, uint32 phaseGroupId /*= 0*/)
Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/, uint8 phaseUseFlags /*= 0*/, uint32 phaseId /*= 0*/, uint32 phaseGroupId /*= 0*/)
{
// instance case, execute GetGameObjectEntry hook
if (map)
@@ -385,7 +385,7 @@ MapTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType gu
}
// create transport...
MapTransport* trans = new MapTransport();
Transport* trans = new Transport();
// ...at first waypoint
TaxiPathNodeEntry const* startNode = tInfo->keyFrames.begin()->Node;
@@ -396,9 +396,9 @@ MapTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType gu
float o = tInfo->keyFrames.begin()->InitialOrientation;
// initialize the gameobject base
ObjectGuid::LowType guidLow = guid ? guid : ASSERT_NOTNULL(map)->GenerateLowGuid<HighGuid::Transport>();
ObjectGuid::LowType guidLow = guid ? guid : sObjectMgr->GetGenerator<HighGuid::Mo_Transport>().Generate();
if (!trans->CreateMapTransport(guidLow, entry, mapId, x, y, z, o, 255))
if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255))
{
delete trans;
return nullptr;
@@ -419,11 +419,11 @@ MapTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType gu
// use preset map for instances (need to know which instance)
trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, nullptr));
if (map && map->IsDungeon())
trans->SetZoneScript();
trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript();
// Passengers will be loaded once a player is near
HashMapHolder<MapTransport>::Insert(trans);
trans->GetMap()->AddToMap<MapTransport>(trans);
HashMapHolder<Transport>::Insert(trans);
trans->GetMap()->AddToMap<Transport>(trans);
return trans;
}
@@ -509,63 +509,20 @@ void TransportMgr::CreateInstanceTransports(Map* map)
CreateTransport(*itr, 0, map);
}
bool TransportAnimation::GetAnimNode(uint32 time, TransportAnimationEntry const*& curr, TransportAnimationEntry const*& next, float& percPos) const
TransportAnimationEntry const* TransportAnimation::GetAnimNode(uint32 time) const
{
if (Path.empty())
return false;
auto itr = Path.lower_bound(time);
if (itr != Path.end())
return itr->second;
for (TransportPathContainer::const_reverse_iterator itr = Path.rbegin(); itr != Path.rend(); ++itr)
if (time >= itr->first)
{
curr = itr->second;
//ASSERT(itr != Path.rbegin());
--itr;
next = itr->second;
percPos = float(time - curr->TimeIndex) / float(next->TimeIndex - curr->TimeIndex);
return true;
}
return false;
return nullptr;
}
void TransportAnimation::GetAnimRotation(uint32 time, QuaternionData& curr, QuaternionData& next, float& percRot) const
TransportRotationEntry const* TransportAnimation::GetAnimRotation(uint32 time) const
{
if (Rotations.empty())
{
curr = QuaternionData(0.0f, 0.0f, 0.0f, 1.0f);
next = QuaternionData(0.0f, 0.0f, 0.0f, 1.0f);
percRot = 0.0f;
return;
}
auto itr = Rotations.lower_bound(time);
if (itr != Rotations.end())
return itr->second;
for (TransportPathRotationContainer::const_reverse_iterator itr = Rotations.rbegin(); itr != Rotations.rend(); ++itr)
if (time >= itr->first)
{
uint32 currSeg = itr->second->TimeIndex;
uint32 nextSeg = 0;
curr = QuaternionData(itr->second->X, itr->second->Y, itr->second->Z, itr->second->W);
if (itr != Rotations.rbegin())
{
--itr;
next = QuaternionData(itr->second->X, itr->second->Y, itr->second->Z, itr->second->W);
nextSeg = itr->second->TimeIndex;
}
else
{
next = QuaternionData(Rotations.begin()->second->X, Rotations.begin()->second->Y, Rotations.begin()->second->Z, Rotations.begin()->second->W);
nextSeg = this->TotalTime;
}
percRot = float(time - currSeg) / float(nextSeg - currSeg);
return;
}
curr = QuaternionData(0.0f, 0.0f, 0.0f, 1.0f);
next = QuaternionData(0.0f, 0.0f, 0.0f, 1.0f);
percRot = 0.0f;
return nullptr;
}
+65 -58
View File
@@ -1,5 +1,5 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
* Copyright (C) 2008-2018 TrinityCore <https://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
@@ -26,7 +26,6 @@ struct KeyFrame;
struct GameObjectTemplate;
struct TransportTemplate;
class Transport;
class MapTransport;
class Map;
namespace Movement
@@ -34,12 +33,12 @@ namespace Movement
template <typename length_type> class Spline;
}
typedef Movement::Spline<double> TransportSpline;
typedef std::vector<KeyFrame> KeyFrameVec;
typedef std::unordered_map<uint32, TransportTemplate> TransportTemplates;
typedef std::set<Transport*> TransportSet;
typedef std::unordered_map<uint32, TransportSet> TransportMap;
typedef std::unordered_map<uint32, std::set<uint32>> TransportInstanceMap;
typedef Movement::Spline<double> TransportSpline;
typedef std::vector<KeyFrame> KeyFrameVec;
typedef std::unordered_map<uint32, TransportTemplate> TransportTemplates;
typedef std::set<Transport*> TransportSet;
typedef std::unordered_map<uint32, TransportSet> TransportMap;
typedef std::unordered_map<uint32, std::set<uint32> > TransportInstanceMap;
struct KeyFrame
{
@@ -66,13 +65,21 @@ struct KeyFrame
float NextDistFromPrev;
uint32 NextArriveTime;
bool IsTeleportFrame() const { return Teleport; }
bool IsStopFrame() const { return Node->Flags == 2; }
bool IsTeleportFrame() const
{
return Teleport;
}
bool IsStopFrame() const
{
return Node->Flags == 2;
}
};
struct TransportTemplate
{
TransportTemplate() : inInstance(false), pathTime(0), accelTime(0.0f), accelDist(0.0f), entry(0) { }
TransportTemplate() : inInstance(false), pathTime(0), accelTime(0.0f), accelDist(0.0f), entry(0)
{
}
~TransportTemplate();
std::set<uint32> mapsUsed;
@@ -84,85 +91,85 @@ struct TransportTemplate
uint32 entry;
};
struct QuaternionData;
typedef std::map<uint32, TransportAnimationEntry const*> TransportPathContainer;
typedef std::map<uint32, TransportRotationEntry const*> TransportPathRotationContainer;
struct TC_GAME_API TransportAnimation
{
TransportAnimation() : TotalTime(0) { }
TransportAnimation() : TotalTime(0)
{
}
TransportPathContainer Path;
TransportPathRotationContainer Rotations;
uint32 TotalTime;
bool GetAnimNode(uint32 time, TransportAnimationEntry const*& curr, TransportAnimationEntry const*& next, float& percPos) const;
void GetAnimRotation(uint32 time, QuaternionData& curr, QuaternionData& next, float& percRot) const;
TransportAnimationEntry const* GetAnimNode(uint32 time) const;
TransportRotationEntry const* GetAnimRotation(uint32 time) const;
};
typedef std::map<uint32, TransportAnimation> TransportAnimationContainer;
class TC_GAME_API TransportMgr
{
public:
static TransportMgr* instance();
public:
static TransportMgr* instance();
void Unload();
void Unload();
void LoadTransportTemplates();
void LoadTransportTemplates();
void LoadTransportAnimationAndRotation();
void LoadTransportAnimationAndRotation();
// Creates a transport using given GameObject template entry
MapTransport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0);
// Creates a transport using given GameObject template entry
Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0);
// Spawns all continent transports, used at core startup
void SpawnContinentTransports();
// Spawns all continent transports, used at core startup
void SpawnContinentTransports();
// creates all transports for instance
void CreateInstanceTransports(Map* map);
// creates all transports for instance
void CreateInstanceTransports(Map* map);
TransportTemplate const* GetTransportTemplate(uint32 entry) const
{
TransportTemplates::const_iterator itr = _transportTemplates.find(entry);
if (itr != _transportTemplates.end())
return &itr->second;
return nullptr;
}
TransportTemplate const* GetTransportTemplate(uint32 entry) const
{
TransportTemplates::const_iterator itr = _transportTemplates.find(entry);
if (itr != _transportTemplates.end())
return &itr->second;
return nullptr;
}
TransportAnimation const* GetTransportAnimInfo(uint32 entry) const
{
TransportAnimationContainer::const_iterator itr = _transportAnimations.find(entry);
if (itr != _transportAnimations.end())
return &itr->second;
TransportAnimation const* GetTransportAnimInfo(uint32 entry) const
{
TransportAnimationContainer::const_iterator itr = _transportAnimations.find(entry);
if (itr != _transportAnimations.end())
return &itr->second;
return nullptr;
}
return nullptr;
}
private:
TransportMgr();
~TransportMgr();
TransportMgr(TransportMgr const&) = delete;
TransportMgr& operator=(TransportMgr const&) = delete;
private:
TransportMgr();
~TransportMgr();
TransportMgr(TransportMgr const&) = delete;
TransportMgr& operator=(TransportMgr const&) = delete;
// Generates and precaches a path for transport to avoid generation each time transport instance is created
void GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport);
// Generates and precaches a path for transport to avoid generation each time transport instance is created
void GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport);
void AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const* node);
void AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const* node);
void AddPathRotationToTransport(uint32 transportEntry, uint32 timeSeg, TransportRotationEntry const* node)
{
_transportAnimations[transportEntry].Rotations[timeSeg] = node;
}
void AddPathRotationToTransport(uint32 transportEntry, uint32 timeSeg, TransportRotationEntry const* node)
{
_transportAnimations[transportEntry].Rotations[timeSeg] = node;
}
// Container storing transport templates
TransportTemplates _transportTemplates;
// Container storing transport templates
TransportTemplates _transportTemplates;
// Container storing transport entries to create for instanced maps
TransportInstanceMap _instanceTransports;
// Container storing transport entries to create for instanced maps
TransportInstanceMap _instanceTransports;
TransportAnimationContainer _transportAnimations;
TransportAnimationContainer _transportAnimations;
};
#define sTransportMgr TransportMgr::instance()
@@ -1870,7 +1870,7 @@ enum GOState : uint8
GO_STATE_ACTIVE = 0, // show in world as used and not reset (closed door open)
GO_STATE_READY = 1, // show in world as ready (closed door close)
GO_STATE_ACTIVE_ALTERNATIVE = 2, // show in world as used in alt way and not reset (closed door open by cannon fire)
GO_STATE_TRANSPORT_ACTIVE = 24, // transport exclusive: transport moves to first stop frame
GO_STATE_TRANSPORT_ACTIVE = 24, // transport exclusive: transport may always move
GO_STATE_TRANSPORT_STOPPED = 25 // transport exclusive: transport is going to stop at provided stop frame
};
+1 -6
View File
@@ -21,7 +21,6 @@
#include "Log.h"
#include "MapManager.h"
#include "ObjectMgr.h"
#include "Transport.h"
////////////////////////////////////////////////////////////
// template class ActivePoolData
@@ -352,11 +351,7 @@ void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj)
// We use current coords to unspawn, not spawn coords since creature can have changed grid
if (map && !map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
{
GameObject* pGameobject = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(data->id) == GAMEOBJECT_TYPE_TRANSPORT)
pGameobject = new Transport();
else
pGameobject = new GameObject();
GameObject* pGameobject = new GameObject;
//TC_LOG_DEBUG("pool", "Spawning gameobject %u", guid);
if (!pGameobject->LoadFromDB(obj->guid, map, false))
{
+7 -27
View File
@@ -2969,11 +2969,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
GameObject* pGameObj = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(gameobject_id) == GAMEOBJECT_TYPE_TRANSPORT)
pGameObj = new Transport();
else
pGameObj = new GameObject();
GameObject* pGameObj = new GameObject;
WorldObject* target = focusObject;
if (!target)
@@ -4032,11 +4028,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
m_caster->m_ObjectSlot[slot].Clear();
}
GameObject* go = nullptr;
if (sObjectMgr->GetGameObjectTypeByEntry(go_id) == GAMEOBJECT_TYPE_TRANSPORT)
go = new Transport();
else
go = new GameObject();
GameObject* go = new GameObject();
float x, y, z, o;
// If dest location if present
@@ -4847,24 +4839,12 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
QuaternionData rot = QuaternionData::fromEulerAnglesZYX(fo, 0.f, 0.f);
GameObject* pGameObj = nullptr;
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
GameObject* pGameObj = new GameObject;
if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, Position(fx, fy, fz, m_caster->GetOrientation()), rot, 255, GO_STATE_READY))
{
pGameObj = new Transport();
if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::Transport>(), name_id, cMap, Position(fx, fy, fz, fo), rot, 255, GO_STATE_READY))
{
delete pGameObj;
return;
}
}
else
{
pGameObj = new GameObject();
if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, Position(fx, fy, fz, fo), rot, 255, GO_STATE_READY))
{
delete pGameObj;
return;
}
delete pGameObj;
return;
}
PhasingHandler::InheritPhaseShift(pGameObj, m_caster);
+1 -1
View File
@@ -1568,7 +1568,7 @@ public:
static bool HandleDebugTransportCommand(ChatHandler* handler, char const* args)
{
MapTransport* transport = handler->GetSession()->GetPlayer()->GetMapTransport();
Transport* transport = handler->GetSession()->GetPlayer()->GetTransport();
if (!transport)
return false;
+4 -18
View File
@@ -39,7 +39,6 @@ EndScriptData */
#include "Player.h"
#include "PoolMgr.h"
#include "RBAC.h"
#include "Transport.h"
#include "WorldSession.h"
// definitions are over in cs_npc.cpp
@@ -154,19 +153,8 @@ public:
Player* player = handler->GetSession()->GetPlayer();
Map* map = player->GetMap();
GameObject* object = nullptr;
ObjectGuid::LowType guidLow = ObjectGuid::Empty;
if (objectInfo->type == GAMEOBJECT_TYPE_TRANSPORT)
{
object = new Transport();
guidLow = map->GenerateLowGuid<HighGuid::Transport>();
}
else
{
object = new GameObject();
guidLow = map->GenerateLowGuid<HighGuid::GameObject>();
}
GameObject* object = new GameObject;
ObjectGuid::LowType guidLow = map->GenerateLowGuid<HighGuid::GameObject>();
QuaternionData rotation = QuaternionData::fromEulerAnglesZYX(player->GetOrientation(), 0.f, 0.f);
if (!object->Create(guidLow, objectInfo->entry, map, *player, rotation, 255, GO_STATE_READY))
{
@@ -190,10 +178,8 @@ public:
// this is required to avoid weird behavior and memory leaks
delete object;
if (objectInfo->type == GAMEOBJECT_TYPE_TRANSPORT)
object = new Transport();
else
object = new GameObject();
object = new GameObject();
// this will generate a new guid if the object is in an instance
if (!object->LoadFromDB(guidLow, map, true))
{
+2 -2
View File
@@ -154,8 +154,8 @@ public:
// before GM
float x, y, z;
gmPlayer->GetPosition(x, y, z);
player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation(), 0, gmPlayer->GetTransport());
gmPlayer->GetClosePoint(x, y, z, player->GetCombatReach());
player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation());
}
return true;
+4 -8
View File
@@ -283,12 +283,8 @@ public:
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation());
if (Transport* transport = object->GetTransport())
{
int32 transMapID = -1;
if (transport->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
transMapID = transport->GetGOInfo()->moTransport.mapID;
handler->PSendSysMessage(LANG_TRANSPORT_POSITION,
transMapID, object->GetTransOffsetX(), object->GetTransOffsetY(), object->GetTransOffsetZ(), object->GetTransOffsetO(),
transport->GetGOInfo()->moTransport.mapID, object->GetTransOffsetX(), object->GetTransOffsetY(), object->GetTransOffsetZ(), object->GetTransOffsetO(),
transport->GetEntry(), transport->GetName().c_str());
}
handler->PSendSysMessage(LANG_GRID_POSITION,
@@ -456,9 +452,9 @@ public:
// to point to see at target with same orientation
float x, y, z;
target->GetPosition(x, y, z);
target->GetContactPoint(_player, x, y, z);
_player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE, target->GetTransport());
_player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE);
PhasingHandler::InheritPhaseShift(_player, target);
_player->UpdateObjectVisibility();
}
@@ -589,7 +585,7 @@ public:
// before GM
float x, y, z;
_player->GetPosition(x, y, z);
target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation(), 0, _player->GetTransport());
target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation());
PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer());
target->UpdateObjectVisibility();
}
+1 -1
View File
@@ -349,7 +349,7 @@ public:
Player* chr = handler->GetSession()->GetPlayer();
Map* map = chr->GetMap();
if (MapTransport* trans = chr->GetMapTransport())
if (Transport* trans = chr->GetTransport())
{
ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId();
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
@@ -31,7 +31,6 @@
#include "SpellMgr.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
#include "Transport.h"
#include "halls_of_origination.h"
enum SunTouchedServant
@@ -781,7 +780,7 @@ struct go_hoo_the_makers_lift_controller : public GameObjectAI
return true;
// Handle elevator: gossip item index => stopFrame (floor index).
Transport* elevator = ObjectAccessor::GetTransportOnMap(*me, instance->GetGuidData(DATA_LIFT_OF_THE_MAKERS));
GameObject* elevator = instance->GetGameObject(DATA_LIFT_OF_THE_MAKERS);
if (!elevator)
return true;
@@ -1122,7 +1122,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript
me->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL);
if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
Talk(SAY_JAINA_ESCAPE_9);
if (MapTransport* gunship = ObjectAccessor::GetMapTransportOnMap(*me, _instance->GetGuidData(DATA_GUNSHIP)))
if (Transport* gunship = ObjectAccessor::GetTransport(*me, _instance->GetGuidData(DATA_GUNSHIP)))
gunship->EnableMovement(true);
_instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, DONE);
break;
@@ -1194,7 +1194,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript
if (Creature* target = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ESCAPE_LEADER)))
DoCast(target, SPELL_HARVEST_SOUL);
if (MapTransport* gunship = ObjectAccessor::GetMapTransportOnMap(*me, _instance->GetGuidData(DATA_GUNSHIP)))
if (Transport* gunship = ObjectAccessor::GetTransport(*me, _instance->GetGuidData(DATA_GUNSHIP)))
gunship->EnableMovement(true);
break;
default:
@@ -393,7 +393,7 @@ class instance_halls_of_reflection : public InstanceMapScript
_teamInInstance = player->GetTeam();
}
if (MapTransport* gunship = sTransportMgr->CreateTransport(_teamInInstance == HORDE ? GO_ORGRIMS_HAMMER : GO_THE_SKYBREAKER, 0, instance))
if (Transport* gunship = sTransportMgr->CreateTransport(_teamInInstance == HORDE ? GO_ORGRIMS_HAMMER : GO_THE_SKYBREAKER, 0, instance))
gunship->EnableMovement(GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE);
}
@@ -640,7 +640,7 @@ class instance_halls_of_reflection : public InstanceMapScript
if (GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE)
break;
if (MapTransport* gunship = instance->GetMapTransport(GunshipGUID))
if (Transport* gunship = instance->GetTransport(GunshipGUID))
gunship->EnableMovement(false);
if (Creature* jainaOrSylvanas = instance->GetCreature(JainaOrSylvanasEscapeGUID))
@@ -658,7 +658,7 @@ class instance_halls_of_reflection : public InstanceMapScript
}
break;
case EVENT_GUNSHIP_ARRIVAL_2:
if (MapTransport* gunship = instance->GetMapTransport(GunshipGUID))
if (Transport* gunship = instance->GetTransport(GunshipGUID))
gunship->EnableMovement(false);
for (ObjectGuid guid : GunshipStairGUIDs)
@@ -384,7 +384,7 @@ public:
ResetSlots(HORDE);
}
void SetTransport(MapTransport* transport) { _transport = transport; }
void SetTransport(Transport* transport) { _transport = transport; }
void ResetSlots(uint32 team)
{
@@ -455,7 +455,7 @@ private:
return newPos;
}
MapTransport* _transport;
Transport* _transport;
ObjectGuid _controlledSlots[MAX_SLOTS];
time_t _respawnCooldowns[MAX_SLOTS];
Position const* _spawnPoint;
@@ -495,7 +495,7 @@ public:
_caster->CastSpell(_caster, _spellId, true);
_caster->GetTransport()->AddObjectToRemoveList();
if (MapTransport* go = ObjectAccessor::GetMapTransport(_otherTransport))
if (Transport* go = HashMapHolder<Transport>::Find(_otherTransport))
go->AddObjectToRemoveList();
return true;
@@ -765,10 +765,10 @@ class npc_gunship : public CreatureScript
if (isVictory)
{
if (MapTransport* trans = ObjectAccessor::GetMapTransport(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
trans->EnableMovement(true);
if (Transport* otherTransport = HashMapHolder<Transport>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
otherTransport->EnableMovement(true);
me->GetMapTransport()->EnableMovement(true);
me->GetTransport()->EnableMovement(true);
if (Creature* ship = me->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f))
{
@@ -844,7 +844,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript
_instance(creature->GetInstanceScript())
{
_controller.ResetSlots(HORDE);
_controller.SetTransport(creature->GetMapTransport());
_controller.SetTransport(creature->GetTransport());
me->setRegeneratingHealth(false);
me->m_CombatDistance = 70.0f;
_firstMageCooldown = GameTime::GetGameTime() + 60;
@@ -954,7 +954,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript
bool GossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->GetMapTransport()->EnableMovement(true);
me->GetTransport()->EnableMovement(true);
_events.SetPhase(PHASE_INTRO);
_events.ScheduleEvent(EVENT_INTRO_H_1, 5000, 0, PHASE_INTRO);
_events.ScheduleEvent(EVENT_INTRO_H_2, 16000, 0, PHASE_INTRO);
@@ -1022,10 +1022,10 @@ class npc_high_overlord_saurfang_igb : public CreatureScript
_controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2);
_controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2);
_controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1);
if (MapTransport* orgrimsHammer = me->GetMapTransport())
if (Transport* orgrimsHammer = me->GetTransport())
orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000);
if (MapTransport* skybreaker = ObjectAccessor::GetMapTransport(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
if (Transport* skybreaker = HashMapHolder<Transport>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000);
_events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000);
@@ -1108,7 +1108,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript
_instance(creature->GetInstanceScript())
{
_controller.ResetSlots(ALLIANCE);
_controller.SetTransport(creature->GetMapTransport());
_controller.SetTransport(creature->GetTransport());
me->setRegeneratingHealth(false);
me->m_CombatDistance = 70.0f;
_firstMageCooldown = GameTime::GetGameTime() + 60;
@@ -1218,7 +1218,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript
bool GossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->GetMapTransport()->EnableMovement(true);
me->GetTransport()->EnableMovement(true);
_events.SetPhase(PHASE_INTRO);
_events.ScheduleEvent(EVENT_INTRO_A_1, 5000);
_events.ScheduleEvent(EVENT_INTRO_A_2, 10000, 0, PHASE_INTRO);
@@ -1290,10 +1290,10 @@ class npc_muradin_bronzebeard_igb : public CreatureScript
_controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2);
_controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2);
_controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1);
if (MapTransport* skybreaker = me->GetMapTransport())
if (Transport* skybreaker = me->GetTransport())
skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000);
if (MapTransport* orgrimsHammer = ObjectAccessor::GetMapTransport(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
if (Transport* orgrimsHammer = HashMapHolder<Transport>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000);
_events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000);
@@ -1439,7 +1439,7 @@ struct npc_gunship_boarding_addAI : public gunship_npc_AI
if (!myTransport)
return;
if (MapTransport* destTransport = ObjectAccessor::GetMapTransport(Instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
if (Transport* destTransport = HashMapHolder<Transport>::Find(Instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)))
destTransport->CalculatePassengerPosition(x, y, z, &o);
float angle = frand(0, float(M_PI) * 2.0f);
@@ -2288,7 +2288,7 @@ class spell_igb_gunship_fall_teleport : public SpellScriptLoader
void SelectTransport(WorldObject*& target)
{
if (InstanceScript* instance = target->GetInstanceScript())
target = ObjectAccessor::GetMapTransport(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE));
target = HashMapHolder<Transport>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE));
}
void RelocateDest(SpellEffIndex /*effIndex*/)
@@ -123,7 +123,6 @@ class instance_icecrown_citadel : public InstanceMapScript
UpperSpireTeleporterActiveState = NOT_STARTED;
BloodPrinceIntro = 1;
SindragosaIntro = 1;
LadyDeathwhisperElevatorTimer = 3000;
}
// A function to help reduce the number of lines for teleporter management.
@@ -436,8 +435,7 @@ class instance_icecrown_citadel : public InstanceMapScript
case GO_LADY_DEATHWHISPER_ELEVATOR:
LadyDeathwisperElevatorGUID = go->GetGUID();
if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE)
if (Transport* transport = go->ToTransport())
transport->SetTransportState(GO_STATE_TRANSPORT_ACTIVE);
go->SetTransportState(GO_STATE_TRANSPORT_ACTIVE);
break;
case GO_THE_SKYBREAKER_H:
case GO_ORGRIMS_HAMMER_A:
@@ -896,7 +894,7 @@ class instance_icecrown_citadel : public InstanceMapScript
{
SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, NOT_STARTED);
uint32 gunshipEntry = TeamInInstance == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A;
if (MapTransport* gunship = sTransportMgr->CreateTransport(gunshipEntry, 0, instance))
if (Transport* gunship = sTransportMgr->CreateTransport(gunshipEntry, 0, instance))
GunshipGUID = gunship->GetGUID();
}
}
@@ -1167,28 +1165,6 @@ class instance_icecrown_citadel : public InstanceMapScript
void Update(uint32 diff) override
{
if (LadyDeathwhisperElevatorTimer <= diff)
{
LadyDeathwhisperElevatorTimer = 3000;
if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE)
{
if (Transport* elevator = instance->GetTransport(LadyDeathwisperElevatorGUID))
{
if (elevator->GetDestinationStopFrameTime() == elevator->GetCurrentTransportTime())
{
if (!elevator->GetCurrentTransportTime())
elevator->SetTransportState(GO_STATE_TRANSPORT_STOPPED, 1);
else
elevator->SetTransportState(GO_STATE_TRANSPORT_STOPPED, 0);
LadyDeathwhisperElevatorTimer = 20000;
}
}
}
}
else
LadyDeathwhisperElevatorTimer -= diff;
if (GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL)
return;
@@ -1244,7 +1220,7 @@ class instance_icecrown_citadel : public InstanceMapScript
case EVENT_PLAYERS_GUNSHIP_SPAWN:
case EVENT_PLAYERS_GUNSHIP_COMBAT:
if (GameObject* go = source->ToGameObject())
if (MapTransport* transport = go->ToMapTransport())
if (Transport* transport = go->ToTransport())
transport->EnableMovement(false);
break;
case EVENT_PLAYERS_GUNSHIP_SAURFANG:
@@ -1252,7 +1228,7 @@ class instance_icecrown_citadel : public InstanceMapScript
if (Creature* captain = source->FindNearestCreature(TeamInInstance == HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 100.0f))
captain->AI()->DoAction(ACTION_EXIT_SHIP);
if (GameObject* go = source->ToGameObject())
if (MapTransport* transport = go->ToMapTransport())
if (Transport* transport = go->ToTransport())
transport->EnableMovement(false);
break;
}
@@ -1353,7 +1329,6 @@ class instance_icecrown_citadel : public InstanceMapScript
std::set<uint32> RimefangTrash;
uint8 BloodPrinceIntro;
uint8 SindragosaIntro;
uint32 LadyDeathwhisperElevatorTimer;
bool IsBonedEligible;
bool IsOozeDanceEligible;
bool IsNauseaEligible;
@@ -26,71 +26,6 @@
#include "ObjectMgr.h"
#include "SpellInfo.h"
enum DeeprunTram
{
MAP_DEEPRUN_TRAM = 369,
GO_SUBWAY = 176080,
MAX_SUBWAY_COUNT = 6
};
Position const SubwaysPos[MAX_SUBWAY_COUNT] =
{
{ 4.580650f, 28.20970f, 7.01107f, 1.5708f },
{ 4.528070f, 8.435290f, 7.01107f, 1.5708f },
{ -45.4005f, 2492.790f, 6.98860f, 1.5708f },
{ -45.4007f, 2512.150f, 6.98860f, 1.5708f },
{ -45.3934f, 2472.930f, 6.98860f, 1.5708f },
{ 4.498830f, -11.3475f, 7.01107f, 1.5708f }
};
static QuaternionData worldRotation = QuaternionData(0.0f, 0.0f, 0.7071066f, 0.7071069f);
static QuaternionData parentRotation = QuaternionData(0.0f, 0.0f, 1.0f, -0.0000000437114f);
class world_map_deeprun_tram: public WorldMapScript
{
public:
world_map_deeprun_tram() : WorldMapScript("world_map_deeprun_tram", MAP_DEEPRUN_TRAM)
{
Initialize();
}
void Initialize()
{
_initializedTrams = false;
}
void OnPlayerEnter(Map* map, Player* /*player*/) override
{
if (!_initializedTrams)
{
_initializedTrams = true;
for (uint8 i = 0; i < MAX_SUBWAY_COUNT; ++i)
{
GameObject* transport = new Transport();
if (!transport->Create(map->GenerateLowGuid<HighGuid::Transport>(), GO_SUBWAY + i, map, SubwaysPos[i], worldRotation, 255, GO_STATE_READY))
{
delete transport;
continue;
}
transport->SetParentRotation(parentRotation);
uint32 spawnId = sObjectMgr->GenerateGameObjectSpawnId();
transport->SetSpawnId(spawnId);
transport->setActive(true);
transport->SetFarVisible(true);
map->AddToMap(transport);
}
}
}
private:
bool _initializedTrams;
};
enum Gilneas
{
MAP_GILNEAS = 654,
@@ -162,6 +97,5 @@ class world_map_gilneas: public WorldMapScript
void AddSC_world_map_scripts()
{
new world_map_deeprun_tram();
new world_map_gilneas();
}