diff options
Diffstat (limited to 'src/game/Vehicle.cpp')
| -rw-r--r-- | src/game/Vehicle.cpp | 270 |
1 files changed, 66 insertions, 204 deletions
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 2b49df166ef..4070878dd81 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -27,30 +27,35 @@ #include "CreatureAI.h" #include "ZoneScript.h" -Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL), m_usableSeatNum(0) +Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0) { - m_summonMask |= SUMMON_MASK_VEHICLE; - m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE); + for(uint32 i = 0; i < 8; ++i) + { + if(uint32 seatId = m_vehicleInfo->m_seatID[i]) + if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId)) + { + m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat))); + if(veSeat->IsUsable()) + ++m_usableSeatNum; + } + } + assert(!m_Seats.empty()); } Vehicle::~Vehicle() { } -void Vehicle::AddToWorld() +void Vehicle::Install() { - if(!IsInWorld()) + if(Creature *cre = dynamic_cast<Creature*>(me)) { - if(m_zoneScript) - m_zoneScript->OnCreatureCreate(this, true); - ObjectAccessor::Instance().AddObject(this); - for(uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i) { - if(!m_spells[i]) + if(!cre->m_spells[i]) continue; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i]); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(cre->m_spells[i]); if(!spellInfo) continue; @@ -59,22 +64,19 @@ void Vehicle::AddToWorld() if(spellInfo->powerType == POWER_ENERGY) { - setPowerType(POWER_ENERGY); - SetMaxPower(POWER_ENERGY, 100); + me->setPowerType(POWER_ENERGY); + me->SetMaxPower(POWER_ENERGY, 100); break; } } - - Unit::AddToWorld(); - InstallAllAccessories(); - - AIM_Initialize(); } + + Reset(); } void Vehicle::InstallAllAccessories() { - switch(GetEntry()) + switch(me->GetEntry()) { //case 27850:InstallAccessory(27905,1);break; case 28782:InstallAccessory(28768,0);break; // Acherus Deathcharger @@ -96,64 +98,27 @@ void Vehicle::InstallAllAccessories() } } -void Vehicle::RemoveFromWorld() +void Vehicle::Uninstall() { - if(IsInWorld()) - { - if(m_zoneScript) - m_zoneScript->OnCreatureCreate(this, false); - RemoveAllPassengers(); - ///- Don't call the function for Creature, normal mobs + totems go in a different storage - Unit::RemoveFromWorld(); - ObjectAccessor::Instance().RemoveObject(this); - } + RemoveAllPassengers(); } -void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState +void Vehicle::Die() { - if(s == JUST_DIED) - { - for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) - { - if(Unit *passenger = itr->second.passenger) - if(passenger->GetOwnerGUID() == GetGUID()) - { - passenger->ExitVehicle(); - passenger->setDeathState(s); - passenger->AddObjectToRemoveList(); - } - } - RemoveAllPassengers(); - } - - Creature::setDeathState(s); - - if(s == JUST_ALIVED) + for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) { - InstallAllAccessories(); - if(m_usableSeatNum) - SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + if(Unit *passenger = itr->second.passenger) + if(passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY)) + passenger->setDeathState(JUST_DIED); } + RemoveAllPassengers(); } -void Vehicle::Update(uint32 diff) -{ - Creature::Update(diff); - //310 - if(getPowerType() == POWER_ENERGY) // m_vehicleInfo->36 - ModifyPower(POWER_ENERGY, 100); - - if(m_deathState == DEAD && !GetDBTableGUIDLow()) - Dismiss(); -} - -bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, float x, float y, float z, float o, const CreatureData * data) +void Vehicle::Reset() { - if(!Creature::Create(guidlow, map, phaseMask, Entry, team, x, y, z, o, data)) - return false; - - SetVehicleId(vehicleId); - return true; + InstallAllAccessories(); + if(m_usableSeatNum) + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } void Vehicle::RemoveAllPassengers() @@ -161,53 +126,20 @@ 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(); - if(!passenger->m_Vehicle || passenger->m_Vehicle != this) - { - sLog.outCrash("Vehicle %u has invalid passenger %u.", GetEntry(), passenger->GetEntry()); - } + if(passenger->IsVehicle()) + passenger->GetVehicleKit()->RemoveAllPassengers(); + if(passenger->GetVehicle() != this) + sLog.outCrash("Vehicle %u has invalid passenger %u.", me->GetEntry(), passenger->GetEntry()); passenger->ExitVehicle(); if(itr->second.passenger) { - sLog.outCrash("Vehicle %u cannot remove passenger %u. %u is still on it.", GetEntry(), passenger->GetEntry(), itr->second.passenger->GetEntry()); + sLog.outCrash("Vehicle %u cannot remove passenger %u. %u is still on it.", me->GetEntry(), passenger->GetEntry(), itr->second.passenger->GetEntry()); //assert(!itr->second.passenger); itr->second.passenger = NULL; } } } -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; - - RemoveAllPassengers(); - m_Seats.clear(); - m_usableSeatNum = 0; - - for(uint32 i = 0; i < 8; ++i) - { - if(uint32 seatId = m_vehicleInfo->m_seatID[i]) - if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId)) - { - m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat))); - if(veSeat->IsUsable()) - ++m_usableSeatNum; - } - } - - assert(!m_Seats.empty()); - if(m_usableSeatNum) - SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); -} - bool Vehicle::HasEmptySeat(int8 seatId) const { SeatMap::const_iterator seat = m_Seats.find(seatId); @@ -254,23 +186,17 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId) if(passenger->GetEntry() == entry) { assert(passenger->GetTypeId() == TYPEID_UNIT); - if(IsInEvadeMode() && ((Creature*)passenger)->AI()) + if(me->GetTypeId() == TYPEID_UNIT && ((Creature*)me)->IsInEvadeMode() && ((Creature*)passenger)->IsAIEnabled) ((Creature*)passenger)->AI()->EnterEvadeMode(); return; } passenger->ExitVehicle(); // this should not happen } - const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(entry); - if(!cInfo) - return; - Creature *accessory; - if(cInfo->VehicleId) - accessory = SummonVehicle(entry, GetPositionX(), GetPositionY(), GetPositionZ()); - else - accessory = SummonCreature(entry, GetPositionX(), GetPositionY(), GetPositionZ()); + Creature *accessory = me->SummonCreature(entry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0); if(!accessory) return; + accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY); accessory->EnterVehicle(this, seatId); // This is not good, we have to send update twice accessory->SendMovementFlagUpdate(); @@ -278,7 +204,7 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId) bool Vehicle::AddPassenger(Unit *unit, int8 seatId) { - if(unit->m_Vehicle != this) + if(unit->GetVehicle() != this) return false; SeatMap::iterator seat; @@ -303,7 +229,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) assert(!seat->second.passenger); } - sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow(), (int32)seat->first); + sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32)seat->first); seat->second.passenger = unit; if(seat->second.seatInfo->IsUsable()) @@ -311,7 +237,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) assert(m_usableSeatNum); --m_usableSeatNum; if(!m_usableSeatNum) - RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } if(!(seat->second.seatInfo->m_flags & 0x4000)) @@ -329,17 +255,21 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) unit->m_movementInfo.t_seat = seat->first; if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right - if (!SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) + if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) assert(false); - if(IsInWorld()) + if(me->GetTypeId() == TYPEID_UNIT) { - unit->SendMonsterMoveTransport(this); - GetMap()->CreatureRelocation(this, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); - } + if(me->IsInWorld()) + { + unit->SendMonsterMoveTransport(me); + // move self = move all passengers + me->GetMap()->CreatureRelocation((Creature*)me, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + } - if(AI()) - AI()->PassengerBoarded(unit, seat->first); + if(((Creature*)me)->IsAIEnabled) + ((Creature*)me)->AI()->PassengerBoarded(unit, seat->first); + } //if(unit->GetTypeId() == TYPEID_PLAYER) // ((Player*)unit)->SendTeleportAckMsg(); @@ -350,7 +280,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) void Vehicle::RemovePassenger(Unit *unit) { - if(unit->m_Vehicle != this) + if(unit->GetVehicle() != this) return; SeatMap::iterator seat; @@ -360,13 +290,13 @@ void Vehicle::RemovePassenger(Unit *unit) assert(seat != m_Seats.end()); - sLog.outDebug("Unit %s exit vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow(), (int32)seat->first); + sLog.outDebug("Unit %s exit vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32)seat->first); seat->second.passenger = NULL; if(seat->second.seatInfo->IsUsable()) { if(!m_usableSeatNum) - SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); ++m_usableSeatNum; } @@ -376,10 +306,10 @@ void Vehicle::RemovePassenger(Unit *unit) //SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) - RemoveCharmedBy(unit); + me->RemoveCharmedBy(unit); - if(AI()) - AI()->PassengerLeft(unit, seat->first); + if(me->GetTypeId() == TYPEID_UNIT && ((Creature*)me)->IsAIEnabled) + ((Creature*)me)->AI()->PassengerLeft(unit, seat->first); // only for flyable vehicles? //CastSpell(this, 45472, true); // Parachute @@ -390,82 +320,14 @@ 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()) + if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->IsVehicle()) { passenger->ExitVehicle(); - ((Vehicle*)passenger)->Dismiss(); + passenger->GetVehicleKit()->Dismiss(); } } RemoveAllPassengers(); - SendObjectDeSpawnAnim(GetGUID()); - CombatStop(); - AddObjectToRemoveList(); -} - -bool Vehicle::LoadFromDB(uint32 guid, Map *map) -{ - CreatureData const* data = objmgr.GetCreatureData(guid); - - if(!data) - { - sLog.outErrorDb("Creature (GUID: %u) not found in table `creature`, can't load. ",guid); - return false; - } - - uint32 id = 0; - if(const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(data->id)) - id = cInfo->VehicleId; - if(!id || !sVehicleStore.LookupEntry(id)) - return false; - - m_DBTableGuid = guid; - if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_VEHICLE); - - uint16 team = 0; - if(!Create(guid,map,data->phaseMask,data->id,id,team,data->posX,data->posY,data->posZ,data->orientation,data)) - return false; - - //We should set first home position, because then AI calls home movement - SetHomePosition(data->posX,data->posY,data->posZ,data->orientation); - - m_respawnradius = data->spawndist; - - m_respawnDelay = data->spawntimesecs; - m_isDeadByDefault = data->is_dead; - m_deathState = m_isDeadByDefault ? DEAD : ALIVE; - - m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); - if(m_respawnTime > time(NULL)) // not ready to respawn - { - m_deathState = DEAD; - if(canFly()) - { - float tz = GetMap()->GetHeight(data->posX,data->posY,data->posZ,false); - if(data->posZ - tz > 0.1) - Relocate(data->posX,data->posY,tz); - } - } - else if(m_respawnTime) // respawn time set but expired - { - m_respawnTime = 0; - objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); - } - - uint32 curhealth = data->curhealth; - if(curhealth) - { - curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank)); - if(curhealth < 1) - curhealth = 1; - } - - SetHealth(m_deathState == ALIVE ? curhealth : 0); - SetPower(POWER_MANA,data->curmana); - - // checked at creature_template loading - m_defaultMovementType = MovementGeneratorType(data->movementType); - - m_creatureData = data; - - return true; + me->SendObjectDeSpawnAnim(me->GetGUID()); + me->CombatStop(); + me->AddObjectToRemoveList(); } |
