diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Chat.cpp | 2 | ||||
-rw-r--r-- | src/game/Chat.h | 2 | ||||
-rw-r--r-- | src/game/Debugcmds.cpp | 51 | ||||
-rw-r--r-- | src/game/Map.cpp | 12 | ||||
-rw-r--r-- | src/game/MiscHandler.cpp | 3 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 28 | ||||
-rw-r--r-- | src/game/Object.cpp | 69 | ||||
-rw-r--r-- | src/game/Object.h | 8 | ||||
-rw-r--r-- | src/game/Opcodes.cpp | 4 | ||||
-rw-r--r-- | src/game/Player.cpp | 109 | ||||
-rw-r--r-- | src/game/Player.h | 43 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 3 | ||||
-rw-r--r-- | src/game/Unit.cpp | 5 | ||||
-rw-r--r-- | src/game/Unit.h | 39 | ||||
-rw-r--r-- | src/game/Vehicle.cpp | 181 | ||||
-rw-r--r-- | src/game/Vehicle.h | 22 | ||||
-rw-r--r-- | src/game/WorldSession.h | 3 |
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 ); |