aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsilinoron <none@none>2010-07-30 21:54:46 -0700
committersilinoron <none@none>2010-07-30 21:54:46 -0700
commit71b1c781e3d05bf208c4b0886a1c8f0f474d6a10 (patch)
treeeb0c5a10bcb60ed83921f23d1f5526484f268595 /src
parentb3bca2743ef2312d443055e9389dc9f999215563 (diff)
Add basic support for NPCs on transports; DB data required.
Currently no support for combat while the transport is in motion. Based on a patch by Socolin. Fixes issue #168 --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Chat/Commands/Level2.cpp25
-rw-r--r--src/server/game/Chat/Commands/Level3.cpp5
-rw-r--r--src/server/game/Entities/Creature/Creature.h4
-rw-r--r--src/server/game/Entities/Object/Object.cpp19
-rw-r--r--src/server/game/Entities/Object/Object.h46
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp211
-rw-r--r--src/server/game/Entities/Transport/Transport.h19
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.h44
-rw-r--r--src/server/game/Maps/MapManager.cpp3
-rw-r--r--src/server/game/Maps/MapManager.h7
-rw-r--r--src/server/game/Server/WorldSession.cpp5
-rw-r--r--src/server/game/World/World.cpp4
14 files changed, 308 insertions, 88 deletions
diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp
index 26b754e23d2..c66311f1277 100644
--- a/src/server/game/Chat/Commands/Level2.cpp
+++ b/src/server/game/Chat/Commands/Level2.cpp
@@ -42,7 +42,7 @@
#include <map>
#include "GlobalEvents.h"
#include "OutdoorPvPMgr.h"
-
+#include "Transport.h"
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
#include "CreatureGroups.h"
@@ -1005,6 +1005,29 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
float o = chr->GetOrientation();
Map *map = chr->GetMap();
+ if (chr->GetTransport())
+ {
+ 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;
+ }
+
Creature* pCreature = new Creature;
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
{
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index fb68581ad89..0d54e4f77ae 100644
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -57,6 +57,7 @@
#include "DBCEnums.h"
#include "ConditionMgr.h"
#include "DisableMgr.h"
+#include "Transport.h"
bool ChatHandler::HandleAHBotOptionsCommand(const char *args)
{
@@ -4801,6 +4802,10 @@ bool ChatHandler::HandleNpcPlayEmoteCommand(const char *args)
return false;
}
+ if (target->GetTransport())
+ if (target->GetGUIDTransport())
+ WorldDatabase.PQuery("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport());
+
target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
return true;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 203106f635e..e31c8576e81 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -667,6 +667,8 @@ class Creature : public Unit, public GridObject<Creature>
float m_SightDistance, m_CombatDistance;
+ void SetGUIDTransport(uint32 guid) { guid_transport=guid; }
+ uint32 GetGUIDTransport() { return guid_transport; }
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);
@@ -714,7 +716,7 @@ class Creature : public Unit, public GridObject<Creature>
CreatureData const* m_creatureData;
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
-
+ uint32 guid_transport;
private:
//WaypointMovementGenerator vars
uint32 m_waypointID;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index f1460cc2fd0..b472a08a3ac 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1151,6 +1151,7 @@ WorldObject::WorldObject()
, m_name("")
, m_notifyflags(0), m_executed_notifies(0)
{
+ m_transport = NULL;
}
void WorldObject::SetWorldObject(bool on)
@@ -1235,6 +1236,22 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const
bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
{
+ float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float maxdist = dist2compare + sizefactor;
+
+ if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == m_transport->GetGUIDLow())
+ {
+ float dtx = m_movementInfo.t_x - obj->m_movementInfo.t_x;
+ float dty = m_movementInfo.t_y - obj->m_movementInfo.t_y;
+ float disttsq = dtx * dtx + dty * dty;
+ if (is3D)
+ {
+ float dtz = m_movementInfo.t_z - obj->m_movementInfo.t_z;
+ disttsq += dtz * dtz;
+ }
+ return disttsq < (maxdist * maxdist);
+ }
+
float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY();
float distsq = dx*dx + dy*dy;
@@ -1243,8 +1260,6 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
float dz = GetPositionZ() - obj->GetPositionZ();
distsq += dz*dz;
}
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
- float maxdist = dist2compare + sizefactor;
return distsq < maxdist * maxdist;
}
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 63f1a1eb487..61a6ef516b3 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -115,9 +115,46 @@ class Vehicle;
class CreatureAI;
class ZoneScript;
class Unit;
+class Transport;
typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
+struct MovementInfo
+{
+ // common
+ uint64 guid;
+ uint32 flags;
+ uint16 unk1;
+ uint32 time;
+ float x, y, z, o;
+ // transport
+ uint64 t_guid;
+ float t_x, t_y, t_z, t_o;
+ uint32 t_time;
+ int8 t_seat;
+ // swimming and unknown
+ float s_pitch;
+ // last fall time
+ uint32 fallTime;
+ // jumping
+ float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed;
+ // spline
+ float u_unk1;
+
+ MovementInfo()
+ {
+ flags = 0;
+ time = t_time = fallTime = 0;
+ unk1 = 0;
+ x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
+ t_guid = 0;
+ }
+
+ uint32 GetMovementFlags() { return flags; }
+ void AddMovementFlag(uint32 flag) { flags |= flag; }
+ bool HasMovementFlag(uint32 flag) const { return flags & flag; }
+};
+
class Object
{
public:
@@ -696,12 +733,21 @@ class WorldObject : public Object, public WorldLocation
bool m_isWorldObject;
uint32 LastUsedScriptID;
+
+ // Transports
+ Transport *GetTransport() const { return m_transport; }
+ void SetTransport(Transport *t) { m_transport = t; }
+
+ MovementInfo m_movementInfo;
protected:
explicit WorldObject();
std::string m_name;
bool m_isActive;
ZoneScript *m_zoneScript;
+ // transports
+ Transport *m_transport;
+
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b29e753f4ec..a5c4dc5570f 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -16093,7 +16093,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder)
GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o) ||
// transport size limited
- m_movementInfo.t_x > 50 || m_movementInfo.t_y > 50 || m_movementInfo.t_z > 50)
+ m_movementInfo.t_x > 250 || m_movementInfo.t_y > 250 || m_movementInfo.t_z > 250)
{
sLog.outError("Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 53272a1eda1..715e0a309b5 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -108,7 +108,12 @@ void MapManager::LoadTransports()
//If we someday decide to use the grid to track transports, here:
t->SetMap(sMapMgr.CreateMap(mapid, t, 0));
- //t->GetMap()->Add<GameObject>((GameObject *)t);
+ 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());
@@ -132,6 +137,48 @@ void MapManager::LoadTransports()
}
}
+void MapManager::LoadTransportNPCs()
+{
+ // Spawn NPCs linked to the transport
+ // 0 1 2 3 4 5 6 7
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO, emote FROM creature_transport");
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u transport NPCs.", count);
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ TransportCreatureProto *transportCreatureProto = new TransportCreatureProto;
+ transportCreatureProto->guid = fields[0].GetUInt32();
+ transportCreatureProto->npc_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();
+
+ m_TransportNPCs.insert(transportCreatureProto);
+ m_TransportNPCMap[transportEntry].insert(transportCreatureProto);
+
+ count++;
+ } while (result->NextRow());
+ sLog.outString();
+ sLog.outString(">> Loaded %u transport npcs", count);
+}
+
Transport::Transport() : GameObject()
{
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_ROTATION);
@@ -443,16 +490,22 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
plr->ResurrectPlayer(1.0);
}
plr->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT);
-
- //WorldPacket data(SMSG_811, 4);
- //data << uint32(0);
- //plr->GetSession()->SendPacket(&data);
}
//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...
- //correct me if I'm wrong O.o
- //yes, you're right
+
+ // 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();
ResetMap();
Map * newMap = sMapMgr.CreateMap(newMapid, this, 0);
@@ -464,6 +517,12 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
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);
+ }
}
bool Transport::AddPassenger(Player* passenger)
@@ -502,37 +561,9 @@ void Transport::Update(uint32 /*p_time*/)
}
else
{
- Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z);
- }
-/*
- if (m_curr->second.delayed)
- {
- switch (GetEntry())
- {
- case 176495:
- case 164871:
- case 175080:
- SendPlaySound(11804, false); break; // ZeppelinDocked
- case 20808:
- case 181646:
- case 176231:
- case 176244:
- case 176310:
- case 177233:
- SendPlaySound(5495, false);break; // BoatDockingWarning
- default:
- SendPlaySound(5154, false); break; // ShipDocked
- }
- }
-*/
- /*
- for (PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();)
- {
- PlayerSet::const_iterator it2 = itr;
- ++itr;
- //(*it2)->SetPosition(m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO());
+ Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z, GetAngle(m_next->second.x,m_next->second.y) + 3.1415926f);
+ UpdateNPCPositions(); // COME BACK MARKER
}
- */
m_nextNodeTime = m_curr->first;
@@ -585,3 +616,109 @@ void Transport::DoEventIfAny(WayPointMap::value_type const& node, bool departure
GetMap()->ScriptsStart(sEventScripts, eventid, this, this);
}
}
+
+void Transport::BuildStartMovePacket(Map const* targetMap)
+{
+ SetByteValue(GAMEOBJECT_FLAGS ,0,41);
+ SetByteValue(GAMEOBJECT_BYTES_1, 0, GO_STATE_ACTIVE);
+ UpdateForMap(targetMap);
+}
+
+void Transport::BuildStopMovePacket(Map const* targetMap)
+{
+ SetByteValue(GAMEOBJECT_FLAGS ,0,40);
+ UpdateForMap(targetMap);
+}
+
+uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim)
+{
+ Map* map = GetMap();
+ Creature* pCreature = new Creature;
+
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), this->GetPhaseMask(), entry, 0, (uint32)(this->GetGOInfo()->faction), 0, 0, 0, 0))
+ {
+ delete pCreature;
+ return 0;
+ }
+
+ pCreature->SetTransport(this);
+ pCreature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ pCreature->m_movementInfo.guid = GetGUID();
+ pCreature->m_movementInfo.t_x = x;
+ pCreature->m_movementInfo.t_y = y;
+ pCreature->m_movementInfo.t_z = z;
+ pCreature->m_movementInfo.t_o = o;
+ pCreature->setActive(true);
+
+ if (anim > 0)
+ pCreature->SetUInt32Value(UNIT_NPC_EMOTESTATE,anim);
+
+ pCreature->Relocate(
+ GetPositionX() + (x * cos(GetOrientation()) + y * sin(GetOrientation() + 3.14159f)),
+ GetPositionY() + (y * cos(GetOrientation()) + x * sin(GetOrientation())),
+ z + GetPositionZ() ,
+ o + 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());
+ delete pCreature;
+ return 0;
+ }
+
+ pCreature->AIM_Initialize();
+
+ map->Add(pCreature);
+ m_NPCPassengerSet.insert(pCreature->GetGUID());
+ if (tguid == 0)
+ {
+ currenttguid++;
+ tguid = currenttguid;
+ }
+ else
+ currenttguid = std::max(tguid,currenttguid);
+
+ pCreature->SetGUIDTransport(tguid);
+ return tguid;
+}
+
+void Transport::UpdatePosition(MovementInfo* mi)
+{
+ float transport_o = mi->o - mi->t_o;
+ float transport_x = mi->x - (mi->t_x*cos(transport_o) - mi->t_y*sin(transport_o));
+ float transport_y = mi->y - (mi->t_y*cos(transport_o) + mi->t_x*sin(transport_o));
+ float transport_z = mi->z - mi->t_z;
+
+ Relocate(transport_x,transport_y,transport_z,transport_o);
+ UpdateNPCPositions();
+}
+
+void Transport::UpdateNPCPositions()
+{
+ if (m_NPCPassengerSet.size() > 0)
+ {
+ // 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;
+
+ uint64 guid = (*it2);
+ if (Creature* npc = Creature::GetCreature(*this, guid))
+ {
+ float x, y, z, o;
+ o = GetOrientation() + npc->m_movementInfo.t_o;
+ x = GetPositionX() + (npc->m_movementInfo.t_x * cos(GetOrientation()) + npc->m_movementInfo.t_y * sin(GetOrientation() + 3.14159f));
+ y = GetPositionY() + (npc->m_movementInfo.t_y * cos(GetOrientation()) + npc->m_movementInfo.t_x * sin(GetOrientation()));
+ z = GetPositionZ() + npc->m_movementInfo.t_z;
+ npc->SetPosition(x, y, z,o);
+ npc->SetHomePosition(x,y,z,o);
+ }
+ else
+ {
+ m_NPCPassengerSet.erase(guid);
+ continue;
+ }
+ }
+ }
+}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 7b93d3e28a8..aa8328afed4 100644
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -27,6 +27,18 @@
#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:
@@ -41,6 +53,12 @@ class Transport : public GameObject
typedef std::set<Player*> PlayerSet;
PlayerSet const& GetPassengers() const { return m_passengers; }
+ mutable std::set<uint64> 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();
+ void BuildStartMovePacket(Map const *targetMap);
+ void BuildStopMovePacket(Map const *targetMap);
private:
struct WayPoint
{
@@ -70,6 +88,7 @@ class Transport : public GameObject
PlayerSet m_passengers;
+ uint32 currenttguid;
public:
WayPointMap m_WayPoints;
uint32 m_nextNodeTime;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 5c8a89ffac5..286d7425232 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -96,7 +96,7 @@ static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostileRefManager(this)
, IsAIEnabled(false), NeedChangeAI(false)
-, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_vehicle(NULL), m_transport(NULL)
+, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_vehicle(NULL)
, m_ControlledByPlayer(false), m_procDeep(0), m_unitTypeMask(UNIT_MASK_NONE), m_vehicleKit(NULL)
, m_movedPlayer(NULL)
{
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 6ab3bf38101..63b8c9db058 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -722,42 +722,6 @@ enum MonsterMovementFlags
};
*/
-struct MovementInfo
-{
- // common
- uint64 guid;
- uint32 flags;
- uint16 unk1;
- uint32 time;
- float x, y, z, o;
- // transport
- uint64 t_guid;
- float t_x, t_y, t_z, t_o;
- uint32 t_time;
- int8 t_seat;
- // swimming and unknown
- float s_pitch;
- // last fall time
- uint32 fallTime;
- // jumping
- float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed;
- // spline
- float u_unk1;
-
- MovementInfo()
- {
- flags = 0;
- time = t_time = fallTime = 0;
- unk1 = 0;
- x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
- t_guid = 0;
- }
-
- uint32 GetMovementFlags() { return flags; }
- void AddMovementFlag(uint32 flag) { flags |= flag; }
- bool HasMovementFlag(uint32 flag) const { return flags & flag; }
-};
-
enum UnitTypeMask
{
UNIT_MASK_NONE = 0x00000000,
@@ -1936,7 +1900,6 @@ class Unit : public WorldObject
Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; }
bool IsAIEnabled, NeedChangeAI;
- MovementInfo m_movementInfo;
bool CreateVehicleKit(uint32 id);
void RemoveVehicleKit();
Vehicle *GetVehicleKit()const { return m_vehicleKit; }
@@ -1959,10 +1922,6 @@ class Unit : public WorldObject
void ExitVehicle();
void ChangeSeat(int8 seatId, bool next = true);
- // Transports
- Transport * GetTransport() const { return m_transport; }
- void SetTransport(Transport * t) { m_transport = t; }
-
void BuildMovementPacket(ByteBuffer *data) const;
bool isMoving() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MOVING); }
@@ -1988,9 +1947,6 @@ class Unit : public WorldObject
UnitAI *i_AI, *i_disabledAI;
- // Transports
- Transport * m_transport;
-
void _UpdateSpells(uint32 time);
void _DeleteRemovedAuras();
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index bb95516dfca..f93d538f6a1 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -52,6 +52,9 @@ MapManager::~MapManager()
for (TransportSet::iterator i = m_Transports.begin(); i != m_Transports.end(); ++i)
delete *i;
+ for (TransportNPCSet::iterator i = m_TransportNPCs.begin(); i != m_TransportNPCs.end(); ++i)
+ delete *i;
+
Map::DeleteStateMachine();
}
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index 47cb9d2f795..8be44721ae9 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -30,6 +30,7 @@
#include "MapUpdater.h"
class Transport;
+struct TransportCreatureProto;
class MapManager
{
@@ -125,6 +126,7 @@ class MapManager
void DoDelayedMovesAndRemoves();
void LoadTransports();
+ void LoadTransportNPCs();
typedef std::set<Transport *> TransportSet;
TransportSet m_Transports;
@@ -132,6 +134,11 @@ 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);
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 6de0cb27381..8dbe54a3b98 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -43,6 +43,7 @@
#include "zlib.h"
#include "ScriptMgr.h"
#include "LFGMgr.h"
+#include "Transport.h"
/// WorldSession constructor
WorldSession::WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
@@ -729,6 +730,10 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
data >> mi->t_o;
data >> mi->t_time;
data >> mi->t_seat;
+
+ if(mi->x != mi->t_x)
+ if(GetPlayer()->GetTransport())
+ GetPlayer()->GetTransport()->UpdatePosition(mi);
}
if ((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->unk1 & 0x20))
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 6cedfeb2910..25ebbef7106 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1704,7 +1704,9 @@ void World::SetInitialWorldSettings()
sLog.outString("Starting Outdoor PvP System");
sOutdoorPvPMgr.InitOutdoorPvP();
- //Not sure if this can be moved up in the sequence (with static data loading) as it uses MapManager
+ sLog.outString("Loading Transport NPCs...");
+ sMapMgr.LoadTransportNPCs();
+
sLog.outString("Loading Transports...");
sMapMgr.LoadTransports();