mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-18 14:10:18 -04:00
Core/Transports
* Fixed fall damage on transports while teleporting * Fixed packets not being received by owner if sent by a controlled minion * Fixed an issue when a teleporting transport would attempt to reload its creature passengers on old map Closes #11140
This commit is contained in:
@@ -2178,26 +2178,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
if (!(options & TELE_TO_NOT_LEAVE_COMBAT))
|
||||
CombatStop();
|
||||
|
||||
// new final coordinates
|
||||
float final_x = x;
|
||||
float final_y = y;
|
||||
float final_z = z;
|
||||
float final_o = orientation;
|
||||
|
||||
// Calculate final positions if on transport
|
||||
if (m_transport)
|
||||
{
|
||||
float tx, ty, tz, to;
|
||||
m_movementInfo.transport.pos.GetPosition(tx, ty, tz, to);
|
||||
|
||||
final_x = x + tx * std::cos(orientation) - ty * std::sin(orientation);
|
||||
final_y = y + ty * std::cos(orientation) + tx * std::sin(orientation);
|
||||
final_z = z + tz;
|
||||
final_o = Position::NormalizeOrientation(orientation + m_movementInfo.transport.pos.GetOrientation());
|
||||
}
|
||||
|
||||
// this will be used instead of the current location in SaveToDB
|
||||
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
|
||||
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
|
||||
SetFallInformation(0, z);
|
||||
|
||||
// code for finish transfer called in WorldSession::HandleMovementOpcodes()
|
||||
@@ -2208,7 +2190,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
{
|
||||
Position oldPos;
|
||||
GetPosition(&oldPos);
|
||||
Relocate(final_x, final_y, final_z, final_o);
|
||||
Relocate(z, y, z, orientation);
|
||||
SendTeleportAckPacket();
|
||||
SendTeleportPacket(oldPos); // this automatically relocates to oldPos in order to broadcast the packet in the right place
|
||||
}
|
||||
@@ -2304,25 +2286,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
if (oldmap)
|
||||
oldmap->RemovePlayerFromMap(this, false);
|
||||
|
||||
// new final coordinates
|
||||
float final_x = x;
|
||||
float final_y = y;
|
||||
float final_z = z;
|
||||
float final_o = orientation;
|
||||
|
||||
// Calculate final positions if on transport
|
||||
if (m_transport)
|
||||
{
|
||||
float tx, ty, tz, to;
|
||||
m_movementInfo.transport.pos.GetPosition(tx, ty, tz, to);
|
||||
|
||||
final_x = x + tx * std::cos(orientation) - ty * std::sin(orientation);
|
||||
final_y = y + ty * std::cos(orientation) + tx * std::sin(orientation);
|
||||
final_z = z + tz;
|
||||
final_o = Position::NormalizeOrientation(orientation + m_movementInfo.transport.pos.GetOrientation());
|
||||
}
|
||||
|
||||
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
|
||||
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
|
||||
SetFallInformation(0, z);
|
||||
// if the player is saved before worldportack (at logout for example)
|
||||
// this will be used instead of the current location in SaveToDB
|
||||
|
||||
@@ -163,13 +163,14 @@ void Transport::Update(uint32 diff)
|
||||
if (GetGOInfo()->moTransport.canBeStopped)
|
||||
SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
// Departure event
|
||||
if (_currentFrame->IsTeleportFrame())
|
||||
TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z);
|
||||
|
||||
sScriptMgr->OnRelocate(this, _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);
|
||||
|
||||
TC_LOG_DEBUG(LOG_FILTER_TRANSPORTS, "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);
|
||||
|
||||
// Departure event
|
||||
if (_currentFrame->IsTeleportFrame())
|
||||
if (TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z))
|
||||
return; // Update more in new map thread
|
||||
}
|
||||
|
||||
// Set position
|
||||
@@ -237,6 +238,10 @@ Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data)
|
||||
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
|
||||
creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos);
|
||||
|
||||
/// @HACK - transport models are not added to map's dynamic LoS calculations
|
||||
/// because the current GameObjectModel cannot be moved without recreating
|
||||
creature->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);
|
||||
|
||||
if (!creature->IsPositionValid())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_TRANSPORTS, "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)",creature->GetGUIDLow(),creature->GetEntry(),creature->GetPositionX(),creature->GetPositionY());
|
||||
@@ -294,30 +299,6 @@ GameObject* Transport::CreateGOPassenger(uint32 guid, GameObjectData const* data
|
||||
return go;
|
||||
}
|
||||
|
||||
void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
float inx = x, iny = y, inz = z;
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(GetOrientation() + *o);
|
||||
|
||||
x = GetPositionX() + inx * std::cos(GetOrientation()) - iny * std::sin(GetOrientation());
|
||||
y = GetPositionY() + iny * std::cos(GetOrientation()) + inx * std::sin(GetOrientation());
|
||||
z = GetPositionZ() + inz;
|
||||
}
|
||||
|
||||
void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(*o - GetOrientation());
|
||||
|
||||
z -= GetPositionZ();
|
||||
y -= GetPositionY(); // y = searchedY * std::cos(o) + searchedX * std::sin(o)
|
||||
x -= GetPositionX(); // x = searchedX * std::cos(o) + searchedY * std::sin(o + pi)
|
||||
float inx = x, iny = y;
|
||||
y = (iny - inx * std::tan(GetOrientation())) / (std::cos(GetOrientation()) + std::sin(GetOrientation()) * std::tan(GetOrientation()));
|
||||
x = (inx + iny * std::tan(GetOrientation())) / (std::cos(GetOrientation()) + std::sin(GetOrientation()) * std::tan(GetOrientation()));
|
||||
}
|
||||
|
||||
void Transport::UpdatePosition(float x, float y, float z, float o)
|
||||
{
|
||||
bool newActive = GetMap()->IsGridLoaded(x, y);
|
||||
@@ -422,7 +403,7 @@ float Transport::CalculateSegmentPos(float now)
|
||||
return segmentPos / frame.NextDistFromPrev;
|
||||
}
|
||||
|
||||
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
{
|
||||
Map const* oldMap = GetMap();
|
||||
|
||||
@@ -465,23 +446,27 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
{
|
||||
WorldObject* obj = (*itr++);
|
||||
|
||||
float destX, destY, destZ, destO;
|
||||
obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
|
||||
TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation());
|
||||
|
||||
switch (obj->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
if (!IS_PLAYER_GUID(obj->ToUnit()->GetOwnerGUID())) // pets should be teleported with player
|
||||
obj->ToCreature()->FarTeleportTo(newMap, x, y, z, obj->GetOrientation());
|
||||
obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO);
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
{
|
||||
GameObject* go = obj->ToGameObject();
|
||||
go->GetMap()->RemoveFromMap(go, false);
|
||||
Relocate(x, y, z, go->GetOrientation());
|
||||
Relocate(destX, destY, destZ, destO);
|
||||
SetMap(newMap);
|
||||
newMap->AddToMap(go);
|
||||
break;
|
||||
}
|
||||
case TYPEID_PLAYER:
|
||||
if (!obj->ToPlayer()->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT))
|
||||
if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
|
||||
_passengers.erase(obj);
|
||||
break;
|
||||
default:
|
||||
@@ -489,17 +474,28 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
}
|
||||
}
|
||||
|
||||
Relocate(x, y, z, GetOrientation());
|
||||
GetMap()->AddToMap<Transport>(this);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Teleport players, they need to know it
|
||||
for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetTypeId() == TYPEID_PLAYER)
|
||||
(*itr)->ToUnit()->NearTeleportTo(x, y, z, GetOrientation());
|
||||
}
|
||||
{
|
||||
float destX, destY, destZ, destO;
|
||||
(*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
|
||||
TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation());
|
||||
|
||||
UpdatePosition(x, y, z, GetOrientation());
|
||||
(*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO);
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePosition(x, y, z, GetOrientation());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Transport::UpdatePassengerPositions(std::set<WorldObject*>& passengers)
|
||||
|
||||
@@ -46,10 +46,16 @@ class Transport : public GameObject, public TransportBase
|
||||
GameObject* CreateGOPassenger(uint32 guid, GameObjectData const* data);
|
||||
|
||||
/// This method transforms supplied transport offsets into global coordinates
|
||||
void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const;
|
||||
void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
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 = NULL) const;
|
||||
void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
TransportBase::CalculatePassengerOffset(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
|
||||
}
|
||||
|
||||
uint32 GetPeriod() const { return GetUInt32Value(GAMEOBJECT_LEVEL); }
|
||||
void SetPeriod(uint32 period) { SetUInt32Value(GAMEOBJECT_LEVEL, period); }
|
||||
@@ -72,7 +78,7 @@ class Transport : public GameObject, public TransportBase
|
||||
private:
|
||||
void MoveToNextWaypoint();
|
||||
float CalculateSegmentPos(float perc);
|
||||
void TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
bool TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
void UpdatePassengerPositions(std::set<WorldObject*>& passengers);
|
||||
void DoEventIfAny(KeyFrame const& node, bool departure);
|
||||
|
||||
|
||||
@@ -679,30 +679,6 @@ uint8 Vehicle::GetAvailableSeatCount() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Vehicle::CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
float inx = x, iny = y, inz = z;
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(GetBase()->GetOrientation() + *o);
|
||||
|
||||
x = GetBase()->GetPositionX() + inx * std::cos(GetBase()->GetOrientation()) - iny * std::sin(GetBase()->GetOrientation());
|
||||
y = GetBase()->GetPositionY() + iny * std::cos(GetBase()->GetOrientation()) + inx * std::sin(GetBase()->GetOrientation());
|
||||
z = GetBase()->GetPositionZ() + inz;
|
||||
}
|
||||
|
||||
void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(*o - GetBase()->GetOrientation());
|
||||
|
||||
z -= GetBase()->GetPositionZ();
|
||||
y -= GetBase()->GetPositionY(); // y = searchedY * std::cos(o) + searchedX * std::sin(o)
|
||||
x -= GetBase()->GetPositionX(); // x = searchedX * std::cos(o) + searchedY * std::sin(o + pi)
|
||||
float inx = x, iny = y;
|
||||
y = (iny - inx * std::tan(GetBase()->GetOrientation())) / (std::cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * std::tan(GetBase()->GetOrientation()));
|
||||
x = (inx + iny * std::tan(GetBase()->GetOrientation())) / (std::cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * std::tan(GetBase()->GetOrientation()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
|
||||
*
|
||||
|
||||
@@ -89,10 +89,20 @@ class Vehicle : public TransportBase
|
||||
void InitMovementInfoForBase();
|
||||
|
||||
/// This method transforms supplied transport offsets into global coordinates
|
||||
void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const;
|
||||
void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
TransportBase::CalculatePassengerPosition(x, y, z, o,
|
||||
GetBase()->GetPositionX(), GetBase()->GetPositionY(),
|
||||
GetBase()->GetPositionZ(), GetBase()->GetOrientation());
|
||||
}
|
||||
|
||||
/// This method transforms supplied global coordinates into local offsets
|
||||
void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const;
|
||||
void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
|
||||
{
|
||||
TransportBase::CalculatePassengerOffset(x, y, z, o,
|
||||
GetBase()->GetPositionX(), GetBase()->GetPositionY(),
|
||||
GetBase()->GetPositionZ(), GetBase()->GetOrientation());
|
||||
}
|
||||
|
||||
void RemovePendingEvent(VehicleJoinEvent* e);
|
||||
void RemovePendingEventsForSeat(int8 seatId);
|
||||
|
||||
@@ -105,6 +105,31 @@ public:
|
||||
|
||||
/// This method transforms supplied global coordinates into local offsets
|
||||
virtual void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) 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;
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(transO + *o);
|
||||
|
||||
x = transX + inx * std::cos(transO) - iny * std::sin(transO);
|
||||
y = transY + iny * std::cos(transO) + inx * std::sin(transO);
|
||||
z = transZ + inz;
|
||||
}
|
||||
|
||||
static void CalculatePassengerOffset(float& x, float& y, float& z, float* o, float transX, float transY, float transZ, float transO)
|
||||
{
|
||||
if (o)
|
||||
*o = Position::NormalizeOrientation(*o - transO);
|
||||
|
||||
z -= transZ;
|
||||
y -= transY; // y = searchedY * std::cos(o) + searchedX * std::sin(o)
|
||||
x -= transX; // x = searchedX * std::cos(o) + searchedY * std::sin(o + pi)
|
||||
float inx = x, iny = y;
|
||||
y = (iny - inx * std::tan(transO)) / (std::cos(transO) + std::sin(transO) * std::tan(transO));
|
||||
x = (inx + iny * std::tan(transO)) / (std::cos(transO) + std::sin(transO) * std::tan(transO));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -164,7 +164,6 @@ namespace Trinity
|
||||
template<class T> void Visit(GridRefManager<T> &m);
|
||||
void Visit(PlayerMapType &) { }
|
||||
void Visit(CorpseMapType &) { }
|
||||
void Visit(CreatureMapType &);
|
||||
};
|
||||
|
||||
// SEARCHERS & LIST SEARCHERS & WORKERS
|
||||
|
||||
@@ -38,13 +38,6 @@ inline void Trinity::VisibleNotifier::Visit(GridRefManager<T> &m)
|
||||
}
|
||||
}
|
||||
|
||||
inline void Trinity::ObjectUpdater::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (iter->GetSource()->IsInWorld())
|
||||
iter->GetSource()->Update(i_timeDiff);
|
||||
}
|
||||
|
||||
// SEARCHERS & LIST SEARCHERS & WORKERS
|
||||
|
||||
// WorldObject searchers & workers
|
||||
|
||||
@@ -2426,8 +2426,20 @@ void Map::RemoveAllObjectsInRemoveList()
|
||||
bool on = itr->second;
|
||||
i_objectsToSwitch.erase(itr);
|
||||
|
||||
if ((obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_GAMEOBJECT) && !obj->IsPermanentWorldObject())
|
||||
SwitchGridContainers(obj, on);
|
||||
if (!obj->IsPermanentWorldObject())
|
||||
{
|
||||
switch (obj->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
SwitchGridContainers<Creature>(obj->ToCreature(), on);
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
SwitchGridContainers<GameObject>(obj->ToGameObject(), on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TC_LOG_DEBUG(LOG_FILTER_MAPS, "Object remover 1 check.");
|
||||
|
||||
Reference in New Issue
Block a user