diff options
-rw-r--r-- | src/game/Map.cpp | 18 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 17 | ||||
-rw-r--r-- | src/game/Object.h | 4 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 73 | ||||
-rw-r--r-- | src/game/Unit.h | 3 | ||||
-rw-r--r-- | src/game/Vehicle.cpp | 206 | ||||
-rw-r--r-- | src/game/Vehicle.h | 8 |
8 files changed, 225 insertions, 106 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..c400e1f23fc 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -496,6 +496,23 @@ 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(GetPlayer()->m_Vehicle) + { + if(Vehicle *vehicle = GetPlayer()->m_Vehicle->HasEmptySeat(seat)) + { + GetPlayer()->m_Vehicle->RemovePassenger(GetPlayer()); + //If the player is going to a turret, the vehicle should be changed + GetPlayer()->m_Vehicle = vehicle; + if(!vehicle->AddPassenger(GetPlayer(), seat)) + { + assert(false); + } + } + } } void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data) diff --git a/src/game/Object.h b/src/game/Object.h index 455484eea2d..eff964aba0f 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -518,8 +518,8 @@ class TRINITY_DLL_SPEC WorldObject : public Object Map * GetMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_getMap(); } Map * FindMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_findMap(); } Map const* GetBaseMap() const; - TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); - Vehicle* SummonVehicle(uint32 entry, float x, float y, float z, float ang); + TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0,TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN,uint32 despwtime = 0); + Vehicle* SummonVehicle(uint32 entry, float x, float y, float z, float ang = 0); GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); bool isActiveObject() const { return m_isActive; } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f928b8fd8bd..5a1648b82f7 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3898,7 +3898,7 @@ void AuraEffect::HandleModThreat(bool apply, bool Real) if(GetMiscValue() & int32(1<<x)) { if(m_target->GetTypeId() == TYPEID_PLAYER) - ApplyPercentModFloatVar(m_target->m_threatModifier[x], GetParentAura()->IsPositive() ? m_amount : -m_amount, apply); + ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_amount, apply); } } } 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..2be74bd628b 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,16 @@ 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) + { + for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) + { + if(Unit *passenger = itr->second.passenger) + if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle()) + ((Vehicle*)passenger)->setDeathState(s); + } + RemoveAllPassengers(); + } Creature::setDeathState(s); } @@ -97,6 +105,18 @@ 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(Unit *passenger = itr->second.passenger) + { + if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle()) + ((Vehicle*)passenger)->RemoveAllPassengers(); + passenger->ExitVehicle(); + assert(!itr->second.passenger); + } +} + void Vehicle::SetVehicleId(uint32 id) { if(m_vehicleInfo && id == m_vehicleInfo->m_ID) @@ -107,9 +127,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 +138,68 @@ 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) +Vehicle* Vehicle::HasEmptySeat(int8 seatNum) const { - sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow()); + SeatMap::const_iterator seat = m_Seats.find(seatNum); + //No such seat + if(seat == m_Seats.end()) return NULL; + //Not occupied + if(!seat->second.passenger) return (Vehicle*)this; + //Check if turret is empty + if(seat->second.passenger->GetTypeId() == TYPEID_UNIT + && ((Creature*)seat->second.passenger)->isVehicle()) + return ((Vehicle*)seat->second.passenger)->HasEmptySeat(seatNum); + //Occupied + return NULL; +} - if(unit->m_Vehicle) - unit->m_Vehicle->RemovePassenger(unit); - unit->m_Vehicle = this; +void Vehicle::InstallAccessory(uint32 entry, int8 seatNum) +{ + Creature *accessory = SummonCreature(entry, GetPositionX(), GetPositionY(), GetPositionZ()); + if(!accessory) + return; - Player *player = NULL; - if(unit->GetTypeId() == TYPEID_PLAYER) - player = (Player*)unit; + accessory->m_Vehicle = this; + accessory->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + AddPassenger(accessory, seatNum); +} - SeatMap::iterator seat = m_Seats.begin(); - uint32 seatnum = 0; - if(seat->second.passenger) +bool Vehicle::AddPassenger(Unit *unit, int8 seatNum) +{ + if(unit->m_Vehicle != this) + return false; + + 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 +209,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 +252,33 @@ 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() { + for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) + { + if(Unit *passenger = itr->second.passenger) + if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle()) + ((Vehicle*)passenger)->Dismiss(); + } + RemoveAllPassengers(); SendObjectDeSpawnAnim(GetGUID()); CombatStop(); CleanupsBeforeDelete(); diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index c01ca027670..0ca76687716 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,8 +52,10 @@ class Vehicle : public Creature VehicleEntry const *GetVehicleInfo() { return m_vehicleInfo; } void SetVehicleId(uint32 vehicleid); - void AddPassenger(Unit *passenger); + Vehicle* HasEmptySeat(int8 seatNum) const; + bool AddPassenger(Unit *passenger, int8 seatNum = -1); void RemovePassenger(Unit *passenger); + void InstallAccessory(uint32 entry, int8 seatNum); void Dismiss(); bool LoadFromDB(uint32 guid, Map *map); @@ -62,6 +64,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 { |