aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Chat.cpp2
-rw-r--r--src/game/Chat.h2
-rw-r--r--src/game/Debugcmds.cpp51
-rw-r--r--src/game/Map.cpp12
-rw-r--r--src/game/MiscHandler.cpp3
-rw-r--r--src/game/MovementHandler.cpp28
-rw-r--r--src/game/Object.cpp69
-rw-r--r--src/game/Object.h8
-rw-r--r--src/game/Opcodes.cpp4
-rw-r--r--src/game/Player.cpp109
-rw-r--r--src/game/Player.h43
-rw-r--r--src/game/SpellEffects.cpp3
-rw-r--r--src/game/Unit.cpp5
-rw-r--r--src/game/Unit.h39
-rw-r--r--src/game/Vehicle.cpp181
-rw-r--r--src/game/Vehicle.h22
-rw-r--r--src/game/WorldSession.h3
17 files changed, 393 insertions, 191 deletions
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 1f66482ac9f..9a01742abc8 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -150,6 +150,8 @@ ChatCommand * ChatHandler::getCommandTable()
{ "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
{ "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL },
{ "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL },
+ { "setvid", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetVehicleId, "", NULL },
+ { "entervehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugEnterVehicle, "", NULL },
{ "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateWorldStateCommand, "", NULL },
{ "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdate, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
diff --git a/src/game/Chat.h b/src/game/Chat.h
index b40dd49a2a9..3cc9aedac6e 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -131,7 +131,9 @@ class ChatHandler
bool HandleDebugMod32Value(const char* args);
bool HandleDebugSetValue(const char* args);
bool HandleDebugSetItemFlagCommand(const char * args);
+ bool HandleDebugSetVehicleId(const char * args);
bool HandleDebugSpawnVehicle(const char * args);
+ bool HandleDebugEnterVehicle(const char * args);
bool HandleDebugUpdate(const char* args);
bool HandleDebugUpdateWorldStateCommand(const char* args);
diff --git a/src/game/Debugcmds.cpp b/src/game/Debugcmds.cpp
index e50ca1677de..940edeb74c2 100644
--- a/src/game/Debugcmds.cpp
+++ b/src/game/Debugcmds.cpp
@@ -32,6 +32,10 @@
#include "BattleGroundMgr.h"
#include <fstream>
#include "ObjectMgr.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
{
@@ -673,6 +677,53 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
return true;
}
+bool ChatHandler::HandleDebugSetVehicleId(const char *args)
+{
+ Unit* target = getSelectedUnit();
+ if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
+ return false;
+
+ if(!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if(!i)
+ return false;
+
+ uint32 id = (uint32)atoi(i);
+ ((Vehicle*)target)->SetVehicleId(id);
+ target->SendUpdateObjectToAllExcept(NULL);
+ PSendSysMessage("Vehicle id set to %u", id);
+ return true;
+}
+
+bool ChatHandler::HandleDebugEnterVehicle(const char * args)
+{
+ Unit* target = getSelectedUnit();
+ if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
+ return false;
+
+ if(!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if(!i)
+ return false;
+
+ uint32 entry = (uint32)atoi(i);
+ Creature *passenger = NULL;
+ Trinity::AllCreaturesOfEntryInRange check(m_session->GetPlayer(), entry, 20.0f);
+ Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_session->GetPlayer(), passenger, check);
+ m_session->GetPlayer()->VisitNearbyObject(20.0f, searcher);
+ if(!passenger || passenger == target)
+ return false;
+
+ ((Vehicle*)target)->AddPassenger(passenger);
+
+ PSendSysMessage("Creature entered vehicle");
+ return true;
+}
+
bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
{
if(!args)
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index d53c617e374..c6c74a74493 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -35,6 +35,7 @@
#include "ScriptCalls.h"
#include "Group.h"
#include "MapRefManager.h"
+#include "Vehicle.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
@@ -962,6 +963,17 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
creature->Relocate(x, y, z, ang);
AddUnitToNotify(creature);
}
+
+ if(creature->isVehicle())
+ {
+ for(SeatMap::iterator itr = ((Vehicle*)creature)->m_Seats.begin(); itr != ((Vehicle*)creature)->m_Seats.end(); ++itr)
+ if(itr->second.passenger)
+ if(itr->second.passenger->GetTypeId() == TYPEID_PLAYER)
+ PlayerRelocation((Player*)itr->second.passenger, x, y, z, ang);
+ else
+ CreatureRelocation((Creature*)itr->second.passenger, x, y, z, ang);
+ }
+
assert(CheckGridIntegrity(creature,true));
}
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 0ced3a57201..ca7a9effbfb 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -44,6 +44,7 @@
#include "Pet.h"
#include "SocialMgr.h"
#include "CellImpl.h"
+#include "Vehicle.h"
void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ )
{
@@ -1695,7 +1696,7 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
return;
}
- _player->EnterVehicle(vehicle);
+ vehicle->AddPassenger(_player);
}
void WorldSession::HandleInspectAchievements( WorldPacket & recv_data )
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 64c4fecdb53..50152de4e97 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -338,9 +338,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
if(Map *map = mover->GetMap())
{
- //if(GetPlayer()->m_seer != mover)
- if(((Creature*)mover)->isVehicle())
- map->PlayerRelocation(GetPlayer(), movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
}
mover->SetUnitMovementFlags(movementInfo.flags);
@@ -482,10 +479,33 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
// using charm guid, because we don't have vehicle guid...
if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
{
- _player->ExitVehicle(vehicle);
+ vehicle->RemovePassenger(_player);
}
}
+void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
+ recv_data.hexlike();
+ uint32 a;
+ uint16 b;
+ uint16 c;
+ uint32 d,e,f,g,h,i,j,k;
+ int8 seat;
+ recv_data >> a >> b >> c;
+ recv_data >> d >> e >> f >> g >> h >> i >> j >> k;
+ recv_data >> seat;
+ //sLog.outError("change seat %u %u %u %u %u %u %u %u %u %u %u %u", a, b,c,d,e,f,g,h,i,j,k,seat);
+}
+
+void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
+ recv_data.hexlike();
+ if(GetPlayer()->m_Vehicle)
+ GetPlayer()->m_Vehicle->RemovePassenger(GetPlayer());
+}
+
void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/)
{
//sLog.outDebug("WORLD: Recvd CMSG_MOUNTSPECIAL_ANIM");
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index c22d00628b2..3c776b6fdfa 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -277,7 +277,10 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
case TYPEID_UNIT:
{
flags2 = ((Unit*)this)->GetUnitMovementFlags();
- flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
+ if(((Unit*)this)->m_Vehicle)
+ flags2 |= MOVEMENTFLAG_ONTRANSPORT;
+ else
+ flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
flags2 &= ~MOVEMENTFLAG_SPLINE2;
}
break;
@@ -285,7 +288,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
{
flags2 = ((Player*)this)->GetUnitMovementFlags();
- if(((Player*)this)->GetTransport() || ((Player*)this)->hasUnitState(UNIT_STAT_ONVEHICLE))
+ if(((Player*)this)->GetTransport() || ((Player*)this)->m_Vehicle)
flags2 |= MOVEMENTFLAG_ONTRANSPORT;
else
flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
@@ -333,20 +336,16 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
// 0x00000200
if(flags2 & MOVEMENTFLAG_ONTRANSPORT)
{
- if(GetTypeId() == TYPEID_PLAYER)
- {
- if(((Player*)this)->hasUnitState(UNIT_STAT_ONVEHICLE))
- *data << (uint64)((Player*)this)->GetCharmGUID();
- else
- *data << (uint64)((Player*)this)->GetTransport()->GetGUID();
- *data << (float)((Player*)this)->GetTransOffsetX();
- *data << (float)((Player*)this)->GetTransOffsetY();
- *data << (float)((Player*)this)->GetTransOffsetZ();
- *data << (float)((Player*)this)->GetTransOffsetO();
- *data << (uint32)((Player*)this)->GetTransTime();
- *data << (int8)((Player*)this)->GetTransSeat();
- }
- //TrinIty currently not have support for other than player on transport
+ if(((Unit*)this)->m_Vehicle)
+ *data << (uint64)((Unit*)this)->m_Vehicle->GetGUID();
+ else
+ *data << (uint64)((Player*)this)->GetTransport()->GetGUID();
+ *data << (float)((Unit*)this)->GetTransOffsetX();
+ *data << (float)((Unit*)this)->GetTransOffsetY();
+ *data << (float)((Unit*)this)->GetTransOffsetZ();
+ *data << (float)((Unit*)this)->GetTransOffsetO();
+ *data << (uint32)((Unit*)this)->GetTransTime();
+ *data << (int8)((Unit*)this)->GetTransSeat();
}
// 0x02200000
@@ -559,7 +558,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
// 0x80
if(flags & UPDATEFLAG_VEHICLE) // unused for now
{
- *data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id
+ *data << uint32(((Vehicle*)this)->GetVehicleInfo()->m_ID); // vehicle id
*data << float(0); // facing adjustment
}
}
@@ -1612,15 +1611,16 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const
*data << m_positionY;
*data << m_positionZ;
*data << m_orientation;
- if(GetTypeId() == TYPEID_PLAYER && ((Unit*)this)->hasUnitState(UNIT_STAT_ONVEHICLE))
+ if(((Unit*)this)->m_Vehicle)
{
- *data << uint64(((Unit*)this)->GetCharmGUID());
- *data << float(((Player*)this)->GetTransOffsetX());
- *data << float(((Player*)this)->GetTransOffsetY());
- *data << float(((Player*)this)->GetTransOffsetZ());
- *data << float(((Player*)this)->GetTransOffsetO());
- *data << uint32(((Player*)this)->GetTransTime());
- *data << uint8(((Player*)this)->GetTransSeat());
+ *data << uint64(((Unit*)this)->m_Vehicle->GetGUID());
+ *data << float (((Unit*)this)->GetTransOffsetX());
+ *data << float (((Unit*)this)->GetTransOffsetY());
+ *data << float (((Unit*)this)->GetTransOffsetZ());
+ *data << float (((Unit*)this)->GetTransOffsetO());
+ *data << uint32(((Unit*)this)->GetTransTime());
+ *data << uint8 (((Unit*)this)->GetTransSeat());
+ sLog.outError("heart seat is %u", ((Unit*)this)->GetTransTime());
}
*data << uint32(0); //fall time
}
@@ -1641,15 +1641,16 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float
*data << y;
*data << z;
*data << ang;
- if(GetTypeId() == TYPEID_PLAYER && ((Unit*)this)->hasUnitState(UNIT_STAT_ONVEHICLE))
- {
- *data << uint64(((Unit*)this)->GetCharmGUID());
- *data << float(((Player*)this)->GetTransOffsetX());
- *data << float(((Player*)this)->GetTransOffsetY());
- *data << float(((Player*)this)->GetTransOffsetZ());
- *data << float(((Player*)this)->GetTransOffsetO());
- *data << uint32(((Player*)this)->GetTransTime());
- *data << uint8(((Player*)this)->GetTransSeat());
+ if(((Unit*)this)->m_Vehicle)
+ {
+ *data << uint64(((Unit*)this)->m_Vehicle->GetGUID());
+ *data << float (((Unit*)this)->GetTransOffsetX());
+ *data << float (((Unit*)this)->GetTransOffsetY());
+ *data << float (((Unit*)this)->GetTransOffsetZ());
+ *data << float (((Unit*)this)->GetTransOffsetO());
+ *data << uint32(((Unit*)this)->GetTransTime());
+ *data << uint8 (((Unit*)this)->GetTransSeat());
+ sLog.outError("seat is %u", ((Unit*)this)->GetTransTime());
}
*data << uint32(0);
}
diff --git a/src/game/Object.h b/src/game/Object.h
index d46abd6d263..83c2afbb880 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -372,6 +372,14 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
+ void Relocate(WorldObject *obj)
+ {
+ m_positionX = obj->GetPositionX();
+ m_positionY = obj->GetPositionY();
+ m_positionZ = obj->GetPositionZ();
+ m_orientation = obj->GetOrientation();
+ }
+
void Relocate(float x, float y, float z, float orientation)
{
m_positionX = x;
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 638d54236d1..5daa369a743 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -1170,7 +1170,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
/*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleExit },
/*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
@@ -1207,7 +1207,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
/*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 96548d84893..c8317e96148 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -16492,7 +16492,7 @@ void Player::StopCastingCharm()
if(((Creature*)charm)->isPet() && ((Pet*)charm)->getPetType() == POSSESSED_PET)
((Pet*)charm)->Remove(PET_SAVE_AS_DELETED);
else if(((Creature*)charm)->isVehicle())
- ExitVehicle((Vehicle*)charm);
+ ((Vehicle*)charm)->RemovePassenger(this);
}
if(GetCharmGUID())
{
@@ -16707,8 +16707,8 @@ void Player::PossessSpellInitialize()
void Player::VehicleSpellInitialize()
{
- Unit* charm = GetCharm();
- if(!charm || charm->GetTypeId() != TYPEID_UNIT)
+ Unit* charm = m_Vehicle;
+ if(!charm)
return;
WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1);
@@ -16808,9 +16808,14 @@ void Player::CharmSpellInitialize()
uint8 count = 0;
data << uint8(count); // cooldowns count
- data.hexlike();
-
+ GetSession()->SendPacket(&data);
+}
+void Player::SendRemoveControlBar()
+{
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
GetSession()->SendPacket(&data);
}
@@ -19559,7 +19564,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
return;
}
- if(target->isType(TYPEMASK_UNIT))
+ if(target->isType(TYPEMASK_UNIT) && !m_Vehicle)
((Unit*)target)->AddPlayerToVision(this);
}
else
@@ -19572,7 +19577,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
return;
}
- if(target->isType(TYPEMASK_UNIT))
+ if(target->isType(TYPEMASK_UNIT) && !m_Vehicle)
((Unit*)target)->RemovePlayerFromVision(this);
//must immediately set seer back otherwise may crash
@@ -19673,96 +19678,6 @@ void Player::InitGlyphsForLevel()
SetUInt32Value(PLAYER_GLYPHS_ENABLED, value);
}
-void Player::EnterVehicle(Vehicle *vehicle)
-{
- sLog.outDebug("Player %s enter vehicle entry %u id %u dbguid %u", GetName(), vehicle->GetEntry(), vehicle->GetVehicleId(), vehicle->GetDBTableGUIDLow());
-
- if(vehicle->GetCharmerGUID())
- return;
-
- VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId());
- if(!ve)
- return;
-
- VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]);
- if(!veSeat)
- return;
-
- vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- vehicle->setFaction(getFaction());
-
- StopCastingCharm();
- StopCastingBindSight();
-
- SetCharm(vehicle, true);
- SetViewpoint(vehicle, true);
- SetMover(vehicle);
- SetClientControl(vehicle, 1); // redirect controls to vehicle
-
- addUnitState(UNIT_STAT_ONVEHICLE);
- Relocate(vehicle->GetPositionX(), vehicle->GetPositionY(), vehicle->GetPositionZ(), vehicle->GetOrientation());
- AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
- m_movementInfo.t_x = veSeat->m_attachmentOffsetX;
- m_movementInfo.t_y = veSeat->m_attachmentOffsetY;
- m_movementInfo.t_z = veSeat->m_attachmentOffsetZ;
- m_movementInfo.t_o = 0;
- m_movementInfo.t_time = getMSTime();
- m_movementInfo.t_seat = 0;
-
- WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
- GetSession()->SendPacket(&data);
-
- BuildTeleportAckMsg(&data, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
- GetSession()->SendPacket(&data);
-
- BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
-
- VehicleSpellInitialize();
-}
-
-void Player::ExitVehicle(Vehicle *vehicle)
-{
- vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
-
- SetCharm(vehicle, false);
- SetViewpoint(vehicle, false);
- SetMover(this);
- SetClientControl(vehicle, 0);
-
- clearUnitState(UNIT_STAT_ONVEHICLE);
- Relocate(vehicle->GetPositionX(), vehicle->GetPositionY(), vehicle->GetPositionZ(), vehicle->GetOrientation());
- RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
- m_movementInfo.t_x = 0;
- m_movementInfo.t_y = 0;
- m_movementInfo.t_z = 0;
- m_movementInfo.t_o = 0;
- m_movementInfo.t_time = 0;
- m_movementInfo.t_seat = 0;
-
- WorldPacket data;
- BuildTeleportAckMsg(&data, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
- GetSession()->SendPacket(&data);
-
- BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
-
- data.Initialize(SMSG_PET_SPELLS, 8+4);
- data << uint64(0);
- data << uint32(0);
- GetSession()->SendPacket(&data);
-
- // only for flyable vehicles?
- //CastSpell(this, 45472, true); // Parachute
-
- //if(!vehicle->GetDBTableGUIDLow())
- if(vehicle->GetOwnerGUID() == GetGUID())
- vehicle->Dismiss();
-}
-
bool Player::isTotalImmune()
{
AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
diff --git a/src/game/Player.h b/src/game/Player.h
index 60b2c7a0a1d..3bf99f073af 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -654,37 +654,6 @@ enum InstanceResetWarningType
RAID_INSTANCE_WELCOME = 4 // Welcome to %s. This raid instance is scheduled to reset in %s.
};
-struct MovementInfo
-{
- // common
- 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_unk, 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_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
- t_guid = 0;
- }
-};
-
// flags that use in movement check for example at spell casting
MovementFlags const movementFlagsMask = MovementFlags(
MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT|MOVEMENTFLAG_STRAFE_RIGHT|
@@ -1360,6 +1329,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void CharmSpellInitialize();
void PossessSpellInitialize();
void VehicleSpellInitialize();
+ void SendRemoveControlBar();
bool HasSpell(uint32 spell) const;
bool HasActiveSpell(uint32 spell) const; // show in spellbook
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
@@ -1912,7 +1882,6 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
/*** VARIOUS SYSTEMS ***/
/*********************************************************/
- MovementInfo m_movementInfo;
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
Unit *m_mover;
WorldObject *m_seer;
@@ -1932,9 +1901,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetClientControl(Unit* target, uint8 allowMove);
- void EnterVehicle(Vehicle *vehicle);
- void ExitVehicle(Vehicle *vehicle);
-
void SetMover(Unit* target) { m_mover = target; }
void SetSeer(WorldObject *target) { m_seer = target; }
void SetViewpoint(WorldObject *target, bool apply);
@@ -1946,13 +1912,6 @@ class TRINITY_DLL_SPEC Player : public Unit
Transport * GetTransport() const { return m_transport; }
void SetTransport(Transport * t) { m_transport = t; }
- float GetTransOffsetX() const { return m_movementInfo.t_x; }
- float GetTransOffsetY() const { return m_movementInfo.t_y; }
- float GetTransOffsetZ() const { return m_movementInfo.t_z; }
- float GetTransOffsetO() const { return m_movementInfo.t_o; }
- uint32 GetTransTime() const { return m_movementInfo.t_time; }
- int8 GetTransSeat() const { return m_movementInfo.t_seat; }
-
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 775c51b75df..ae468f0fdbb 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -6525,8 +6525,7 @@ void Spell::SummonVehicle(uint32 entry, SummonPropertiesEntry const *properties)
if(damage)
{
m_caster->CastSpell(vehicle, damage, true);
- if(m_caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_caster)->EnterVehicle(vehicle);
+ vehicle->AddPassenger(m_caster);
}
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index da197ec7f5c..281679bc3e6 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -51,6 +51,7 @@
#include "NullCreatureAI.h"
#include "Traveller.h"
#include "TemporarySummon.h"
+#include "Vehicle.h"
#include <math.h>
@@ -79,7 +80,7 @@ static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false), IsAIEnabled(false), NeedChangeAI(false)
-, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0)
+, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_Vehicle(NULL)
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -10145,6 +10146,7 @@ void Unit::setDeathState(DeathState s)
UnsummonAllTotems();
RemoveAllControlled();
RemoveAllAurasOnDeath();
+ if(m_Vehicle) m_Vehicle->RemovePassenger(this);
//This is needed to clear visible auras after unit dies
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
@@ -11112,6 +11114,7 @@ void Unit::RemoveFromWorld()
RemoveCharmAuras();
RemoveBindSightAuras();
RemoveNotOwnSingleTargetAuras();
+ if(m_Vehicle) m_Vehicle->RemovePassenger(this);
if(GetCharmerGUID())
sLog.outCrash("Unit %u has charmer guid when removed from world", GetEntry());
diff --git a/src/game/Unit.h b/src/game/Unit.h
index d768ea28254..60f1a113175 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -632,6 +632,37 @@ enum MovementFlags
MOVEMENTFLAG_UNK3 = 0x40000000
};
+struct MovementInfo
+{
+ // common
+ 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_unk, 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_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
+ t_guid = 0;
+ }
+};
+
enum DiminishingLevels
{
DIMINISHING_LEVEL_1 = 0,
@@ -1561,6 +1592,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; }
bool IsAIEnabled, NeedChangeAI;
+ MovementInfo m_movementInfo;
+ Vehicle *m_Vehicle;
+ float GetTransOffsetX() const { return m_movementInfo.t_x; }
+ float GetTransOffsetY() const { return m_movementInfo.t_y; }
+ float GetTransOffsetZ() const { return m_movementInfo.t_z; }
+ float GetTransOffsetO() const { return m_movementInfo.t_o; }
+ uint32 GetTransTime() const { return m_movementInfo.t_time; }
+ int8 GetTransSeat() const { return m_movementInfo.t_seat; }
protected:
explicit Unit ();
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
index 377b1d263b2..dee2a57a1fa 100644
--- a/src/game/Vehicle.cpp
+++ b/src/game/Vehicle.cpp
@@ -22,8 +22,11 @@
#include "Vehicle.h"
#include "Unit.h"
#include "Util.h"
+#include "WorldPacket.h"
-Vehicle::Vehicle() : Creature(), m_vehicleId(0)
+#include "Chat.h"
+
+Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL)
{
m_summonMask |= SUMMON_MASK_VEHICLE;
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
@@ -55,9 +58,9 @@ void Vehicle::RemoveFromWorld()
void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
{
- if(Unit *charmer = GetCharmer())
- if(charmer->GetTypeId() == TYPEID_PLAYER)
- ((Player*)charmer)->ExitVehicle(this);
+ for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+ if(itr->second.passenger)
+ RemovePassenger(itr->second.passenger);
Creature::setDeathState(s);
}
@@ -68,6 +71,7 @@ void Vehicle::Update(uint32 diff)
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team)
{
+ //sLog.outError("create vehicle begin");
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
@@ -89,9 +93,178 @@ bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, u
SelectLevel(ci);
SetHealth(GetMaxHealth());
+ //sLog.outError("create vehicle end");
return true;
}
+void Vehicle::SetVehicleId(uint32 id)
+{
+ if(m_vehicleInfo && id == m_vehicleInfo->m_ID)
+ return;
+
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+ if(!ve)
+ return;
+
+ m_vehicleInfo = ve;
+ for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+ if(itr->second.passenger)
+ RemovePassenger(itr->second.passenger);
+ m_Seats.clear();
+
+ for(uint32 i = 0; i < 8; ++i)
+ {
+ uint32 seatId = m_vehicleInfo->m_seatID[i];
+ if(seatId)
+ if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
+ m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
+ }
+}
+
+void Vehicle::AddPassenger(Unit *unit)
+{
+ sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
+
+ if(unit->m_Vehicle)
+ unit->m_Vehicle->RemovePassenger(unit);
+ unit->m_Vehicle = this;
+
+ Player *player = NULL;
+ if(unit->GetTypeId() == TYPEID_PLAYER)
+ player = (Player*)unit;
+
+ SeatMap::iterator seat = m_Seats.begin();
+ uint32 seatnum = 0;
+ if(seat->second.passenger)
+ {
+ if(m_Seats.size() <= 1)
+ return;
+ seatnum = rand()%(m_Seats.size()-1) + 1;
+ advance(seat, seatnum);
+ if(seat->second.passenger)
+ return;
+ //RemovePassenger(seat->second.passenger);
+ }
+ seat->second.passenger = unit;
+
+ bool driver = (seat == m_Seats.begin());
+
+ //RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ setFaction(unit->getFaction());
+
+ if(player)
+ {
+ player->StopCastingCharm();
+ player->StopCastingBindSight();
+
+ if(driver)
+ {
+ player->SetCharm(this, true);
+ player->SetViewpoint(this, true);
+ player->SetMover(this);
+ player->VehicleSpellInitialize();
+ }
+ player->SetClientControl(this, 1);
+ }
+
+ unit->addUnitState(UNIT_STAT_ONVEHICLE);
+ unit->Relocate(this);
+ unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+
+ VehicleSeatEntry const *veSeat = seat->second.seatInfo;
+ unit->m_movementInfo.t_x = veSeat->m_attachmentOffsetX;
+ unit->m_movementInfo.t_y = veSeat->m_attachmentOffsetY;
+ unit->m_movementInfo.t_z = veSeat->m_attachmentOffsetZ;
+ unit->m_movementInfo.t_o = 0;
+ unit->m_movementInfo.t_time = 4;
+ unit->m_movementInfo.t_seat = seat->first;
+
+ WorldPacket data;
+ if(player)
+ {
+ //ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
+
+ data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ player->GetSession()->SendPacket(&data);
+
+ player->BuildTeleportAckMsg(&data, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation());
+ player->GetSession()->SendPacket(&data);
+ }
+
+ unit->BuildHeartBeatMsg(&data);
+ unit->SendMessageToSet(&data, player ? false : true);
+}
+
+void Vehicle::RemovePassenger(Unit *unit)
+{
+ SeatMap::iterator seat;
+ for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
+ {
+ if(seat->second.passenger == unit)
+ {
+ seat->second.passenger = NULL;
+ break;
+ }
+ }
+
+ if(seat == m_Seats.end())
+ return;
+
+ sLog.outDebug("Unit %s exit vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
+
+ bool driver = (seat == m_Seats.begin());
+
+ Player *player = NULL;
+ if(unit->GetTypeId() == TYPEID_PLAYER)
+ player = (Player*)unit;
+
+ //SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ //setFaction((GetTeam() == ALLIANCE) ? GetCreatureInfo()->faction_A : GetCreatureInfo()->faction_H);
+
+ if(player)
+ {
+ if(driver)
+ {
+ player->SetCharm(this, false);
+ player->SetViewpoint(this, false);
+ player->SetMover(player);
+ player->SendRemoveControlBar();
+ }
+ player->SetClientControl(player, 1);
+ }
+
+ unit->clearUnitState(UNIT_STAT_ONVEHICLE);
+ unit->Relocate(this);
+ unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ unit->m_movementInfo.t_x = 0;
+ unit->m_movementInfo.t_y = 0;
+ unit->m_movementInfo.t_z = 0;
+ unit->m_movementInfo.t_o = 0;
+ unit->m_movementInfo.t_time = 0;
+ unit->m_movementInfo.t_seat = 0;
+
+ unit->m_Vehicle = NULL;
+
+ WorldPacket data;
+ if(player)
+ {
+ player->BuildTeleportAckMsg(&data, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation());
+ player->GetSession()->SendPacket(&data);
+ }
+
+ unit->BuildHeartBeatMsg(&data);
+ unit->SendMessageToSet(&data, player ? false : true);
+
+ // only for flyable vehicles?
+ //CastSpell(this, 45472, true); // Parachute
+
+ //if(!vehicle->GetDBTableGUIDLow())
+ if(GetOwnerGUID() == unit->GetGUID())
+ Dismiss();
+}
+
void Vehicle::Dismiss()
{
SendObjectDeSpawnAnim(GetGUID());
diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
index 06630368798..c01ca027670 100644
--- a/src/game/Vehicle.h
+++ b/src/game/Vehicle.h
@@ -23,6 +23,18 @@
#include "Creature.h"
#include "Unit.h"
+struct VehicleEntry;
+struct VehicleSeatEntry;
+
+struct VehicleSeat
+{
+ explicit VehicleSeat(VehicleSeatEntry const *_seatInfo) : seatInfo(_seatInfo), passenger(NULL) {}
+ VehicleSeatEntry const *seatInfo;
+ Unit* passenger;
+};
+
+typedef std::map<uint32, VehicleSeat> SeatMap;
+
class Vehicle : public Creature
{
public:
@@ -37,14 +49,18 @@ class Vehicle : public Creature
void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
- uint32 GetVehicleId() { return m_vehicleId; }
- void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
+ VehicleEntry const *GetVehicleInfo() { return m_vehicleInfo; }
+ void SetVehicleId(uint32 vehicleid);
+ void AddPassenger(Unit *passenger);
+ void RemovePassenger(Unit *passenger);
void Dismiss();
bool LoadFromDB(uint32 guid, Map *map);
+
+ SeatMap m_Seats;
protected:
- uint32 m_vehicleId;
+ VehicleEntry const *m_vehicleInfo;
private:
void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 0848ef63ecb..c4126ce51b9 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -361,10 +361,11 @@ class TRINITY_DLL_SPEC WorldSession
void HandleMoveWorldportAckOpcode(); // for server-side calls
void HandleMovementOpcodes(WorldPacket& recvPacket);
- //void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
void HandleMoveNotActiveMover(WorldPacket &recv_data);
void HandleDismissControlledVehicle(WorldPacket &recv_data);
+ void HandleRequestVehicleExit(WorldPacket &recv_data);
+ void HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data);
void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );