diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/Map.cpp | 18 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 15 | ||||
-rw-r--r-- | src/game/Unit.cpp | 73 | ||||
-rw-r--r-- | src/game/Unit.h | 3 | ||||
-rw-r--r-- | src/game/Vehicle.cpp | 168 | ||||
-rw-r--r-- | src/game/Vehicle.h | 12 |
6 files changed, 184 insertions, 105 deletions
diff --git a/src/game/Map.cpp b/src/game/Map.cpp index f0dce40e2fd..0dabf205af7 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -911,11 +911,21 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang 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); + if(Unit *passenger = itr->second.passenger) + { + if(passenger->GetTypeId() == TYPEID_PLAYER) + PlayerRelocation((Player*)passenger, + x + passenger->m_movementInfo.t_x, + y + passenger->m_movementInfo.t_y, + z + passenger->m_movementInfo.t_z, + ang + passenger->m_movementInfo.t_o); else - CreatureRelocation((Creature*)itr->second.passenger, x, y, z, ang); + CreatureRelocation((Creature*)passenger, + x + passenger->m_movementInfo.t_x, + y + passenger->m_movementInfo.t_y, + z + passenger->m_movementInfo.t_z, + ang + passenger->m_movementInfo.t_o); + } } assert(CheckGridIntegrity(creature,true)); diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 50152de4e97..a5d79b678b2 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -496,6 +496,21 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) 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); + + if(seat == GetPlayer()->GetTransSeat()) + return; + + if(Vehicle *vehicle = GetPlayer()->m_Vehicle) + { + if(vehicle->HasEmptySeat(seat)) + { + vehicle->RemovePassenger(GetPlayer()); + if(!vehicle->AddPassenger(GetPlayer(), seat)) + { + assert(false); + } + } + } } void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9150f312e22..7dec93b881e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -13465,6 +13465,79 @@ void Unit::JumpTo(WorldObject *obj, float speedZ) GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ); } +void Unit::EnterVehicle(Vehicle *vehicle) +{ + if(m_Vehicle) + ExitVehicle(); + + if(GetTypeId() == TYPEID_PLAYER) + { + ((Player*)this)->StopCastingCharm(); + ((Player*)this)->StopCastingBindSight(); + } + + assert(!m_Vehicle); + m_Vehicle = vehicle; + if(!m_Vehicle->AddPassenger(this)) + { + m_Vehicle = NULL; + return; + } + + m_Vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); + m_Vehicle->setFaction(getFaction()); + + addUnitState(UNIT_STAT_ONVEHICLE); + AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + //movementInfo is set in AddPassenger + //packets are sent in AddPassenger + + if(GetTypeId() == TYPEID_PLAYER) + { + ((Player*)this)->SetClientControl(vehicle, 1); + WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); + ((Player*)this)->GetSession()->SendPacket(&data); + } +} + +void Unit::ExitVehicle() +{ + if(!m_Vehicle) + return; + + m_Vehicle->RemovePassenger(this); + + m_Vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); + //setFaction((GetTeam() == ALLIANCE) ? GetCreatureInfo()->faction_A : GetCreatureInfo()->faction_H); + + clearUnitState(UNIT_STAT_ONVEHICLE); + 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; + + //Send leave vehicle + WorldPacket data; + if(GetTypeId() == TYPEID_PLAYER) + { + ((Player*)this)->SetClientControl(this, 1); + ((Player*)this)->BuildTeleportAckMsg(&data, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); + ((Player*)this)->GetSession()->SendPacket(&data); + } + + BuildHeartBeatMsg(&data); + SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? false : true); + + if(m_Vehicle->GetOwnerGUID() == GetGUID()) + m_Vehicle->Dismiss(); + + m_Vehicle = NULL; +} + void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool casting /*= false*/ ) { if(GetTypeId() == TYPEID_PLAYER) diff --git a/src/game/Unit.h b/src/game/Unit.h index 3db7573a8b2..1e50ed1e255 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1626,6 +1626,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject int8 GetTransSeat() const { return m_movementInfo.t_seat; } bool m_ControlledByPlayer; + + void EnterVehicle(Vehicle *vehicle); + void ExitVehicle(); protected: explicit Unit (); diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index dee2a57a1fa..2292e981d5b 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -50,6 +50,7 @@ void Vehicle::RemoveFromWorld() { if(IsInWorld()) { + RemoveAllPassengers(); ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); ObjectAccessor::Instance().RemoveObject(this); @@ -58,9 +59,8 @@ void Vehicle::RemoveFromWorld() void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState { - for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) - if(itr->second.passenger) - RemovePassenger(itr->second.passenger); + if(s == JUST_DIED) + RemoveAllPassengers(); Creature::setDeathState(s); } @@ -97,6 +97,16 @@ bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, u return true; } +void Vehicle::RemoveAllPassengers() +{ + for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) + if(itr->second.passenger) + { + itr->second.passenger->ExitVehicle(); + assert(!itr->second.passenger); + } +} + void Vehicle::SetVehicleId(uint32 id) { if(m_vehicleInfo && id == m_vehicleInfo->m_ID) @@ -107,9 +117,8 @@ void Vehicle::SetVehicleId(uint32 id) return; m_vehicleInfo = ve; - for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) - if(itr->second.passenger) - RemovePassenger(itr->second.passenger); + + RemoveAllPassengers(); m_Seats.clear(); for(uint32 i = 0; i < 8; ++i) @@ -119,58 +128,42 @@ void Vehicle::SetVehicleId(uint32 id) if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId)) m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat))); } + + assert(!m_Seats.empty()); } -void Vehicle::AddPassenger(Unit *unit) +bool Vehicle::AddPassenger(Unit *unit, int8 seatNum) { - 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; + if(unit->m_Vehicle != this) + return false; - SeatMap::iterator seat = m_Seats.begin(); - uint32 seatnum = 0; - if(seat->second.passenger) + SeatMap::iterator seat; + if(seatNum < 0) // no specific seat requirement { - 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); + for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) + if(!seat->second.passenger) + break; + + if(seat == m_Seats.end()) // no available seat + return false; } - seat->second.passenger = unit; + else + { + seat = m_Seats.find(seatNum); + if(seat == m_Seats.end()) + return false; - bool driver = (seat == m_Seats.begin()); + if(seat->second.passenger) + seat->second.passenger->ExitVehicle(); - //RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); - setFaction(unit->getFaction()); + assert(!seat->second.passenger); + } - if(player) - { - player->StopCastingCharm(); - player->StopCastingBindSight(); + sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow()); - if(driver) - { - player->SetCharm(this, true); - player->SetViewpoint(this, true); - player->SetMover(this); - player->VehicleSpellInitialize(); - } - player->SetClientControl(this, 1); - } + seat->second.passenger = unit; - unit->addUnitState(UNIT_STAT_ONVEHICLE); - unit->Relocate(this); - unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + //RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); VehicleSeatEntry const *veSeat = seat->second.seatInfo; unit->m_movementInfo.t_x = veSeat->m_attachmentOffsetX; @@ -180,24 +173,39 @@ void Vehicle::AddPassenger(Unit *unit) unit->m_movementInfo.t_time = 4; unit->m_movementInfo.t_seat = seat->first; + unit->Relocate(GetPositionX() + veSeat->m_attachmentOffsetX, + GetPositionY() + veSeat->m_attachmentOffsetY, + GetPositionZ() + veSeat->m_attachmentOffsetZ, + GetOrientation()); + WorldPacket data; - if(player) + if(unit->GetTypeId() == TYPEID_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); + if(seat == m_Seats.begin()) + { + ((Player*)unit)->SetCharm(this, true); + ((Player*)unit)->SetViewpoint(this, true); + ((Player*)unit)->SetMover(this); + ((Player*)unit)->VehicleSpellInitialize(); + } - player->BuildTeleportAckMsg(&data, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation()); - player->GetSession()->SendPacket(&data); + ((Player*)unit)->BuildTeleportAckMsg(&data, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation()); + ((Player*)unit)->GetSession()->SendPacket(&data); } - unit->BuildHeartBeatMsg(&data); - unit->SendMessageToSet(&data, player ? false : true); + BuildHeartBeatMsg(&data); + SendMessageToSet(&data, unit->GetTypeId() == TYPEID_PLAYER ? false : true); + + return true; } void Vehicle::RemovePassenger(Unit *unit) { + if(unit->m_Vehicle != this) + return; + SeatMap::iterator seat; for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) { @@ -208,65 +216,27 @@ void Vehicle::RemovePassenger(Unit *unit) } } - if(seat == m_Seats.end()) - return; + assert(seat != m_Seats.end()); 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) + if(unit->GetTypeId() == TYPEID_PLAYER && seat == m_Seats.begin()) { - player->BuildTeleportAckMsg(&data, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation()); - player->GetSession()->SendPacket(&data); + ((Player*)unit)->SetCharm(this, false); + ((Player*)unit)->SetViewpoint(this, false); + ((Player*)unit)->SetMover(unit); + ((Player*)unit)->SendRemoveControlBar(); } - 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() { + RemoveAllPassengers(); SendObjectDeSpawnAnim(GetGUID()); CombatStop(); CleanupsBeforeDelete(); diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index c01ca027670..a4dffa9ea03 100644 --- a/src/game/Vehicle.h +++ b/src/game/Vehicle.h @@ -33,7 +33,7 @@ struct VehicleSeat Unit* passenger; }; -typedef std::map<uint32, VehicleSeat> SeatMap; +typedef std::map<int8, VehicleSeat> SeatMap; class Vehicle : public Creature { @@ -52,7 +52,13 @@ class Vehicle : public Creature VehicleEntry const *GetVehicleInfo() { return m_vehicleInfo; } void SetVehicleId(uint32 vehicleid); - void AddPassenger(Unit *passenger); + bool HasEmptySeat(int8 seatNum) const + { + SeatMap::const_iterator seat = m_Seats.find(seatNum); + if(seat == m_Seats.end()) return false; + return !seat->second.passenger; + } + bool AddPassenger(Unit *passenger, int8 seatNum = -1); void RemovePassenger(Unit *passenger); void Dismiss(); @@ -62,6 +68,8 @@ class Vehicle : public Creature protected: VehicleEntry const *m_vehicleInfo; + void RemoveAllPassengers(); + private: void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called { |