Core/Creature: Implement FarTeleportTo (teleport to an other map)

Core/Transport: Cleanup and optimize transport and passenger handling
- Only transports will be active objects
  - Reduced cpu and memory usage
- Using FarTeleportTo for creature passengers at transport teleportation
  - Creatures won't be recreated on teleport

--HG--
branch : trunk
This commit is contained in:
linencloth
2010-10-24 02:55:50 +02:00
parent 153352aac0
commit 07fa1bcbdf
9 changed files with 72 additions and 108 deletions
-14
View File
@@ -965,22 +965,8 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
{
uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
if (tguid > 0)
{
WorldDatabase.PQuery("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
TransportCreatureProto *transportCreatureProto = new TransportCreatureProto;
transportCreatureProto->guid = tguid;
transportCreatureProto->npc_entry = id;
uint32 transportEntry = chr->GetTransport()->GetEntry();
transportCreatureProto->TransOffsetX = chr->GetTransOffsetX();
transportCreatureProto->TransOffsetY = chr->GetTransOffsetY();
transportCreatureProto->TransOffsetZ = chr->GetTransOffsetZ();
transportCreatureProto->TransOffsetO = chr->GetTransOffsetO();
transportCreatureProto->emote = 0;
sMapMgr.m_TransportNPCMap[transportEntry].insert(transportCreatureProto);
sMapMgr.m_TransportNPCs.insert(transportCreatureProto);
}
return true;
}
@@ -2454,3 +2454,20 @@ time_t Creature::GetLinkedCreatureRespawnTime() const
return 0;
}
void Creature::FarTeleportTo(Map* map, float X, float Y, float Z, float O)
{
InterruptNonMeleeSpells(true);
CombatStop();
ClearComboPointHolders();
DeleteThreatList();
GetMotionMaster()->Clear(false);
DestroyForNearbyPlayers();
RemoveFromWorld();
ResetMap();
SetMap(map);
AddToWorld();
SetPosition(X, Y, Z, O, true);
}
@@ -674,6 +674,8 @@ class Creature : public Unit, public GridObject<Creature>
void SetGUIDTransport(uint32 guid) { guid_transport=guid; }
uint32 GetGUIDTransport() { return guid_transport; }
void FarTeleportTo(Map* map, float X, float Y, float Z, float O);
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
@@ -108,12 +108,6 @@ void MapManager::LoadTransports()
t->SetMap(sMapMgr.CreateMap(mapid, t, 0));
t->AddToWorld();
for (TransportNPCSet::const_iterator i = m_TransportNPCMap[entry].begin(); i != m_TransportNPCMap[entry].end(); ++i)
{
TransportCreatureProto *proto = (*i);
t->AddNPCPassenger(proto->guid, proto->npc_entry, proto->TransOffsetX, proto->TransOffsetY, proto->TransOffsetZ, proto->TransOffsetO, proto->emote);
}
++count;
}
while (result->NextRow());
@@ -161,18 +155,23 @@ void MapManager::LoadTransportNPCs()
{
bar.step();
Field *fields = result->Fetch();
TransportCreatureProto *transportCreatureProto = new TransportCreatureProto;
transportCreatureProto->guid = fields[0].GetUInt32();
transportCreatureProto->npc_entry = fields[1].GetUInt32();
uint32 guid = fields[0].GetUInt32();
uint32 entry = fields[1].GetUInt32();
uint32 transportEntry = fields[2].GetUInt32();
transportCreatureProto->TransOffsetX = fields[3].GetFloat();
transportCreatureProto->TransOffsetY = fields[4].GetFloat();
transportCreatureProto->TransOffsetZ = fields[5].GetFloat();
transportCreatureProto->TransOffsetO = fields[6].GetFloat();
transportCreatureProto->emote = fields[7].GetUInt32();
float tX = fields[3].GetFloat();
float tY = fields[4].GetFloat();
float tZ = fields[5].GetFloat();
float tO = fields[6].GetFloat();
uint32 anim = fields[7].GetUInt32();
m_TransportNPCs.insert(transportCreatureProto);
m_TransportNPCMap[transportEntry].insert(transportCreatureProto);
for (MapManager::TransportSet::iterator itr = m_Transports.begin(); itr != m_Transports.end(); ++itr)
{
if ((*itr)->GetEntry() == transportEntry)
{
(*itr)->AddNPCPassenger(guid, entry, tX, tY, tZ, tO, anim);
break;
}
}
count++;
} while (result->NextRow());
@@ -187,14 +186,9 @@ Transport::Transport(uint32 period, uint32 script) : GameObject(), m_period(peri
Transport::~Transport()
{
std::set<uint64>::iterator it2;
for (std::set<uint64>::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
{
it2 = itr;
++itr;
if (Creature *npc = Creature::GetCreature(*this, *it2))
npc->AddObjectToRemoveList();
}
for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
(*(itr++))->ForcedDespawn();
m_NPCPassengerSet.clear();
m_WayPoints.clear();
@@ -242,6 +236,8 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa
if (dynflags)
SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));
setActive(true);
SetName(goinfo->name);
SetZoneScript();
@@ -513,18 +509,6 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
//we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
//player far teleport would try to create same instance, but we need it NOW for transport...
// Clear all NPCs on the transport
for (std::set<uint64>::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
{
std::set<uint64>::iterator it2 = itr;
++itr;
uint64 guid = (*it2);
if (Creature *npc = Creature::GetCreature(*this, guid))
npc->AddObjectToRemoveList();
}
m_NPCPassengerSet.clear();
RemoveFromWorld();
ResetMap();
Map * newMap = sMapMgr.CreateMap(newMapid, this, 0);
@@ -532,17 +516,18 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
ASSERT (GetMap());
AddToWorld();
setActive(true);
if (oldMap != newMap)
{
UpdateForMap(oldMap);
UpdateForMap(newMap);
}
for (std::set<TransportCreatureProto *>::const_iterator i = sMapMgr.m_TransportNPCMap[GetEntry()].begin(); i != sMapMgr.m_TransportNPCMap[GetEntry()].end(); ++i)
{
TransportCreatureProto *proto = (*i);
AddNPCPassenger(proto->guid, proto->npc_entry, proto->TransOffsetX, proto->TransOffsetY, proto->TransOffsetZ, proto->TransOffsetO, proto->emote);
}
for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end(); ++itr)
(*itr)->FarTeleportTo(newMap, x, y, z, (*itr)->GetOrientation());
UpdateNPCPositions();
}
bool Transport::AddPassenger(Player* passenger)
@@ -665,7 +650,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
Map* map = GetMap();
Creature* pCreature = new Creature;
if (!pCreature->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0))
if (!pCreature->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0))
{
delete pCreature;
return 0;
@@ -675,7 +660,6 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
pCreature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
pCreature->m_movementInfo.guid = GetGUID();
pCreature->m_movementInfo.t_pos.Relocate(x, y, z, o);
pCreature->setActive(true);
if (anim)
pCreature->SetUInt32Value(UNIT_NPC_EMOTESTATE, anim);
@@ -686,6 +670,8 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
z + GetPositionZ() ,
o + GetOrientation());
pCreature->SetHomePosition(pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), pCreature->GetOrientation());
if(!pCreature->IsPositionValid())
{
sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
@@ -693,13 +679,12 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
return 0;
}
pCreature->AIM_Initialize();
map->Add(pCreature);
m_NPCPassengerSet.insert(pCreature->GetGUID());
m_NPCPassengerSet.insert(pCreature);
if (tguid == 0)
{
currenttguid++;
++currenttguid;
tguid = currenttguid;
}
else
@@ -723,30 +708,17 @@ void Transport::UpdatePosition(MovementInfo* mi)
void Transport::UpdateNPCPositions()
{
if (m_NPCPassengerSet.size() > 0)
// We update the positions of all NPCs
for(CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
{
// We update the positions of all NPCs
for(std::set<uint64>::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
{
std::set<uint64>::iterator it2 = itr;
++itr;
Creature* npc = *(itr++);
uint64 guid = (*it2);
if (Creature* npc = Creature::GetCreature(*this, guid))
{
float x, y, z, o;
o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation;
x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI));
y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation()));
z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ;
npc->SetPosition(x, y, z,o);
npc->SetHomePosition(x,y,z,o);
}
else
{
m_NPCPassengerSet.erase(guid);
continue;
}
}
float x, y, z, o;
o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation;
x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI));
y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation()));
z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ;
npc->SetHomePosition(x, y, z, o);
GetMap()->CreatureRelocation(npc, x, y, z, o);
}
}
+4 -13
View File
@@ -25,18 +25,6 @@
#include <set>
#include <string>
struct TransportCreatureProto
{
uint32 guid;
uint32 transport_entry;
uint32 npc_entry;
float TransOffsetX;
float TransOffsetY;
float TransOffsetZ;
float TransOffsetO;
uint32 emote;
};
class Transport : public GameObject
{
public:
@@ -49,10 +37,13 @@ class Transport : public GameObject
bool AddPassenger(Player* passenger);
bool RemovePassenger(Player* passenger);
void RemovePassenger(Creature* passenger) { m_NPCPassengerSet.erase(passenger); }
typedef std::set<Player*> PlayerSet;
PlayerSet const& GetPassengers() const { return m_passengers; }
mutable std::set<uint64> m_NPCPassengerSet;
typedef std::set<Creature*> CreatureSet;
CreatureSet m_NPCPassengerSet;
uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);
void UpdatePosition(MovementInfo *mi);
void UpdateNPCPositions();
+4
View File
@@ -13564,6 +13564,10 @@ void Unit::CleanupsBeforeDelete(bool finalCleanup)
DeleteThreatList();
getHostileRefManager().setOnlineOfflineState(false);
GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
if (Creature* thisCreature = ToCreature())
if (GetTransport())
GetTransport()->RemovePassenger(thisCreature);
}
void Unit::UpdateCharmAI()
-3
View File
@@ -53,9 +53,6 @@ MapManager::~MapManager()
delete *i;
}
for (TransportNPCSet::iterator i = m_TransportNPCs.begin(); i != m_TransportNPCs.end(); ++i)
delete *i;
Map::DeleteStateMachine();
}
-5
View File
@@ -132,11 +132,6 @@ class MapManager
typedef std::map<uint32, TransportSet> TransportMap;
TransportMap m_TransportsByMap;
typedef std::set<TransportCreatureProto *> TransportNPCSet;
TransportNPCSet m_TransportNPCs;
typedef std::map<uint32, TransportNPCSet> TransportNPCMap;
TransportNPCMap m_TransportNPCMap;
bool CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck = false);
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
void InitMaxInstanceId();
+3 -3
View File
@@ -1711,12 +1711,12 @@ void World::SetInitialWorldSettings()
sLog.outString("Starting Outdoor PvP System");
sOutdoorPvPMgr.InitOutdoorPvP();
sLog.outString("Loading Transport NPCs...");
sMapMgr.LoadTransportNPCs();
sLog.outString("Loading Transports...");
sMapMgr.LoadTransports();
sLog.outString("Loading Transport NPCs...");
sMapMgr.LoadTransportNPCs();
sLog.outString("Deleting expired bans...");
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");