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:
Shauren
2013-11-02 13:22:14 +01:00
parent 8d15c4c743
commit 39175ac680
9 changed files with 94 additions and 113 deletions
+3 -39
View File
@@ -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)
*
+12 -2
View File
@@ -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
+14 -2
View File
@@ -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.");