diff options
Diffstat (limited to 'src')
11 files changed, 75 insertions, 26 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 53370170c9e..03e50ee2a8a 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1251,7 +1251,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint3 if (!vehId) vehId = cinfo->VehicleId; - if (vehId && !CreateVehicleKit(vehId)) + if (vehId && !CreateVehicleKit(vehId, Entry)) vehId = 0; Object::_Create(guidlow, Entry, vehId ? HIGHGUID_VEHICLE : HIGHGUID_UNIT); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ef7c19c9cae..8a42d9c41dd 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11694,7 +11694,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) if (VehicleId) { - if (CreateVehicleKit(VehicleId)) + if (CreateVehicleKit(VehicleId, creatureEntry)) { GetVehicleKit()->Reset(); @@ -11708,7 +11708,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) plr->GetSession()->SendPacket(&data); // mounts can also have accessories - GetVehicleKit()->InstallAllAccessories(creatureEntry); + GetVehicleKit()->InstallAllAccessories(); } } } @@ -15683,13 +15683,13 @@ void Unit::RestoreFaction() } } -bool Unit::CreateVehicleKit(uint32 id) +bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry) { VehicleEntry const *vehInfo = sVehicleStore.LookupEntry(id); if (!vehInfo) return false; - m_vehicleKit = new Vehicle(this, vehInfo); + m_vehicleKit = new Vehicle(this, vehInfo, creatureEntry); m_updateFlag |= UPDATEFLAG_VEHICLE; m_unitTypeMask |= UNIT_MASK_VEHICLE; return true; @@ -16459,7 +16459,7 @@ bool Unit::CheckPlayerCondition(Player* pPlayer) bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) { bool success = false; - uint32 spellClickEntry = GetTypeId() == TYPEID_UNIT ? GetEntry() : GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); + uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->m_creatureEntry : GetEntry(); SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry); for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) { @@ -16477,7 +16477,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) uint8 i = 0; bool valid = false; while (i < MAX_SPELL_EFFECTS && !valid) - if (spellEntry->EffectApplyAuraName[i] == SPELL_AURA_CONTROL_VEHICLE) + if (spellEntry->EffectApplyAuraName[i++] == SPELL_AURA_CONTROL_VEHICLE) valid = true; if (!valid) @@ -16486,10 +16486,21 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) return false; } - caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID); + if (IsInMap(caster)) + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID); + else // This can happen during Player::_LoadAuras + { + int32 bp0 = seatId; + Aura::TryCreate(spellEntry, this, clicker, &bp0, NULL, origCasterGUID); + } } else - caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID); + { + if (IsInMap(caster)) + caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID); + else + Aura::TryCreate(spellEntry, this, clicker, NULL, NULL, origCasterGUID); + } success = true; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 3d7b9d6979d..97becdad1cc 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2039,7 +2039,7 @@ class Unit : public WorldObject Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; } bool IsAIEnabled, NeedChangeAI; - bool CreateVehicleKit(uint32 id); + bool CreateVehicleKit(uint32 id, uint32 creatureEntry); void RemoveVehicleKit(); Vehicle *GetVehicleKit()const { return m_vehicleKit; } Vehicle *GetVehicle() const { return m_vehicle; } diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index d3244cafad1..465d8cf12b4 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -27,7 +27,8 @@ #include "CreatureAI.h" #include "ZoneScript.h" -Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0), m_bonusHP(0) +Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo, uint32 creatureEntry) +: me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0), m_bonusHP(0), m_creatureEntry(creatureEntry) { for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i) { @@ -119,9 +120,11 @@ void Vehicle::Install() sScriptMgr->OnInstall(this); } -void Vehicle::InstallAllAccessories(uint32 entry) +void Vehicle::InstallAllAccessories() { - VehicleAccessoryList const* mVehicleList = sObjectMgr->GetVehicleAccessoryList(entry); + me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE); // We might have aura's saved in the DB with now invalid casters - remove + + VehicleAccessoryList const* mVehicleList = sObjectMgr->GetVehicleAccessoryList(m_creatureEntry); if (!mVehicleList) return; @@ -167,7 +170,7 @@ void Vehicle::Reset() } else { - InstallAllAccessories(me->GetEntry()); + InstallAllAccessories(); if (m_usableSeatNum) me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } @@ -528,3 +531,14 @@ SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger) return m_Seats.end(); } + +uint8 Vehicle::GetAvailableSeatCount() const +{ + uint8 ret = 0; + SeatMap::const_iterator itr; + for (itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) + if (!itr->second.passenger && (itr->second.seatInfo->CanEnterOrExit() || itr->second.seatInfo->IsUsableByOverride())) + ++ret; + + return ret; +}
\ No newline at end of file diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 8ec342e21e5..8b2acf9954e 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -113,14 +113,14 @@ class Vehicle friend class WorldSession; public: - explicit Vehicle(Unit *unit, VehicleEntry const *vehInfo); + explicit Vehicle(Unit *unit, VehicleEntry const *vehInfo, uint32 creatureEntry); virtual ~Vehicle(); void Install(); void Uninstall(); void Reset(); void Die(); - void InstallAllAccessories(uint32 entry); + void InstallAllAccessories(); Unit *GetBase() const { return me; } VehicleEntry const *GetVehicleInfo() const { return m_vehicleInfo; } @@ -128,6 +128,7 @@ class Vehicle bool HasEmptySeat(int8 seatId) const; Unit *GetPassenger(int8 seatId) const; int8 GetNextEmptySeat(int8 seatId, bool next) const; + uint8 GetAvailableSeatCount() const; bool AddPassenger(Unit *passenger, int8 seatId = -1); void EjectPassenger(Unit* passenger, Unit* controller); @@ -152,6 +153,7 @@ class Vehicle VehicleEntry const *m_vehicleInfo; uint32 m_usableSeatNum; // Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags uint32 m_bonusHP; + uint32 m_creatureEntry; // Can be different than me->GetBase()->GetEntry() in case of players void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime); }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 691c647862a..1ebf2fd1c86 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -790,12 +790,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureInfo const* cInfo) if (cInfo->rangeattacktime == 0) const_cast<CreatureInfo*>(cInfo)->rangeattacktime = BASE_ATTACK_TIME; - if (cInfo->npcflag & UNIT_NPC_FLAG_SPELLCLICK) - { - sLog->outErrorDb("Creature (Entry: %u) has dynamic flag UNIT_NPC_FLAG_SPELLCLICK (%u) set, it is expected to be set by code handling `npc_spellclick_spells` content.", cInfo->Entry, UNIT_NPC_FLAG_SPELLCLICK); - const_cast<CreatureInfo*>(cInfo)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK; - } - if ((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE) sLog->outErrorDb("Creature (Entry: %u) has wrong trainer type %u.", cInfo->Entry, cInfo->trainer_type); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 1681f6f78fd..470fffb4108 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6594,7 +6594,7 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const * aurApp, uint8 mode if (apply) { - if (!target->CreateVehicleKit(vehicleId)) + if (!target->CreateVehicleKit(vehicleId, 0)) return; } else if (target->GetVehicleKit()) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0b8276f2c74..e0f50baba41 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3177,6 +3177,34 @@ bool SpellMgr::CanAurasStack(Aura const *aura1, Aura const *aura2, bool sameCast } } + bool isVehicleAura1 = false; + bool isVehicleAura2 = false; + uint8 i = 0; + while (i < MAX_SPELL_EFFECTS && !(isVehicleAura1 && isVehicleAura2)) + { + if (spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_CONTROL_VEHICLE) + isVehicleAura1 = true; + if (spellInfo_2->EffectApplyAuraName[i] == SPELL_AURA_CONTROL_VEHICLE) + isVehicleAura2 = true; + + ++i; + } + + if (isVehicleAura1 && isVehicleAura2) + { + Vehicle* veh = NULL; + if (aura1->GetOwner()->ToUnit()) + veh = aura1->GetOwner()->ToUnit()->GetVehicleKit(); + + if (!veh) // We should probably just let it stack. Vehicle system will prevent undefined behaviour later + return true; + + if (!veh->GetAvailableSeatCount()) + return false; // No empty seat available + + return true; // Empty seat available (skip rest) + } + uint32 spellId_1 = GetLastSpellInChain(spellInfo_1->Id); uint32 spellId_2 = GetLastSpellInChain(spellInfo_2->Id); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index b7fa040b1bf..3c17a025022 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -162,7 +162,7 @@ class boss_ick : public CreatureScript void EnterCombat(Unit * /*who*/) { - _vehicle->InstallAllAccessories(me->GetEntry()); + _vehicle->InstallAllAccessories(); if (Creature* krick = GetKrick()) DoScriptText(SAY_KRICK_AGGRO, krick); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index cd436e1dc8f..a863b07dcf3 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -301,7 +301,7 @@ class boss_rimefang : public CreatureScript void JustReachedHome() { - _vehicle->InstallAllAccessories(me->GetEntry()); + _vehicle->InstallAllAccessories(); } void DoAction(const int32 actionId) diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp index b3a061bc9da..fb6053cc2c9 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp @@ -366,7 +366,7 @@ public: void SpellHit(Unit* /*caster*/, const SpellEntry* pSpell) { if (pSpell->Id == SPELL_START_THE_ENGINE) - vehicle->InstallAllAccessories(me->GetEntry()); + vehicle->InstallAllAccessories(); if (pSpell->Id == SPELL_ELECTROSHOCK) me->InterruptSpell(CURRENT_CHANNELED_SPELL); |