diff options
author | megamage <none@none> | 2009-08-23 22:09:43 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-08-23 22:09:43 -0500 |
commit | 1ee90e1022a235859316e55356ea8a3d2f456c9b (patch) | |
tree | b3db14f5e81ac865bb3fe92158b8837eb9b0ca5f | |
parent | e71f5e474e2d935f2bfd8520dbf62a6f4b552a18 (diff) |
*Update vehicle system. Make vehicle a seperate class from creature.
--HG--
branch : trunk
42 files changed, 451 insertions, 579 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index aa64a6fcbf1..89c996c6589 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -175,6 +175,13 @@ Creature *ScriptedAI::DoSummon(uint32 uiEntry, WorldObject* pGo, float fRadius, return me->SummonCreature(uiEntry, fX, fY, fZ, me->GetOrientation(), uiType, uiDespawntime); } +Creature *ScriptedAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float _fZ, float fRadius, uint32 uiDespawntime, TempSummonType uiType) +{ + float fX, fY, fZ; + obj->GetGroundPointAroundUnit(fX, fY, fZ, fRadius * rand_norm(), rand_norm()*2*M_PI); + return me->SummonCreature(uiEntry, fX, fY, _fZ, me->GetOrientation(), uiType, uiDespawntime); +} + Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 uiPosition) { diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 74eea9ad599..c4066a95598 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -18,7 +18,6 @@ #define CAST_PLR(a) (SCRIPT_CAST_TYPE<Player*>(a)) #define CAST_CRE(a) (SCRIPT_CAST_TYPE<Creature*>(a)) -#define CAST_VEH(a) (SCRIPT_CAST_TYPE<Vehicle*>(a)) #define CAST_SUM(a) (SCRIPT_CAST_TYPE<TempSummon*>(a)) #define CAST_PET(a) (SCRIPT_CAST_TYPE<Pet*>(a)) #define CAST_AI(a,b) (SCRIPT_CAST_TYPE<a*>(b)) @@ -27,7 +26,7 @@ class ScriptedInstance; -class SummonList : private std::list<uint64> +class SummonList : public std::list<uint64> { public: explicit SummonList(Creature* creature) : m_creature(creature) {} @@ -154,6 +153,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI Creature* DoSpawnCreature(uint32 uiId, float fX, float fY, float fZ, float fAngle, uint32 uiType, uint32 uiDespawntime); Creature *DoSummon(uint32 uiEntry, const float fPos[4], uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); Creature *DoSummon(uint32 uiEntry, WorldObject *obj, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); + Creature *DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float fZ, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); //Selects a unit from the creature's current aggro list Unit* SelectUnit(SelectAggroTarget target, uint32 uiPosition); diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp index 9b1b7db6bdd..545e62a530e 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp @@ -582,7 +582,7 @@ struct TRINITY_DLL_DECL npc_salanar_the_horsemanAI : public ScriptedAI { if (spell->Id == DELIVER_STOLEN_HORSE) { - if (caster->GetTypeId() == TYPEID_UNIT && CAST_CRE(caster)->isVehicle()) + if (caster->GetTypeId() == TYPEID_UNIT && caster->IsVehicle()) { if (Unit *charmer = caster->GetCharmer()) { @@ -601,7 +601,7 @@ struct TRINITY_DLL_DECL npc_salanar_the_horsemanAI : public ScriptedAI { ScriptedAI::MoveInLineOfSight(who); - if (who->GetTypeId() == TYPEID_UNIT && CAST_CRE(who)->isVehicle() && me->IsWithinDistInMap(who, 5.0f)) + if (who->GetTypeId() == TYPEID_UNIT && who->IsVehicle() && me->IsWithinDistInMap(who, 5.0f)) { if (Unit *charmer = who->GetCharmer()) { @@ -649,15 +649,15 @@ struct TRINITY_DLL_DECL npc_ros_dark_riderAI : public ScriptedAI deathcharger->RestoreFaction(); deathcharger->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); deathcharger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (!me->m_Vehicle && deathcharger->isVehicle() && CAST_VEH(deathcharger)->HasEmptySeat(0)) - me->EnterVehicle(CAST_VEH(deathcharger)); + if (!me->GetVehicle() && deathcharger->IsVehicle() && deathcharger->GetVehicleKit()->HasEmptySeat(0)) + me->EnterVehicle(deathcharger); } void JustDied(Unit *killer) { Creature* deathcharger = me->FindNearestCreature(28782, 30); if (!deathcharger) return; - if (killer->GetTypeId() == TYPEID_PLAYER && deathcharger->GetTypeId() == TYPEID_UNIT && deathcharger->isVehicle()) + if (killer->GetTypeId() == TYPEID_PLAYER && deathcharger->GetTypeId() == TYPEID_UNIT && deathcharger->IsVehicle()) { deathcharger->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); deathcharger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -811,7 +811,7 @@ struct TRINITY_DLL_DECL npc_scarlet_minerAI : public npc_escortAI void InitCartQuest(Player *who) { - carGUID = who->m_Vehicle->GetGUID(); + carGUID = who->GetVehicleBase()->GetGUID(); InitWaypoint(); Start(false, false, who->GetGUID()); SetDespawnAtFar(false); @@ -894,7 +894,7 @@ bool GOHello_go_inconspicuous_mine_car(Player* pPlayer, GameObject* pGO) if(Creature *miner = pPlayer->SummonCreature(28841, 2383.869629, -5900.312500, 107.996086, pPlayer->GetOrientation(),TEMPSUMMON_DEAD_DESPAWN, 1)) { pPlayer->CastSpell(pPlayer, SPELL_CART_SUMM, true); - if(Vehicle *car = pPlayer->m_Vehicle) + if(Creature *car = pPlayer->GetVehicleCreatureBase()) { if(car->GetEntry() == 28817) { diff --git a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 61d9519d9b0..0d0ca80830d 100644 --- a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -37,6 +37,15 @@ #define SPELL_BLAZE 62292 +#define SPELL_SMOKE_TRAIL 63575 + +enum Mobs +{ + MOB_MECHANOLIFT = 33214, + MOB_LIQUID = 33189, + MOB_CONTAINER = 33218, +}; + enum Events { EVENT_PURSUE = 1, @@ -53,19 +62,21 @@ enum Seats struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI { - boss_flame_leviathanAI(Creature *c) : BossAI(c, BOSS_LEVIATHAN) + boss_flame_leviathanAI(Creature *c) : BossAI(c, BOSS_LEVIATHAN), vehicle(me->GetVehicleKit()) { - assert(c->isVehicle()); + assert(vehicle); me->SetReactState(REACT_DEFENSIVE); } + Vehicle *vehicle; + void EnterCombat(Unit *who) { _EnterCombat(); events.ScheduleEvent(EVENT_PURSUE, 0); events.ScheduleEvent(EVENT_MISSILE, 1500); events.ScheduleEvent(EVENT_VENT, 20000); - if (Creature *turret = CAST_CRE(CAST_VEH(me)->GetPassenger(7))) + if (Creature *turret = CAST_CRE(vehicle->GetPassenger(7))) turret->AI()->DoZoneInCombat(); } @@ -79,7 +90,25 @@ struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI void SpellHit(Unit *caster, const SpellEntry *spell) { if(spell->Id == 62472) - CAST_VEH(me)->InstallAllAccessories(); + vehicle->InstallAllAccessories(); + } + + void JustSummoned(Creature *summon) + { + if(summon->GetEntry() == MOB_MECHANOLIFT) + { + summons.Summon(summon); + } + } + + void SummonedCreatureDespawn(Creature *summon) + { + if(summon->GetEntry() == MOB_MECHANOLIFT) + { + summons.Despawn(summon); + if(Creature* container = DoSummon(MOB_CONTAINER, summon, 0, 0)) + container->GetMotionMaster()->MovePoint(1, container->GetPositionX(), container->GetPositionY(), me->GetPositionZ()); + } } void UpdateAI(const uint32 diff) @@ -93,6 +122,10 @@ struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI return; } + if(summons.size() < 4) + if(Creature *lift = DoSummonFlyer(MOB_MECHANOLIFT, me, 50, rand()%20 + 20, 0)) + lift->GetMotionMaster()->MoveRandom(100); + events.Update(diff); if (me->hasUnitState(UNIT_STAT_CASTING)) @@ -182,39 +215,45 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_turretAI : public ScriptedAI } }; +//#define BOSS_DEBUG struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public PassiveAI { - boss_flame_leviathan_seatAI(Creature *c) : PassiveAI(c) + boss_flame_leviathan_seatAI(Creature *c) : PassiveAI(c), vehicle(c->GetVehicleKit()) { - assert(c->isVehicle()); + assert(vehicle); if (const CreatureInfo *cInfo = me->GetCreatureInfo()) me->SetDisplayId(cInfo->DisplayID_A[0]); // 0 invisible, 1 visible - //me->SetReactState(REACT_AGGRESSIVE); +#ifdef BOSS_DEBUG + me->SetReactState(REACT_AGGRESSIVE); +#endif } - /* + Vehicle *vehicle; + +#ifdef BOSS_DEBUG void MoveInLineOfSight(Unit *who) { if(who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->isGameMaster() - && !who->m_Vehicle && CAST_VEH(me)->GetPassenger(SEAT_TURRET)) - who->EnterVehicle((Vehicle*)me, 0); + && !who->GetVehicle() && vehicle->GetPassenger(SEAT_TURRET)) + who->EnterVehicle(vehicle, SEAT_PLAYER); } - */ +#endif void PassengerBoarded(Unit *who, int8 seatId) { - if(!me->m_Vehicle) + if(!me->GetVehicle()) return; if(seatId == SEAT_PLAYER) { - if(Unit *turret = CAST_VEH(me)->GetPassenger(SEAT_TURRET)) + if(Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET))) { - turret->setFaction(me->m_Vehicle->getFaction()); + turret->setFaction(me->GetVehicleBase()->getFaction()); turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable + turret->AI()->AttackStart(who); } - if(Unit *device = CAST_VEH(me)->GetPassenger(SEAT_DEVICE)) + if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE)) { device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -226,7 +265,7 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public PassiveAI { if(seatId == SEAT_TURRET) { - if(Unit *device = CAST_VEH(me)->GetPassenger(SEAT_DEVICE)) + if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE)) { device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable @@ -243,7 +282,7 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_defense_turretAI : public ScriptedA void DamageTaken(Unit *who, uint32 &damage) { - if (!who->m_Vehicle || who->m_Vehicle->GetEntry() != 33114) + if (!who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114) damage = 0; } @@ -252,7 +291,7 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_defense_turretAI : public ScriptedA if (me->getVictim()) return; - if (who->GetTypeId() != TYPEID_PLAYER || !who->m_Vehicle || who->m_Vehicle->GetEntry() != 33114) + if (who->GetTypeId() != TYPEID_PLAYER || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114) return; AttackStart(who); @@ -296,9 +335,16 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_overload_deviceAI : public PassiveA { me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if(me->m_Vehicle) - if(Unit *player = me->m_Vehicle->GetPassenger(SEAT_PLAYER)) + if(me->GetVehicle()) + { + if(Unit *player = me->GetVehicle()->GetPassenger(SEAT_PLAYER)) + { player->ExitVehicle(); + me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); + if(Unit *leviathan = me->GetVehicleBase()->GetVehicleBase()) + player->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30); + } + } } } }; diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 4d07c1ee6c2..68e758855a9 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1563,7 +1563,7 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f return NULL; Creature* pCreature = new Creature; - if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, teamval, x, y, z, o)) + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, 0, teamval, x, y, z, o)) { sLog.outError("Can't create creature entry: %u",entry); delete pCreature; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 4cf41b0ab92..a8d1ffe9b54 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -138,7 +138,7 @@ m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_resp m_gossipOptionLoaded(false), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), -m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL), m_summonMask(SUMMON_MASK_NONE) +m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL) , m_AlreadySearchedAssistance(false) , m_creatureData(NULL), m_PlayerDamageReq(0) { @@ -700,7 +700,7 @@ void Creature::Motion_Initialize() i_motionMaster.Initialize(); } -bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data) +bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data) { ASSERT(map); SetMap(map); @@ -715,7 +715,7 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, } //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; - const bool bResult = CreateFromProto(guidlow, Entry, team, data); + const bool bResult = CreateFromProto(guidlow, Entry, vehId, team, data); if (bResult) { @@ -1500,7 +1500,7 @@ float Creature::GetSpellDamageMod(int32 Rank) } } -bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data) +bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data) { SetZoneScript(); if(m_zoneScript && data) @@ -1519,10 +1519,13 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const SetOriginalEntry(Entry); - if(isVehicle()) - Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE); - else - Object::_Create(guidlow, Entry, HIGHGUID_UNIT); + if(!vehId) + vehId = cinfo->VehicleId; + + if(vehId && !CreateVehicleKit(vehId)) + vehId = 0; + + Object::_Create(guidlow, Entry, vehId ? HIGHGUID_VEHICLE : HIGHGUID_UNIT); if(!UpdateEntry(Entry, team, data)) return false; @@ -1540,15 +1543,11 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) return false; } - if(const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(data->id)) - if(cInfo->VehicleId) - return false; - m_DBTableGuid = guid; if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT); uint16 team = 0; - if(!Create(guid,map,data->phaseMask,data->id,team,data->posX,data->posY,data->posZ,data->orientation,data)) + if(!Create(guid,map,data->phaseMask,data->id,team,0,data->posX,data->posY,data->posZ,data->orientation,data)) return false; //We should set first home position, because then AI calls home movement diff --git a/src/game/Creature.h b/src/game/Creature.h index 7f8d6040129..a798c88a7e4 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -154,20 +154,6 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills }; -enum SummonMask -{ - SUMMON_MASK_NONE = 0x00000000, - SUMMON_MASK_SUMMON = 0x00000001, - SUMMON_MASK_MINION = 0x00000002, - SUMMON_MASK_GUARDIAN = 0x00000004, - SUMMON_MASK_TOTEM = 0x00000008, - SUMMON_MASK_PET = 0x00000010, - SUMMON_MASK_VEHICLE = 0x00000020, - SUMMON_MASK_PUPPET = 0x00000040, - SUMMON_MASK_HUNTER_PET = 0x00000080, - SUMMON_MASK_CONTROLABLE_GUARDIAN = 0x00000100, -}; - // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined( __GNUC__ ) #pragma pack(1) @@ -493,7 +479,7 @@ class TRINITY_DLL_SPEC Creature : public Unit void DisappearAndDie(); - bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL); + bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL); bool LoadCreaturesAddon(bool reload = false); void SelectLevel(const CreatureInfo *cinfo); void LoadEquipment(uint32 equip_entry, bool force=false); @@ -505,14 +491,6 @@ class TRINITY_DLL_SPEC Creature : public Unit void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const; uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; } - uint32 HasSummonMask(uint32 mask) const { return mask & m_summonMask; } - bool isSummon() const { return m_summonMask & SUMMON_MASK_SUMMON; } - bool isGuardian() const { return m_summonMask & SUMMON_MASK_GUARDIAN; } - bool isPet() const { return m_summonMask & SUMMON_MASK_PET; } - bool isHunterPet() const{ return m_summonMask & SUMMON_MASK_HUNTER_PET; } - bool isVehicle() const { return m_summonMask & SUMMON_MASK_VEHICLE; } - bool isTotem() const { return m_summonMask & SUMMON_MASK_TOTEM; } - void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; } bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; } @@ -747,7 +725,7 @@ class TRINITY_DLL_SPEC Creature : public Unit float m_SightDistance, m_CombatDistance; protected: - bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); + bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); // vendor items @@ -770,7 +748,6 @@ class TRINITY_DLL_SPEC Creature : public Unit bool m_gossipOptionLoaded; GossipOptionList m_goptions; - uint32 m_summonMask; ReactStates m_reactState; // for AI, not charmInfo void RegenerateMana(); void RegenerateHealth(); diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index fe7e0c1a2c5..a16cd09cc09 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -201,7 +201,7 @@ void CreatureAI::EnterEvadeMode() if(!_EnterEvadeMode()) return; - if(!me->m_Vehicle) // otherwise me will be in evade mode forever + if(!me->GetVehicle()) // otherwise me will be in evade mode forever { if(Unit *owner = me->GetCharmerOrOwner()) { @@ -212,8 +212,8 @@ void CreatureAI::EnterEvadeMode() me->GetMotionMaster()->MoveTargetedHome(); } - if(me->isVehicle()) - ((Vehicle*)me)->InstallAllAccessories(); + if(me->IsVehicle()) + me->GetVehicleKit()->InstallAllAccessories(); Reset(); } diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index b268391f260..9f2828bf776 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -54,13 +54,13 @@ namespace FactorySelector // select by NPC flags if(!ai_factory) { - if(creature->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER) + if(creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER) ai_factory = ai_registry.GetRegistryItem("PetAI"); - else if(creature->isVehicle() || creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK)) + else if(creature->IsVehicle() || creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK)) ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); else if(creature->isGuard()) ai_factory = ai_registry.GetRegistryItem("GuardAI"); - else if(creature->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN)) + else if(creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) ai_factory = ai_registry.GetRegistryItem("PetAI"); else if(creature->isTotem()) ai_factory = ai_registry.GetRegistryItem("TotemAI"); @@ -71,7 +71,7 @@ namespace FactorySelector else ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); } - else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasSummonMask(SUMMON_MASK_GUARDIAN)) + else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) ai_factory = ai_registry.GetRegistryItem("CritterAI"); } diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 78a8689a6de..cb444bb3165 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -515,9 +515,9 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 Creature* pCreature = NULL; if (action.summon.duration) - pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); + pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); else - pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!pCreature) sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, EventId, m_creature->GetEntry()); diff --git a/src/game/Debugcmds.cpp b/src/game/Debugcmds.cpp index b7c88b1ad04..c86632cf72e 100644 --- a/src/game/Debugcmds.cpp +++ b/src/game/Debugcmds.cpp @@ -705,7 +705,7 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/) bool ChatHandler::HandleDebugSetVehicleId(const char *args) { Unit* target = getSelectedUnit(); - if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle()) + if(!target || target->IsVehicle()) return false; if(!args) @@ -716,7 +716,7 @@ bool ChatHandler::HandleDebugSetVehicleId(const char *args) return false; uint32 id = (uint32)atoi(i); - ((Vehicle*)target)->SetVehicleId(id); + //target->SetVehicleId(id); target->SendUpdateObjectToAllExcept(NULL); PSendSysMessage("Vehicle id set to %u", id); return true; @@ -725,7 +725,7 @@ bool ChatHandler::HandleDebugSetVehicleId(const char *args) bool ChatHandler::HandleDebugEnterVehicle(const char * args) { Unit* target = getSelectedUnit(); - if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle()) + if(!target || !target->IsVehicle()) return false; if(!args) @@ -741,7 +741,7 @@ bool ChatHandler::HandleDebugEnterVehicle(const char * args) int8 seatId = j ? (int8)atoi(j) : -1; if(!entry) - m_session->GetPlayer()->EnterVehicle((Vehicle*)target, seatId); + m_session->GetPlayer()->EnterVehicle(target, seatId); else { Creature *passenger = NULL; @@ -750,7 +750,7 @@ bool ChatHandler::HandleDebugEnterVehicle(const char * args) m_session->GetPlayer()->VisitNearbyObject(30.0f, searcher); if(!passenger || passenger == target) return false; - passenger->EnterVehicle((Vehicle*)target, seatId); + passenger->EnterVehicle(target, seatId); } PSendSysMessage("Unit %u entered vehicle %d", entry, (int32)seatId); @@ -774,7 +774,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args) m_session->GetPlayer()->GetClosePoint(x, y, z, m_session->GetPlayer()->GetObjectSize()); if(!i) - return m_session->GetPlayer()->SummonVehicle(entry, x, y, z, o); + return m_session->GetPlayer()->SummonCreature(entry, x, y, z, o, 0); uint32 id = (uint32)atoi(i); @@ -788,7 +788,8 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args) if (!ve) return false; - Vehicle *v = new Vehicle; + Creature *v = new Creature; + Map *map = m_session->GetPlayer()->GetMap(); if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMask(), entry, id, m_session->GetPlayer()->GetTeam(), x, y, z, o)) diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index 5e40b8d81d9..11cbb741e45 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -162,7 +162,7 @@ MessageDistDeliverer::Visit(PlayerMapType &m) SendPacket(*i); } - if(target->m_seer == target || target->m_Vehicle) + if(target->m_seer == target || target->GetVehicle()) SendPacket(target); } } diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index ab226f9ab6c..ed4527dcc5b 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1016,7 +1016,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args) Map *map = chr->GetMap(); Creature* pCreature = new Creature; - if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval, x, y, z, o)) + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o)) { delete pCreature; return false; @@ -1269,7 +1269,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args) else unit = getSelectedCreature(); - if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle()) + if(!unit || unit->isPet() || unit->isTotem()) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); @@ -2848,7 +2848,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) wpCreature->AddObjectToRemoveList(); // re-create Creature* wpCreature2 = new Creature; - if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -3059,7 +3059,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) float o = chr->GetOrientation(); Creature* wpCreature = new Creature; - if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, x, y, z, o)) + if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -3113,7 +3113,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) Map *map = chr->GetMap(); Creature* pCreature = new Creature; - if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0, x, y, z, o)) + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete pCreature; @@ -3168,7 +3168,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) Map *map = chr->GetMap(); Creature* pCreature = new Creature; - if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, x, y, z, o)) + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete pCreature; @@ -4155,7 +4155,7 @@ bool ChatHandler::HandleTempAddSpwCommand(const char* args) uint32 id = atoi(charID); - chr->SummonCreature(id,x,y,z,ang,TEMPSUMMON_CORPSE_DESPAWN,120); + chr->SummonCreature(id,x,y,z,ang,0,TEMPSUMMON_CORPSE_DESPAWN,120); return true; } diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 3c1d383e95f..4621c38602b 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -465,7 +465,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) Loot *pLoot = NULL; - if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID())) + if(IS_CRE_OR_VEH_GUID(GetPlayer()->GetLootGUID())) { Creature *pCreature = GetPlayer()->GetMap()->GetCreature(lootguid); if(!pCreature) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index d4194243a0f..c8c7140b0e5 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -648,7 +648,7 @@ void Map::Update(const uint32 &t_diff) } } - if(plr->m_seer != plr && !plr->m_Vehicle) + if(plr->m_seer != plr && !plr->GetVehicle()) AddUnitToNotify(plr); } @@ -879,9 +879,9 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang AddUnitToNotify(creature); } - if(creature->isVehicle()) + if(creature->IsVehicle()) { - for(SeatMap::iterator itr = ((Vehicle*)creature)->m_Seats.begin(); itr != ((Vehicle*)creature)->m_Seats.end(); ++itr) + for(SeatMap::iterator itr = creature->GetVehicleKit()->m_Seats.begin(); itr != creature->GetVehicleKit()->m_Seats.end(); ++itr) if(Unit *passenger = itr->second.passenger) { if(passenger->GetTypeId() == TYPEID_PLAYER) @@ -2790,9 +2790,9 @@ void Map::ScriptsProcess() case HIGHGUID_PET: source = HashMapHolder<Pet>::Find(step.sourceGUID); break; - case HIGHGUID_VEHICLE: - source = HashMapHolder<Vehicle>::Find(step.sourceGUID); - break; + //case HIGHGUID_VEHICLE: + // source = HashMapHolder<Vehicle>::Find(step.sourceGUID); + // break; case HIGHGUID_PLAYER: source = HashMapHolder<Player>::Find(step.sourceGUID); break; @@ -2832,9 +2832,9 @@ void Map::ScriptsProcess() case HIGHGUID_PET: target = HashMapHolder<Pet>::Find(step.targetGUID); break; - case HIGHGUID_VEHICLE: - target = HashMapHolder<Vehicle>::Find(step.targetGUID); - break; + //case HIGHGUID_VEHICLE: + // target = HashMapHolder<Vehicle>::Find(step.targetGUID); + // break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder<Player>::Find(step.targetGUID); break; @@ -3531,10 +3531,8 @@ Creature* Map::GetCreature(uint64 guid) { Creature * ret = NULL; - if(IS_CREATURE_GUID(guid)) + if(IS_CRE_OR_VEH_GUID(guid)) ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL); - else if(IS_VEHICLE_GUID(guid)) - ret = ObjectAccessor::GetObjectInWorld(guid, (Vehicle*)NULL); if(!ret) return NULL; diff --git a/src/game/Map.h b/src/game/Map.h index 631e5264a2f..e9909b122a3 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -441,7 +441,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj double rand_chance() { return mtRand.randExc(100.0); } #endif - TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL); + TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle = 0, uint32 vehId = 0, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL); Creature* GetCreature(uint64 guid); GameObject* GetGameObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index bb494aed05a..0cdb489573a 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -93,7 +93,7 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) Creature *unit = NULL; GameObject *go = NULL; - if(IS_CREATURE_GUID(guid)) + if(IS_CRE_OR_VEH_GUID(guid)) { unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!unit) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 04033050b40..1b0922f1aa1 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -276,7 +276,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) } } - if(!mover->GetTransport() && !mover->m_Vehicle) + if(!mover->GetTransport() && !mover->GetVehicle()) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } else if (plMover && plMover->m_transport) // if we were on a transport, leave @@ -312,7 +312,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) mover->m_movementInfo = movementInfo; - if(mover->m_Vehicle) + if(mover->GetVehicle()) { mover->SetOrientation(movementInfo.o); return; @@ -515,7 +515,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE"); recv_data.hexlike(); - if(!GetPlayer()->m_Vehicle) + if(!GetPlayer()->GetVehicle()) return; if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_PREV_SEAT) @@ -529,7 +529,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) return; } else if(recv_data.GetOpcode() == CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE) - ReadMovementInfo(recv_data, &GetPlayer()->m_Vehicle->m_movementInfo); + ReadMovementInfo(recv_data, &GetPlayer()->GetVehicleBase()->m_movementInfo); uint64 guid; if(!recv_data.readPackGUID(guid)) @@ -540,11 +540,10 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) if(!guid) GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next - else if(Vehicle *vehicle = ObjectAccessor::GetVehicle(guid)) - { - if(vehicle->HasEmptySeat(seatId)) - GetPlayer()->EnterVehicle(vehicle, seatId); - } + else if(Unit *vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), guid)) + if(Vehicle *vehicle = vehUnit->GetVehicleKit()) + if(vehicle->HasEmptySeat(seatId)) + GetPlayer()->EnterVehicle(vehicle, seatId); } void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 71d922298dd..8b8bfec0c96 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -462,7 +462,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const // 0x80 if(flags & UPDATEFLAG_VEHICLE) // unused for now { - *data << uint32(((Vehicle*)this)->GetVehicleInfo()->m_ID); // vehicle id + *data << uint32(((Unit*)this)->GetVehicleKit()->GetVehicleInfo()->m_ID); // vehicle id *data << float(0); // facing adjustment } @@ -1746,27 +1746,27 @@ void WorldObject::AddObjectToRemoveList() map->AddObjectToRemoveList(this); } -TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties, uint32 duration, Unit *summoner) +TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float angle, uint32 vehId, SummonPropertiesEntry const *properties, uint32 duration, Unit *summoner) { - uint32 mask = SUMMON_MASK_SUMMON; + uint32 mask = UNIT_MASK_SUMMON; if(properties) { if(properties->Category == SUMMON_CATEGORY_PET || properties->Type == SUMMON_TYPE_GUARDIAN || properties->Type == SUMMON_TYPE_MINION) - mask = SUMMON_MASK_GUARDIAN; + mask = UNIT_MASK_GUARDIAN; else if(properties->Type == SUMMON_TYPE_TOTEM) - mask = SUMMON_MASK_TOTEM; + mask = UNIT_MASK_TOTEM; else if(properties->Category == SUMMON_CATEGORY_VEHICLE || properties->Type == SUMMON_TYPE_VEHICLE || properties->Type == SUMMON_TYPE_VEHICLE2) - mask = SUMMON_MASK_VEHICLE; + mask = UNIT_MASK_VEHICLE; else if(properties->Category == SUMMON_CATEGORY_PUPPET) - mask = SUMMON_MASK_PUPPET; + mask = UNIT_MASK_PUPPET; else if(properties->Type == SUMMON_TYPE_MINIPET) - mask = SUMMON_MASK_MINION; + mask = UNIT_MASK_MINION; else if (properties->Flags & 512) // Mirror Image, Summon Gargoyle - mask = SUMMON_MASK_GUARDIAN; + mask = UNIT_MASK_GUARDIAN; } uint32 phase = PHASEMASK_NORMAL, team = 0; @@ -1780,15 +1780,15 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a TempSummon *summon = NULL; switch(mask) { - case SUMMON_MASK_SUMMON: summon = new TempSummon (properties, summoner); break; - case SUMMON_MASK_GUARDIAN: summon = new Guardian (properties, summoner); break; - case SUMMON_MASK_PUPPET: summon = new Puppet (properties, summoner); break; - case SUMMON_MASK_TOTEM: summon = new Totem (properties, summoner); break; - case SUMMON_MASK_MINION: summon = new Minion (properties, summoner); break; + case UNIT_MASK_SUMMON: summon = new TempSummon (properties, summoner); break; + case UNIT_MASK_GUARDIAN: summon = new Guardian (properties, summoner); break; + case UNIT_MASK_PUPPET: summon = new Puppet (properties, summoner); break; + case UNIT_MASK_TOTEM: summon = new Totem (properties, summoner); break; + case UNIT_MASK_MINION: summon = new Minion (properties, summoner); break; default: return NULL; } - if(!summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team, x, y, z, angle)) + if(!summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, vehId, team, x, y, z, angle)) { delete summon; return NULL; @@ -1816,7 +1816,7 @@ void WorldObject::SetZoneScript() } } -TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, float ang, TempSummonType spwtype, uint32 duration) +TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, float ang, uint32 vehId, TempSummonType spwtype, uint32 duration) { Map *map = FindMap(); if(!map) @@ -1825,7 +1825,7 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, if (x == 0.0f && y == 0.0f && z == 0.0f) GetClosePoint(x, y, z, GetObjectSize()); - TempSummon *pCreature = map->SummonCreature(entry, x, y, z, ang, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL); + TempSummon *pCreature = map->SummonCreature(entry, x, y, z, ang, vehId, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL); if(!pCreature) return NULL; @@ -1834,41 +1834,6 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, return pCreature; } -Vehicle* WorldObject::SummonVehicle(uint32 entry, float x, float y, float z, float ang) -{ - CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); - if(!ci) - return NULL; - - uint32 id = ci->VehicleId; //temp store id here - if(!id) id = 156; - VehicleEntry const *ve = sVehicleStore.LookupEntry(id); - if(!ve) - return NULL; - - Vehicle *v = new Vehicle; - Map *map = GetMap(); - uint32 team = 0; - if (GetTypeId()==TYPEID_PLAYER) - team = ((Player*)this)->GetTeam(); - if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, GetPhaseMask(), entry, id, team, x, y, z, ang)) - { - delete v; - return NULL; - } - - if(isType(TYPEMASK_UNIT)) - { - v->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, GetGUID()); - //v->setFaction(((Unit*)this)->getFaction()); - } - map->Add((Creature*)v); - - //ObjectAccessor::UpdateObjectVisibility(v); - - return v; -} - Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration) { Pet* pet = new Pet(this, petType); diff --git a/src/game/Object.h b/src/game/Object.h index 63ee95fd5c6..3688f37c882 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -542,8 +542,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object void SetZoneScript(); ZoneScript * GetZoneScript() const { return m_zoneScript; } - 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); + TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, uint32 vehId = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0); + TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0) + { + return SummonCreature(id, x, y, z, ang, 0, spwtype, despwtime); + } 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); diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 602e6eb5391..f534a448a4c 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -61,9 +61,6 @@ ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) if(IS_PET_GUID(guid)) return GetPet(guid); - if(IS_VEHICLE_GUID(guid)) - return GetVehicle(guid); - return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; } @@ -232,12 +229,6 @@ ObjectAccessor::GetPet(uint64 guid) return GetObjectInWorld(guid, (Pet*)NULL); } -Vehicle* -ObjectAccessor::GetVehicle(uint64 guid) -{ - return GetObjectInWorld(guid, (Vehicle*)NULL); -} - Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) { @@ -491,7 +482,6 @@ template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock; template class HashMapHolder<Player>; template class HashMapHolder<Pet>; -template class HashMapHolder<Vehicle>; template class HashMapHolder<GameObject>; template class HashMapHolder<DynamicObject>; template class HashMapHolder<Creature>; @@ -499,7 +489,6 @@ template class HashMapHolder<Corpse>; template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); -template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/); template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/); template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/); template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 1941ccea30c..3979831657b 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -41,7 +41,6 @@ class Corpse; class Unit; class GameObject; class DynamicObject; -class Vehicle; class WorldObject; class Map; @@ -112,13 +111,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, return u; } - if(IS_CREATURE_GUID(guid)) - return (Unit*)HashMapHolder<Creature>::Find(guid); - if(IS_PET_GUID(guid)) return (Unit*)HashMapHolder<Pet>::Find(guid); - return (Unit*)HashMapHolder<Vehicle>::Find(guid); + return (Unit*)HashMapHolder<Creature>::Find(guid); } static Unit* GetUnitInOrOutOfWorld(uint64 guid, Unit* /*fake*/) @@ -173,7 +169,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); } static Corpse* GetCorpse(WorldObject const &u, uint64 guid); static Pet* GetPet(uint64 guid); - static Vehicle* GetVehicle(uint64 guid); static Player* FindPlayer(uint64); Player* FindPlayerByName(const char *name) ; diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h index 028367a7bf8..6a2eb7906eb 100644 --- a/src/game/ObjectDefines.h +++ b/src/game/ObjectDefines.h @@ -52,9 +52,10 @@ enum HighGuid #define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT ) #define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET ) #define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE ) -#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) ) +#define IS_CRE_OR_VEH_GUID(Guid) ( IS_CREATURE_GUID(Guid) || IS_VEHICLE_GUID(Guid) ) +#define IS_CRE_OR_VEH_OR_PET_GUID(Guid)( IS_CRE_OR_VEH_GUID(Guid) || IS_PET_GUID(Guid) ) #define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 ) -#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) ) +#define IS_UNIT_GUID(Guid) ( IS_CRE_OR_VEH_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) ) // special case for empty guid need check #define IS_ITEM_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_ITEM ) #define IS_GAMEOBJECT_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_GAMEOBJECT ) diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 82222f1e91e..db08590b354 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -139,28 +139,6 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> & } } -void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, CreatureMapType &m, uint32 &count, Map* map) -{ - for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid) - { - Creature* obj = new Creature; - uint32 guid = *i_guid; - //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid); - if(!obj->LoadFromDB(guid, map)) - { - delete obj; - obj = new Vehicle; - if(!((Vehicle*)obj)->LoadFromDB(guid, map)) - { - delete (Vehicle*)obj; - continue; - } - } - - AddObjectHelper(cell, m, count, map, obj); - } -} - void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map) { if(cell_corpses.empty()) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 820e52ec240..0cf38f470b3 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -6019,6 +6019,7 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) } return m_hiPetGuid++; case HIGHGUID_VEHICLE: + ASSERT(0); if(m_hiVehicleGuid>=0x00FFFFFF) { sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. "); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 3bce66a631a..75ae3a54bc2 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -46,13 +46,13 @@ m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL), m_owner(owner) { - m_summonMask |= SUMMON_MASK_PET; + m_unitTypeMask |= UNIT_MASK_PET; if(type == HUNTER_PET) - m_summonMask |= SUMMON_MASK_HUNTER_PET; + m_unitTypeMask |= UNIT_MASK_HUNTER_PET; - if (!(m_summonMask & SUMMON_MASK_CONTROLABLE_GUARDIAN)) + if (!(m_unitTypeMask & UNIT_MASK_CONTROLABLE_GUARDIAN)) { - m_summonMask |= SUMMON_MASK_CONTROLABLE_GUARDIAN; + m_unitTypeMask |= UNIT_MASK_CONTROLABLE_GUARDIAN; InitCharmInfo(); } @@ -780,14 +780,14 @@ bool Guardian::InitStatsForLevel(uint32 petlevel) //Determine pet type PetType petType = MAX_PET_TYPE; - if(HasSummonMask(SUMMON_MASK_PET) && m_owner->GetTypeId() == TYPEID_PLAYER) + if(HasUnitTypeMask(UNIT_MASK_PET) && m_owner->GetTypeId() == TYPEID_PLAYER) { if(m_owner->getClass() == CLASS_WARLOCK) petType = SUMMON_PET; else if(m_owner->getClass() == CLASS_HUNTER) { petType = HUNTER_PET; - m_summonMask |= SUMMON_MASK_HUNTER_PET; + m_unitTypeMask |= UNIT_MASK_HUNTER_PET; } else sLog.outError("Unknown type pet %u is summoned by player class %u", GetEntry(), m_owner->getClass()); diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 3b192fa13fb..9da36fc9215 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -175,7 +175,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) pet->setDeathState(CORPSE); } - else if(((Creature*)pet)->HasSummonMask(SUMMON_MASK_MINION)) + else if(((Creature*)pet)->HasUnitTypeMask(UNIT_MASK_MINION)) { ((Minion*)pet)->UnSummon(); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b21276c2e51..f3270e640bd 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14061,7 +14061,7 @@ void Player::KilledMonsterCredit( uint32 entry, uint64 guid ) void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id ) { - bool isCreature = IS_CREATURE_GUID(guid); + bool isCreature = IS_CRE_OR_VEH_GUID(guid); uint32 addCastCount = 1; for( uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) @@ -17111,9 +17111,9 @@ void Player::StopCastingCharm() if(charm->GetTypeId() == TYPEID_UNIT) { - if(((Creature*)charm)->HasSummonMask(SUMMON_MASK_PUPPET)) + if(((Creature*)charm)->HasUnitTypeMask(UNIT_MASK_PUPPET)) ((Puppet*)charm)->UnSummon(); - else if(((Creature*)charm)->isVehicle()) + else if(charm->IsVehicle()) ExitVehicle(); } if(GetCharmGUID()) @@ -17321,19 +17321,19 @@ void Player::PossessSpellInitialize() void Player::VehicleSpellInitialize() { - Unit* charm = m_Vehicle; - if(!charm) + Creature* veh = GetVehicleCreatureBase(); + if(!veh) return; WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*10+1+1); - data << uint64(charm->GetGUID()); + data << uint64(veh->GetGUID()); data << uint16(0); data << uint32(0); data << uint32(0x00000101); for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { - uint32 spellId = ((Creature*)charm)->m_spells[i]; + uint32 spellId = ((Creature*)veh)->m_spells[i]; if(!spellId) continue; @@ -17343,7 +17343,7 @@ void Player::VehicleSpellInitialize() if(IsPassiveSpell(spellId)) { - charm->CastSpell(charm, spellId, true); + veh->CastSpell(veh, spellId, true); data << uint16(0) << uint8(0) << uint8(i+8); } else @@ -19122,7 +19122,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObjec #endif } } - else //if(visibleNow.size() < 30 || target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isVehicle()) + else //if(visibleNow.size() < 30 || target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsVehicle()) { if(target->isVisibleForInState(this,false)) { @@ -19750,7 +19750,7 @@ void Player::UpdateForQuestWorldObjects() if(obj) obj->BuildValuesUpdateBlockForPlayer(&udata,this); } - else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr)) + else if(IS_CRE_OR_VEH_GUID(*itr)) { Creature *obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr); if(!obj) @@ -20252,14 +20252,14 @@ void Player::UpdateAreaDependentAuras( uint32 newArea ) if( !HasAura(itr->second->spellId) ) CastSpell(this,itr->second->spellId,true); - if(newArea == 4273 && m_Vehicle && GetPositionX() > 400) // Ulduar + if(newArea == 4273 && GetVehicle() && GetPositionX() > 400) // Ulduar { - switch(m_Vehicle->GetEntry()) + switch(GetVehicleBase()->GetEntry()) { case 33062: case 33109: case 33060: - m_Vehicle->Dismiss(); + GetVehicle()->Dismiss(); break; } } @@ -20532,7 +20532,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) // farsight dynobj or puppet may be very far away UpdateVisibilityOf(target); - if(target->isType(TYPEMASK_UNIT) && !m_Vehicle) + if(target->isType(TYPEMASK_UNIT) && !GetVehicle()) ((Unit*)target)->AddPlayerToVision(this); } else @@ -20545,7 +20545,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) return; } - if(target->isType(TYPEMASK_UNIT) && !m_Vehicle) + if(target->isType(TYPEMASK_UNIT) && !GetVehicle()) ((Unit*)target)->RemovePlayerFromVision(this); //must immediately set seer back otherwise may crash diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 204b8395fce..86f9669695d 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -595,7 +595,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket uint8 questStatus = DIALOG_STATUS_NONE; uint8 defstatus = DIALOG_STATUS_NONE; - if (IS_CREATURE_OR_PET_GUID(*itr)) + if (IS_CRE_OR_VEH_OR_PET_GUID(*itr)) { // need also pet quests case support Creature *questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(),*itr); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 07d69bf25bb..ff96db642a8 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1860,12 +1860,12 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) pushType = PUSH_CASTER_CENTER; break; case TARGET_UNIT_VEHICLE: - if(Vehicle *vehicle = m_caster->m_Vehicle) + if(Unit *vehicle = m_caster->GetVehicleBase()) AddUnitTarget(vehicle, i); break; case TARGET_UNIT_PASSENGER: - if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isVehicle()) - if(Unit *unit = ((Vehicle*)m_caster)->GetPassenger(1)) // maybe not right + if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsVehicle()) + if(Unit *unit = m_caster->GetVehicleKit()->GetPassenger(1)) // maybe not right AddUnitTarget(unit, i); break; } @@ -3275,7 +3275,7 @@ void Spell::update(uint32 difftime) for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { TargetInfo* target = &*ihit; - if(!IS_CREATURE_GUID(target->targetGUID)) + if(!IS_CRE_OR_VEH_GUID(target->targetGUID)) continue; Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID); @@ -3327,7 +3327,7 @@ void Spell::finish(bool ok) { if(Unit *charm = m_caster->GetCharm()) if(charm->GetTypeId() == TYPEID_UNIT - && ((Creature*)charm)->HasSummonMask(SUMMON_MASK_PUPPET) + && ((Creature*)charm)->HasUnitTypeMask(UNIT_MASK_PUPPET) && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id) ((Puppet*)charm)->UnSummon(); } @@ -5128,7 +5128,7 @@ SpellCastResult Spell::CheckCast(bool strict) if(Unit *target = m_targets.getUnitTarget()) { - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isVehicle()) + if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsVehicle()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; if(target->GetCharmerGUID()) @@ -6133,7 +6133,7 @@ bool Spell::CheckTarget(Unit* target, uint32 eff) case SPELL_AURA_MOD_CHARM: case SPELL_AURA_MOD_POSSESS_PET: case SPELL_AURA_AOE_CHARM: - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isVehicle()) + if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsVehicle()) return false; if(target->GetCharmerGUID()) return false; @@ -6600,7 +6600,7 @@ void Spell::SelectTrajTargets() UnitList::const_iterator itr = unitList.begin(); for(; itr != unitList.end(); ++itr) { - if(m_caster == *itr || m_caster == (*itr)->m_Vehicle || m_caster->m_Vehicle == *itr) + if(m_caster == *itr || m_caster->IsOnVehicle(*itr) || (*itr)->IsOnVehicle(m_caster)) continue; const float size = (*itr)->GetObjectSize() * 0.6f; // 1/sqrt(3) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 837b8323a60..344dd7f733a 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4487,8 +4487,8 @@ void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmoun if(m_target->GetAuras().count(62399) >= (m_target->GetMap()->IsHeroic() ? 4 : 2)) { m_target->CastSpell(m_target, 62475, true); // System Shutdown - if(m_target->m_Vehicle) - m_target->m_Vehicle->CastSpell(m_target, 62475, true); + if(Unit *veh = m_target->GetVehicleBase()) + veh->CastSpell(m_target, 62475, true); } } break; @@ -6619,27 +6619,25 @@ void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAm if(!Real) return; - if(m_target->GetTypeId() != TYPEID_UNIT || !((Creature*)m_target)->isVehicle()) + if(!m_target->IsVehicle()) return; Unit *caster = GetSource(); if(!caster || caster == m_target) return; - Vehicle * const vehicle = dynamic_cast<Vehicle * const>(m_target); - if (apply) { //if(caster->GetTypeId() == TYPEID_PLAYER) // if(Pet *pet = ((Player*)caster)->GetPet()) // pet->Remove(PET_SAVE_AS_CURRENT); - caster->EnterVehicle(vehicle, m_amount - 1); + caster->EnterVehicle(m_target->GetVehicleKit(), m_amount - 1); } else { if(GetId() == 53111) // Devour Humanoid { - vehicle->Kill(caster); + m_target->Kill(caster); if(caster->GetTypeId() == TYPEID_UNIT) ((Creature*)caster)->RemoveCorpse(); } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 2c748bba89d..d3a49bcba2e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1219,7 +1219,7 @@ void Spell::EffectDummy(uint32 i) case 62324: // Throw Passenger if(m_targets.HasTraj()) { - if(Vehicle *vehicle = dynamic_cast<Vehicle*>(m_caster)) + if(Vehicle *vehicle = m_caster->GetVehicleKit()) if(Unit *passenger = vehicle->GetPassenger(damage - 1)) { std::list<Unit*> unitList; @@ -1229,12 +1229,12 @@ void Spell::EffectDummy(uint32 i) Vehicle *target = NULL; for(std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) { - if(Vehicle *seat = dynamic_cast<Vehicle*>(*itr)) + if(Vehicle *seat = (*itr)->GetVehicleKit()) if(!seat->GetPassenger(0)) if(Unit *device = seat->GetPassenger(2)) if(!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) { - float dist = seat->GetExactDistSq(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + float dist = (*itr)->GetExactDistSq(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); if(dist < minDist) { minDist = dist; @@ -1242,7 +1242,7 @@ void Spell::EffectDummy(uint32 i) } } } - if(target && target->IsWithinDist2d(m_targets.m_destX, m_targets.m_destY, GetSpellRadius(m_spellInfo, i, false) * 2)) // now we use *2 because the location of the seat is not correct + if(target && target->GetBase()->IsWithinDist2d(m_targets.m_destX, m_targets.m_destY, GetSpellRadius(m_spellInfo, i, false) * 2)) // now we use *2 because the location of the seat is not correct passenger->EnterVehicle(target, 0); else { @@ -1888,8 +1888,8 @@ void Spell::EffectDummy(uint32 i) // Death Grip if(m_spellInfo->Id == 49560) { - if (unitTarget->m_Vehicle) - unitTarget->m_Vehicle->CastSpell(m_caster, damage, true); + if (Unit *unit = unitTarget->GetVehicleBase()) // what is this for? + unit->CastSpell(m_caster, damage, true); else unitTarget->CastSpell(m_caster, damage, true); return; @@ -3415,20 +3415,20 @@ void Spell::EffectSummonType(uint32 i) if(!m_originalCaster) return; - Vehicle *vehicle = m_originalCaster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation()); + Creature *vehicle = m_originalCaster->SummonCreature(entry, x, y, z, 0, 0); if(!vehicle) return; // this is for wintergrasp, need to find a better way // in the future, we can just use getsummoner - //vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_originalCasterGUID); + vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_originalCasterGUID); vehicle->setFaction(m_originalCaster->getFaction()); vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); break; } case SUMMON_TYPE_TOTEM: { - summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); + summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), 0, properties, duration, m_originalCaster); if(!summon || !summon->isTotem()) return; @@ -3456,8 +3456,8 @@ void Spell::EffectSummonType(uint32 i) } case SUMMON_TYPE_MINIPET: { - summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); - if(!summon || !summon->HasSummonMask(SUMMON_MASK_MINION)) + summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), 0, properties, duration, m_originalCaster); + if(!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION)) return; //summon->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as summon... @@ -3505,23 +3505,23 @@ void Spell::EffectSummonType(uint32 i) SummonGuardian(entry, properties); break; case SUMMON_CATEGORY_PUPPET: - summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); + summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), 0, properties, duration, m_originalCaster); break; case SUMMON_CATEGORY_VEHICLE: { float x, y, z; m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); - Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation()); - if(!vehicle) + Creature *vehicle = m_caster->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), 0); + if(!vehicle || !vehicle->IsVehicle()) return; - //vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); + vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); vehicle->setFaction(m_caster->getFaction()); vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); if(damage) m_caster->CastSpell(vehicle, damage, true); - m_caster->EnterVehicle(vehicle); + m_caster->EnterVehicle(vehicle->GetVehicleKit()); break; } } @@ -5286,8 +5286,8 @@ void Spell::EffectScriptEffect(uint32 effIndex) return; } case 62428: // Load into Catapult - if(Vehicle *demolisher = m_caster->m_Vehicle) - if(Vehicle *seat = dynamic_cast<Vehicle*>(m_caster)) + if(Unit *demolisher = m_caster->GetVehicleBase()) + if(Vehicle *seat = m_caster->GetVehicleKit()) if(Unit *passenger = seat->GetPassenger(0)) passenger->CastSpell(demolisher, damage, true); return; @@ -6986,14 +6986,14 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties float px, py, pz; GetSummonPosition(0, px, py, pz, radius, count); - TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster); + TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), 0, properties, duration, caster); if(!summon) return; - if(summon->HasSummonMask(SUMMON_MASK_GUARDIAN)) + if(summon->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) ((Guardian*)summon)->InitStatsForLevel(level); summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - if(summon->HasSummonMask(SUMMON_MASK_MINION) && m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + if(summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon)); summon->AI()->EnterEvadeMode(); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 500947a321c..d93716de0af 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -515,8 +515,8 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data ) } } - if(unit->isVehicle()) - _player->EnterVehicle((Vehicle*)unit); + if(unit->IsVehicle()) + _player->EnterVehicle(unit); unit->AI()->DoAction(EVENT_SPELLCLICK); } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 308387b4358..c0a1d4bdd37 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -3017,7 +3017,7 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp if(!sameCaster) { - if(spellInfo_1->AttributesEx & SPELL_ATTR_EX3_STACK_FOR_DIFF_CASTERS + if(spellInfo_1->AttributesEx & SPELL_ATTR_EX_STACK_FOR_DIFF_CASTERS || spellInfo_1->AttributesEx3 & SPELL_ATTR_EX3_STACK_FOR_DIFF_CASTERS) return true; diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 70d55cc55fb..ab7ebbcca3e 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -29,7 +29,7 @@ Creature(), m_type(TEMPSUMMON_MANUAL_DESPAWN), m_timer(0), m_lifetime(0) , m_Properties(properties) { m_summonerGUID = owner ? owner->GetGUID() : 0; - m_summonMask |= SUMMON_MASK_SUMMON; + m_unitTypeMask |= UNIT_MASK_SUMMON; } Unit* TempSummon::GetSummoner() const @@ -271,7 +271,7 @@ Minion::Minion(SummonPropertiesEntry const *properties, Unit *owner) : TempSummo , m_owner(owner) { assert(m_owner); - m_summonMask |= SUMMON_MASK_MINION; + m_unitTypeMask |= UNIT_MASK_MINION; m_followAngle = PET_FOLLOW_ANGLE; } @@ -309,10 +309,10 @@ void Minion::RemoveFromWorld() Guardian::Guardian(SummonPropertiesEntry const *properties, Unit *owner) : Minion(properties, owner) , m_bonusdamage(0) { - m_summonMask |= SUMMON_MASK_GUARDIAN; + m_unitTypeMask |= UNIT_MASK_GUARDIAN; if (properties && properties->Type == SUMMON_TYPE_PET) { - m_summonMask |= SUMMON_MASK_CONTROLABLE_GUARDIAN; + m_unitTypeMask |= UNIT_MASK_CONTROLABLE_GUARDIAN; InitCharmInfo(); } } @@ -323,7 +323,7 @@ void Guardian::InitStats(uint32 duration) InitStatsForLevel(m_owner->getLevel()); - if(m_owner->GetTypeId() == TYPEID_PLAYER && HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN)) + if(m_owner->GetTypeId() == TYPEID_PLAYER && HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) m_charmInfo->InitCharmCreateSpells(); SetReactState(REACT_AGGRESSIVE); @@ -333,7 +333,7 @@ Puppet::Puppet(SummonPropertiesEntry const *properties, Unit *owner) : Minion(pr { assert(owner->GetTypeId() == TYPEID_PLAYER); m_owner = (Player*)owner; - m_summonMask |= SUMMON_MASK_PUPPET; + m_unitTypeMask |= UNIT_MASK_PUPPET; } void Puppet::InitStats(uint32 duration) diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index d35ba9e30b9..aba3550ab5a 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -28,7 +28,7 @@ Totem::Totem(SummonPropertiesEntry const *properties, Unit *owner) : Minion(properties, owner) { - m_summonMask |= SUMMON_MASK_TOTEM; + m_unitTypeMask |= UNIT_MASK_TOTEM; m_duration = 0; m_type = TOTEM_PASSIVE; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3a99ec8c22f..55435379a73 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -81,8 +81,8 @@ static bool procPrepared = InitTriggerAuraData(); Unit::Unit() : WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this) , m_NotifyListPos(-1), m_Notified(false), IsAIEnabled(false), NeedChangeAI(false) -, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_Vehicle(NULL), m_transport(NULL) -, m_ControlledByPlayer(false), m_procDeep(0) +, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_vehicle(NULL), m_transport(NULL) +, m_ControlledByPlayer(false), m_procDeep(0), m_unitTypeMask(UNIT_MASK_NONE), m_vehicleKit(NULL) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; @@ -192,6 +192,7 @@ Unit::~Unit() _DeleteAuras(); if(m_charmInfo) delete m_charmInfo; + if(m_vehicleKit) delete m_vehicleKit; assert(!m_attacking); assert(m_attackers.empty()); @@ -430,16 +431,16 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end) addUnitState(UNIT_STAT_MOVE); } -void Unit::SendMonsterMoveTransport(Vehicle *vehicle) +void Unit::SendMonsterMoveTransport(Unit *vehicleOwner) { - WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicle->GetPackGUID().size()); + WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size()); data.append(GetPackGUID()); - data.append(vehicle->GetPackGUID()); + data.append(vehicleOwner->GetPackGUID()); data << int8(GetTransSeat()); data << uint8(0); - data << GetPositionX() - vehicle->GetPositionX(); - data << GetPositionY() - vehicle->GetPositionY(); - data << GetPositionZ() - vehicle->GetPositionZ(); + data << GetPositionX() - vehicleOwner->GetPositionX(); + data << GetPositionY() - vehicleOwner->GetPositionY(); + data << GetPositionZ() - vehicleOwner->GetPositionZ(); data << uint32(getMSTime()); data << uint8(4); data << GetTransOffsetO(); @@ -8502,7 +8503,7 @@ Minion *Unit::GetFirstMinion() const if(uint64 pet_guid = GetMinionGUID()) { if(Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid)) - if(pet->HasSummonMask(SUMMON_MASK_MINION)) + if(pet->HasUnitTypeMask(UNIT_MASK_MINION)) return (Minion*)pet; sLog.outError("Unit::GetFirstMinion: Minion %u not exist.",GUID_LOPART(pet_guid)); @@ -8517,7 +8518,7 @@ Guardian* Unit::GetGuardianPet() const if(uint64 pet_guid = GetPetGUID()) { if(Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid)) - if(pet->HasSummonMask(SUMMON_MASK_GUARDIAN)) + if(pet->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) return (Guardian*)pet; sLog.outError("Unit::GetGuardianPet: Guardian %u not exist.",GUID_LOPART(pet_guid)); @@ -8584,7 +8585,7 @@ void Unit::SetMinion(Minion *minion, bool apply) } } - if(minion->HasSummonMask(SUMMON_MASK_GUARDIAN)) + if(minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) { if(AddUInt64Value(UNIT_FIELD_SUMMON, minion->GetGUID())) { @@ -8597,7 +8598,7 @@ void Unit::SetMinion(Minion *minion, bool apply) minion->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1)); // FIXME: hack, speed must be set only at follow - if(GetTypeId() == TYPEID_PLAYER && minion->HasSummonMask(SUMMON_MASK_PET)) + if(GetTypeId() == TYPEID_PLAYER && minion->HasUnitTypeMask(UNIT_MASK_PET)) for(uint8 i = 0; i < MAX_MOVE_TYPE; ++i) minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true); @@ -8643,7 +8644,7 @@ void Unit::SetMinion(Minion *minion, bool apply) } } - //if(minion->HasSummonMask(SUMMON_MASK_GUARDIAN)) + //if(minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) { if(RemoveUInt64Value(UNIT_FIELD_SUMMON, minion->GetGUID())) { @@ -8664,13 +8665,13 @@ void Unit::SetMinion(Minion *minion, bool apply) } assert((*itr)->GetTypeId() == TYPEID_UNIT); - if(!((Creature*)(*itr))->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN)) + if(!((Creature*)(*itr))->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) continue; if(AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID())) { //show another pet bar if there is no charm bar - if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID() && ((Creature*)(*itr))->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN)) + if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID() && ((Creature*)(*itr))->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) { if(((Creature*)(*itr))->isPet()) ((Player*)this)->PetSpellInitialize(); @@ -8761,7 +8762,7 @@ void Unit::SetCharm(Unit* charm, bool apply) sLog.outCrash("Unit %u is being uncharmed, but it has another charmer %u", charm->GetEntry(), charm->GetCharmerGUID()); if(charm->GetTypeId() == TYPEID_PLAYER - || !((Creature*)charm)->HasSummonMask(SUMMON_MASK_MINION) + || !((Creature*)charm)->HasUnitTypeMask(UNIT_MASK_MINION) || charm->GetOwnerGUID() != GetGUID()) m_Controlled.erase(charm); } @@ -8865,7 +8866,7 @@ void Unit::RemoveAllControlled() } else if(target->GetOwnerGUID() == GetGUID() && target->GetTypeId() == TYPEID_UNIT - && ((Creature*)target)->HasSummonMask(SUMMON_MASK_SUMMON)) + && ((Creature*)target)->HasUnitTypeMask(UNIT_MASK_SUMMON)) { ((TempSummon*)target)->UnSummon(); } @@ -9303,7 +9304,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); // Pets just add their bonus damage to their spell damage // note that their spell damage is just gain of their own auras - if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN)) + if (HasUnitTypeMask(UNIT_MASK_GUARDIAN)) DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage(); // Check for table values @@ -10599,8 +10600,8 @@ bool Unit::canAttack(Unit const* target, bool force) const if(target->GetVisibility() == VISIBILITY_GROUP_STEALTH && !canDetectStealthOf(target, GetDistance(target))) return false; - if(m_Vehicle) - if(target == m_Vehicle || m_Vehicle->m_Vehicle && target == m_Vehicle->m_Vehicle) + if(m_vehicle) + if(IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target)) return false; return true; @@ -10891,9 +10892,8 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) non_stack_bonus = (100.0 + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK))/100.0f; // Update speed for vehicle if avalible - if (GetTypeId()==TYPEID_PLAYER) - if (Unit * vehicle = ((Player*)this)->m_Vehicle) - vehicle->UpdateSpeed(MOVE_FLIGHT, true); + if (GetTypeId()==TYPEID_PLAYER && GetVehicle()) + GetVehicleBase()->UpdateSpeed(MOVE_FLIGHT, true); break; } default: @@ -11095,12 +11095,14 @@ void Unit::setDeathState(DeathState s) ClearDiminishings(); GetMotionMaster()->Clear(false); GetMotionMaster()->MoveIdle(); + if(m_vehicleKit) m_vehicleKit->Die(); //without this when removing IncreaseMaxHealth aura player may stuck with 1 hp //do not why since in IncreaseMaxHealth currenthealth is checked SetHealth(0); } else if(s == JUST_ALIVED) { + if(m_vehicleKit) m_vehicleKit->Reset(); RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) } @@ -11133,11 +11135,11 @@ bool Unit::CanHaveThreatList() const return false; // vehicles can not have threat list - //if( ((Creature*)this)->isVehicle() ) + //if( ((Creature*)this)->IsVehicle() ) // return false; // summons can not have a threat list, unless they are controlled by a creature - if( ((Creature*)this)->HasSummonMask(SUMMON_MASK_MINION | SUMMON_MASK_GUARDIAN | SUMMON_MASK_CONTROLABLE_GUARDIAN) && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) ) + if( HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN) && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) ) return false; return true; @@ -11322,11 +11324,12 @@ Unit* Creature::SelectVictim() // Note: creature not have targeted movement generator but have attacker in this case for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) { - if(canCreatureAttack(*itr) && ((*itr)->GetTypeId() != TYPEID_PLAYER && (!((Creature*)(*itr))->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN)))) + if(canCreatureAttack(*itr) && ((*itr)->GetTypeId() != TYPEID_PLAYER && (!((Creature*)(*itr))->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)))) return NULL; } - if(m_Vehicle) + // TODO: a vehicle may eat some mob, so mob should not evade + if(GetVehicle()) return NULL; // search nearby enemy before enter evade mode @@ -12120,6 +12123,8 @@ void Unit::AddToWorld() assert(m_NotifyListPos < 0); //instance : crash //m_NotifyListPos = -1; SetToNotify(); + if(IsVehicle()) + GetVehicleKit()->Install(); } } @@ -12130,6 +12135,9 @@ void Unit::RemoveFromWorld() if(IsInWorld()) { + if(IsVehicle()) + GetVehicleKit()->Uninstall(); + RemoveCharmAuras(); RemoveBindSightAuras(); RemoveNotOwnSingleTargetAuras(); @@ -12191,7 +12199,7 @@ void Unit::UpdateCharmAI() if(isCharmed()) { i_disabledAI = i_AI; - if(isPossessed() || ((Creature*)this)->isVehicle()) + if(isPossessed() || IsVehicle()) i_AI = new PossessedAI((Creature*)this); else i_AI = new PetAI((Creature*)this); @@ -13847,7 +13855,7 @@ void Unit::SetControlled(bool apply, UnitState state) { case UNIT_STAT_STUNNED: if(HasAuraType(SPELL_AURA_MOD_STUN)) return; else SetStunned(false); break; - case UNIT_STAT_ROOT: if(HasAuraType(SPELL_AURA_MOD_ROOT) || m_Vehicle) return; + case UNIT_STAT_ROOT: if(HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle()) return; else SetRooted(false); break; case UNIT_STAT_CONFUSED:if(HasAuraType(SPELL_AURA_MOD_CONFUSE)) return; else SetConfused(false); break; @@ -14000,7 +14008,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) return false; assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER); - assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle()); + assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && IsVehicle()); sLog.outDebug("SetCharmedBy: charmer %u, charmed %u, type %u.", charmer->GetEntry(), GetEntry(), (uint32)type); @@ -14128,7 +14136,7 @@ void Unit::RemoveCharmedBy(Unit *charmer) CharmType type; if(hasUnitState(UNIT_STAT_POSSESSED)) type = CHARM_TYPE_POSSESS; - else if(this == charmer->m_Vehicle) + else if(charmer->IsOnVehicle(this)) type = CHARM_TYPE_VEHICLE; else type = CHARM_TYPE_CHARM; @@ -14169,7 +14177,7 @@ void Unit::RemoveCharmedBy(Unit *charmer) return; assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER); - assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle()); + assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && IsVehicle()); charmer->SetCharm(this, false); @@ -14219,7 +14227,7 @@ void Unit::RestoreFaction() ((Player*)this)->setFactionForRace(getRace()); else { - if(((Creature*)this)->HasSummonMask(SUMMON_MASK_MINION)) + if(HasUnitTypeMask(UNIT_MASK_MINION)) { if(Unit* owner = GetOwner()) { @@ -14233,6 +14241,31 @@ void Unit::RestoreFaction() } } +bool Unit::CreateVehicleKit(uint32 id) +{ + VehicleEntry const *vehInfo = sVehicleStore.LookupEntry(id); + if(!vehInfo) + return false; + + m_vehicleKit = new Vehicle(this, vehInfo); + m_updateFlag |= UPDATEFLAG_VEHICLE; + m_unitTypeMask |= UNIT_MASK_VEHICLE; + return true; +} + +Unit *Unit::GetVehicleBase() const +{ + return m_vehicle ? m_vehicle->GetBase() : NULL; +} + +Creature *Unit::GetVehicleCreatureBase() const +{ + Unit *veh = GetVehicleBase(); + if(veh->GetTypeId() == TYPEID_UNIT) + return (Creature*)veh; + return NULL; +} + bool Unit::IsInPartyWith(Unit const *unit) const { if(this == unit) @@ -14619,23 +14652,23 @@ void Unit::JumpTo(WorldObject *obj, float speedZ) void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId) { - if(!isAlive() || this == vehicle) + if(!isAlive() || GetVehicleKit() == vehicle) return; - if(m_Vehicle) + if(m_vehicle) { - if(m_Vehicle == vehicle) + if(m_vehicle == vehicle) { if(seatId >= 0) { - sLog.outDebug("EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_Vehicle->GetEntry(), GetTransSeat(), seatId); + sLog.outDebug("EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId); ChangeSeat(seatId); } return; } else { - sLog.outDebug("EnterVehicle: %u exit %u and enter %u.", GetEntry(), m_Vehicle->GetEntry(), vehicle->GetEntry()); + sLog.outDebug("EnterVehicle: %u exit %u and enter %u.", GetEntry(), m_vehicle->GetBase()->GetEntry(), vehicle->GetBase()->GetEntry()); ExitVehicle(); } } @@ -14646,11 +14679,11 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId) ((Player*)this)->StopCastingBindSight(); } - assert(!m_Vehicle); - m_Vehicle = vehicle; - if(!m_Vehicle->AddPassenger(this, seatId)) + assert(!m_vehicle); + m_vehicle = vehicle; + if(!m_vehicle->AddPassenger(this, seatId)) { - m_Vehicle = NULL; + m_vehicle = NULL; return; } @@ -14668,35 +14701,35 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId) void Unit::ChangeSeat(int8 seatId, bool next) { - if(!m_Vehicle) + if(!m_vehicle) return; if(seatId < 0) { - seatId = m_Vehicle->GetNextEmptySeat(GetTransSeat(), next); + seatId = m_vehicle->GetNextEmptySeat(GetTransSeat(), next); if(seatId < 0) return; } - else if(seatId == GetTransSeat() || !m_Vehicle->HasEmptySeat(seatId)) + else if(seatId == GetTransSeat() || !m_vehicle->HasEmptySeat(seatId)) return; - m_Vehicle->RemovePassenger(this); - if(!m_Vehicle->AddPassenger(this, seatId)) + m_vehicle->RemovePassenger(this); + if(!m_vehicle->AddPassenger(this, seatId)) assert(false); } void Unit::ExitVehicle() { - if(!m_Vehicle) + if(!m_vehicle) return; //sLog.outError("exit vehicle"); - m_Vehicle->RemovePassenger(this); + m_vehicle->RemovePassenger(this); // This should be done before dismiss, because there may be some aura removal - Vehicle *vehicle = m_Vehicle; - m_Vehicle = NULL; + Vehicle *vehicle = m_vehicle; + m_vehicle = NULL; SetControlled(false, UNIT_STAT_ROOT); @@ -14708,7 +14741,7 @@ void Unit::ExitVehicle() m_movementInfo.t_time = 0; m_movementInfo.t_seat = 0; - Relocate(vehicle->GetPositionX(), vehicle->GetPositionY(), vehicle->GetPositionZ(), GetOrientation()); + Relocate(vehicle->GetBase()); //Send leave vehicle, not correct if(GetTypeId() == TYPEID_PLAYER) @@ -14721,7 +14754,7 @@ void Unit::ExitVehicle() BuildHeartBeatMsg(&data); SendMessageToSet(&data, false); - if(vehicle->GetOwnerGUID() == GetGUID()) + if(vehicle->GetBase()->GetOwnerGUID() == GetGUID()) vehicle->Dismiss(); } @@ -14755,8 +14788,8 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const // 0x00000200 if(GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT) { - if(m_Vehicle) - data->append(m_Vehicle->GetPackGUID()); + if(m_vehicle) + data->append(m_vehicle->GetBase()->GetPackGUID()); else if(GetTransport()) data->append(GetTransport()->GetPackGUID()); else diff --git a/src/game/Unit.h b/src/game/Unit.h index b8784f1aca7..270d8de883b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -36,7 +36,6 @@ #include "DBCStructure.h" #include <list> -class Vehicle; #define WORLD_TRIGGER 12999 @@ -326,6 +325,7 @@ class Minion; class Guardian; class UnitAI; class Transport; +class Vehicle; struct SpellImmune { @@ -744,6 +744,21 @@ struct MovementInfo bool HasMovementFlag(uint32 flag) const { return flags & flag; } }; +enum UnitTypeMask +{ + UNIT_MASK_NONE = 0x00000000, + UNIT_MASK_SUMMON = 0x00000001, + UNIT_MASK_MINION = 0x00000002, + UNIT_MASK_GUARDIAN = 0x00000004, + UNIT_MASK_TOTEM = 0x00000008, + UNIT_MASK_PET = 0x00000010, + UNIT_MASK_VEHICLE = 0x00000020, + UNIT_MASK_PUPPET = 0x00000040, + UNIT_MASK_HUNTER_PET = 0x00000080, + UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100, + UNIT_MASK_ACCESSORY = 0x00000200, +}; + enum DiminishingLevels { DIMINISHING_LEVEL_1 = 0, @@ -1125,6 +1140,15 @@ class TRINITY_DLL_SPEC Unit : public WorldObject UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0; } + uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; } + void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; } + bool isSummon() const { return m_unitTypeMask & UNIT_MASK_SUMMON; } + bool isGuardian() const { return m_unitTypeMask & UNIT_MASK_GUARDIAN; } + bool isPet() const { return m_unitTypeMask & UNIT_MASK_PET; } + bool isHunterPet() const{ return m_unitTypeMask & UNIT_MASK_HUNTER_PET; } + bool isTotem() const { return m_unitTypeMask & UNIT_MASK_TOTEM; } + bool IsVehicle() const { return m_unitTypeMask & UNIT_MASK_VEHICLE; } + uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); } virtual uint32 getLevelForTarget(Unit const* /*target*/) const { return getLevel(); } void SetLevel(uint32 lvl); @@ -1363,7 +1387,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); - void SendMonsterMoveTransport(Vehicle *vehicle); + void SendMonsterMoveTransport(Unit *vehicleOwner); void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); void SendMovementFlagUpdate(); @@ -1811,7 +1835,12 @@ class TRINITY_DLL_SPEC Unit : public WorldObject bool IsAIEnabled, NeedChangeAI; MovementInfo m_movementInfo; - Vehicle *m_Vehicle; + bool CreateVehicleKit(uint32 id); + Vehicle *GetVehicleKit()const { return m_vehicleKit; } + Vehicle *GetVehicle() const { return m_vehicle; } + bool IsOnVehicle(const Unit *unit) const { return m_vehicle == unit->GetVehicleKit(); } + Unit *GetVehicleBase() const; + Creature *GetVehicleCreatureBase() const; float GetTransOffsetX() const { return m_movementInfo.t_x; } float GetTransOffsetY() const { return m_movementInfo.t_y; } float GetTransOffsetZ() const { return m_movementInfo.t_z; } @@ -1821,6 +1850,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject bool m_ControlledByPlayer; + void EnterVehicle(Unit *base, int8 seatId = -1) { EnterVehicle(base->GetVehicleKit(), seatId); } void EnterVehicle(Vehicle *vehicle, int8 seatId = -1); void ExitVehicle(); void ChangeSeat(int8 seatId, bool next = true); @@ -1907,6 +1937,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject ThreatManager m_ThreatManager; + Vehicle *m_vehicle; + Vehicle *m_vehicleKit; + + uint32 m_unitTypeMask; + private: bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent ); bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); 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(); } diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index 075644e5cba..3a600625c7b 100644 --- a/src/game/Vehicle.h +++ b/src/game/Vehicle.h @@ -20,11 +20,10 @@ #define MANGOSSERVER_VEHICLE_H #include "ObjectDefines.h" -#include "Creature.h" -#include "Unit.h" struct VehicleEntry; struct VehicleSeatEntry; +class Unit; struct VehicleSeat { @@ -35,22 +34,19 @@ struct VehicleSeat typedef std::map<int8, VehicleSeat> SeatMap; -class TRINITY_DLL_SPEC Vehicle : public Creature +class TRINITY_DLL_SPEC Vehicle { public: - explicit Vehicle(); + explicit Vehicle(Unit *unit, VehicleEntry const *vehInfo); virtual ~Vehicle(); - void AddToWorld(); - void RemoveFromWorld(); + void Install(); + void Uninstall(); - bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, float x, float y, float z, float o, const CreatureData * data = NULL); - - void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState - void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update + void Reset(); + void Die(); VehicleEntry const *GetVehicleInfo() { return m_vehicleInfo; } - void SetVehicleId(uint32 vehicleid); bool HasEmptySeat(int8 seatId) const; Unit *GetPassenger(int8 seatId) const; @@ -61,23 +57,14 @@ class TRINITY_DLL_SPEC Vehicle : public Creature void InstallAllAccessories(); void Dismiss(); - bool LoadFromDB(uint32 guid, Map *map); - SeatMap m_Seats; + + Unit *GetBase() const { return me; } protected: + Unit *me; VehicleEntry const *m_vehicleInfo; uint32 m_usableSeatNum; void InstallAccessory(uint32 entry, int8 seatId); - - private: - void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called - { - assert(false); - } - void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called - { - assert(false); - } }; #endif diff --git a/src/game/Wintergrasp.cpp b/src/game/Wintergrasp.cpp index aa270041c3f..70f3c23acc2 100644 --- a/src/game/Wintergrasp.cpp +++ b/src/game/Wintergrasp.cpp @@ -369,8 +369,8 @@ void OPvPWintergrasp::OnCreatureCreate(Creature *creature, bool add) { if(CanBuildVehicle(workshop)) { - m_vehicles[team].insert((Vehicle*)creature); - //workshop->m_vehicles.insert((Vehicle*)creature); + m_vehicles[team].insert(creature); + //workshop->m_vehicles.insert(creature); } else { @@ -382,8 +382,8 @@ void OPvPWintergrasp::OnCreatureCreate(Creature *creature, bool add) // TODO: now you have to wait until the corpse of vehicle disappear to build a new one else { - m_vehicles[team].erase((Vehicle*)creature); - //if(!workshop->m_vehicles.erase((Vehicle*)creature)) + m_vehicles[team].erase(creature); + //if(!workshop->m_vehicles.erase(creature)) // sLog.outError("OPvPWintergrasp::OnCreatureCreate: a vehicle is removed but it does not have record in workshop!"); } } @@ -587,8 +587,8 @@ void OPvPWintergrasp::HandlePlayerLeaveZone(Player * plr, uint32 zone) { if(!plr->GetSession()->PlayerLogout()) { - if(plr->m_Vehicle) // dismiss in change zone case - plr->m_Vehicle->Dismiss(); + if(plr->GetVehicle()) // dismiss in change zone case + plr->GetVehicle()->Dismiss(); REMOVE_RANK_AURAS(plr); } plr->RemoveAura(SPELL_TENACITY); @@ -687,7 +687,7 @@ void OPvPWintergrasp::UpdateTenacityStack() if(newStack < 0) newStack = -newStack; for(PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) (*itr)->SetAuraStack(SPELL_TENACITY, *itr, newStack); - for(VehicleSet::iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) + for(CreatureSet::iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) (*itr)->SetAuraStack(SPELL_TENACITY_VEHICLE, *itr, newStack); } } @@ -695,10 +695,10 @@ void OPvPWintergrasp::UpdateTenacityStack() void OPvPWintergrasp::VehicleCastSpell(TeamId team, int32 spellId) const { if(spellId > 0) - for(VehicleSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) + for(CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) (*itr)->CastSpell(*itr, (uint32)spellId, true); else - for(VehicleSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) + for(CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) (*itr)->RemoveAura((uint32)-spellId); // by stack? } @@ -808,7 +808,7 @@ void OPvPWintergrasp::EndBattle() // destroyed all vehicles while(!m_vehicles[team].empty()) { - Vehicle *veh = *m_vehicles[team].begin(); + Creature *veh = *m_vehicles[team].begin(); m_vehicles[team].erase(m_vehicles[team].begin()); veh->CastSpell(veh, SPELL_SHUTDOWN_VEHICLE, true); } diff --git a/src/game/Wintergrasp.h b/src/game/Wintergrasp.h index 3aed89bbfcb..a8c4a5a12ce 100644 --- a/src/game/Wintergrasp.h +++ b/src/game/Wintergrasp.h @@ -140,8 +140,6 @@ typedef std::map<uint32, uint32> TeamPairMap; class SiegeWorkshop; -typedef std::set<Vehicle*> VehicleSet; - class OPvPWintergrasp : public OutdoorPvP { protected: @@ -179,7 +177,7 @@ class OPvPWintergrasp : public OutdoorPvP BuildingStateMap m_buildingStates; CreatureSet m_creatures; - VehicleSet m_vehicles[2]; + CreatureSet m_vehicles[2]; GameObjectSet m_gobjects; TeamPairMap m_creEntryPair, m_goDisplayPair; @@ -231,7 +229,7 @@ class SiegeWorkshop : public OPvPCapturePoint uint32 m_engGuid; Creature *m_engineer; uint32 m_workshopGuid; - //VehicleSet m_vehicles; + //CreatureSet m_vehicles; BuildingState *m_buildingState; protected: OPvPWintergrasp *m_wintergrasp; |