Core/Vehicles:
* Added generic solution for vehicle accessories not relying on AI calls * Only accessories marked as minion will be respawned when the vehicle enters evade mode * Notify the summoner's AI when vehicle accessory fails to install and despawns
This commit is contained in:
@@ -317,8 +317,6 @@ void VehicleAI::UpdateAI(const uint32 diff)
|
||||
void VehicleAI::Reset()
|
||||
{
|
||||
me->SetVisible(true);
|
||||
|
||||
m_vehicle->Reset();
|
||||
}
|
||||
|
||||
void VehicleAI::OnCharmed(bool apply)
|
||||
|
||||
@@ -155,7 +155,7 @@ void CreatureAI::EnterEvadeMode()
|
||||
Reset();
|
||||
|
||||
if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
|
||||
me->GetVehicleKit()->Reset();
|
||||
me->GetVehicleKit()->Reset(true);
|
||||
}
|
||||
|
||||
/*void CreatureAI::AttackedBy(Unit* attacker)
|
||||
|
||||
@@ -549,8 +549,13 @@ inline bool CreatureAI::_EnterEvadeMode()
|
||||
if (!me->isAlive())
|
||||
return false;
|
||||
|
||||
// call specialized vehicle remove auras if creature is one
|
||||
if (!me->IsVehicle())
|
||||
me->RemoveAllAuras();
|
||||
else
|
||||
me->RemoveAllAurasExceptVehicle();
|
||||
|
||||
// sometimes bosses stuck in combat?
|
||||
me->RemoveAllAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
me->LoadCreaturesAddon();
|
||||
|
||||
@@ -516,9 +516,6 @@ void BossAI::_Reset()
|
||||
if (!me->isAlive())
|
||||
return;
|
||||
|
||||
if (me->GetVehicleKit())
|
||||
me->GetVehicleKit()->Reset();
|
||||
|
||||
me->ResetLootMode();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
@@ -431,6 +431,8 @@ void Creature::Update(uint32 diff)
|
||||
{
|
||||
TriggerJustRespawned = false;
|
||||
AI()->JustRespawned();
|
||||
if (m_vehicleKit)
|
||||
m_vehicleKit->Reset();
|
||||
}
|
||||
|
||||
switch(m_deathState)
|
||||
@@ -712,6 +714,9 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
|
||||
delete oldAI;
|
||||
IsAIEnabled = true;
|
||||
i_AI->InitializeAI();
|
||||
// Initialize vehicle
|
||||
if (GetVehicleKit())
|
||||
GetVehicleKit()->Reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1553,7 +1558,6 @@ void Creature::setDeathState(DeathState s)
|
||||
Motion_Initialize();
|
||||
if (GetCreatureData() && GetPhaseMask() != GetCreatureData()->phaseMask)
|
||||
SetPhaseMask(GetCreatureData()->phaseMask, false);
|
||||
if (m_vehicleKit) m_vehicleKit->Reset();
|
||||
Unit::setDeathState(ALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4010,6 +4010,27 @@ void Unit::RemoveAllAurasRequiringDeadTarget()
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAllAurasExceptVehicle()
|
||||
{
|
||||
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
|
||||
{
|
||||
Aura const* aura = iter->second->GetBase();
|
||||
if (!IsSpellHaveAura(aura->GetSpellProto(), SPELL_AURA_CONTROL_VEHICLE))
|
||||
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
||||
for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
|
||||
{
|
||||
Aura* aura = iter->second;
|
||||
if (!IsSpellHaveAura(aura->GetSpellProto(), SPELL_AURA_CONTROL_VEHICLE))
|
||||
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime)
|
||||
{
|
||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);++iter)
|
||||
@@ -11755,7 +11776,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
|
||||
// mounts can also have accessories
|
||||
GetVehicleKit()->InstallAllAccessories();
|
||||
GetVehicleKit()->InstallAllAccessories(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1664,6 +1664,7 @@ class Unit : public WorldObject
|
||||
void RemoveArenaAuras(bool onleave = false);
|
||||
void RemoveAllAurasOnDeath();
|
||||
void RemoveAllAurasRequiringDeadTarget();
|
||||
void RemoveAllAurasExceptVehicle();
|
||||
void DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime);
|
||||
|
||||
void _RemoveAllAuraStatMods();
|
||||
|
||||
@@ -118,16 +118,18 @@ void Vehicle::Install()
|
||||
sScriptMgr->OnInstall(this);
|
||||
}
|
||||
|
||||
void Vehicle::InstallAllAccessories()
|
||||
void Vehicle::InstallAllAccessories(bool evading)
|
||||
{
|
||||
RemoveAllPassengers(); // We might have aura's saved in the DB with now invalid casters - remove
|
||||
if (GetBase()->GetTypeId() == TYPEID_PLAYER || !evading)
|
||||
RemoveAllPassengers(); // We might have aura's saved in the DB with now invalid casters - remove
|
||||
|
||||
VehicleAccessoryList const* mVehicleList = sObjectMgr->GetVehicleAccessoryList(this);
|
||||
if (!mVehicleList)
|
||||
VehicleAccessoryList const* accessories = sObjectMgr->GetVehicleAccessoryList(this);
|
||||
if (!accessories)
|
||||
return;
|
||||
|
||||
for (VehicleAccessoryList::const_iterator itr = mVehicleList->begin(); itr != mVehicleList->end(); ++itr)
|
||||
InstallAccessory(itr->uiAccessory, itr->uiSeat, itr->bMinion, itr->uiSummonType, itr->uiSummonTime);
|
||||
for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
|
||||
if (!evading || itr->IsMinion) // only install minions on evade mode
|
||||
InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
|
||||
}
|
||||
|
||||
void Vehicle::Uninstall()
|
||||
@@ -139,7 +141,7 @@ void Vehicle::Uninstall()
|
||||
sScriptMgr->OnUninstall(this);
|
||||
}
|
||||
|
||||
void Vehicle::Reset()
|
||||
void Vehicle::Reset(bool evading /*= false*/)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Reset Entry: %u, GuidLow: %u", m_creatureEntry, me->GetGUIDLow());
|
||||
if (me->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -149,7 +151,7 @@ void Vehicle::Reset()
|
||||
}
|
||||
else
|
||||
{
|
||||
InstallAllAccessories();
|
||||
InstallAllAccessories(evading);
|
||||
if (m_usableSeatNum)
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
@@ -222,7 +224,7 @@ int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
|
||||
void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle: Installing accessory entry %u on vehicle entry %u (seat:%i)", entry, GetCreatureEntry(), seatId);
|
||||
if (Unit *passenger = GetPassenger(seatId))
|
||||
if (Unit* passenger = GetPassenger(seatId))
|
||||
{
|
||||
// already installed
|
||||
if (passenger->GetEntry() == entry)
|
||||
@@ -239,22 +241,24 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
|
||||
passenger->ExitVehicle(); // this should not happen
|
||||
}
|
||||
|
||||
if (Creature *accessory = me->SummonCreature(entry, *me, TempSummonType(type), summonTime))
|
||||
if (TempSummon *accessory = me->SummonCreature(entry, *me, TempSummonType(type), summonTime))
|
||||
{
|
||||
if (minion)
|
||||
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
|
||||
|
||||
if (!me->HandleSpellClick(accessory, seatId))
|
||||
{
|
||||
accessory->AddObjectToRemoveList();
|
||||
accessory->UnSummon();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!accessory->IsOnVehicle(me))
|
||||
{
|
||||
accessory->AddObjectToRemoveList();
|
||||
return; // Something went wrong in the spellsystem
|
||||
}
|
||||
// this cannot be checked instantly like this
|
||||
// spellsystem is delaying everything to next update tick
|
||||
//if (!accessory->IsOnVehicle(me))
|
||||
//{
|
||||
// accessory->UnSummon();
|
||||
// return; // Something went wrong in the spellsystem
|
||||
//}
|
||||
|
||||
// This is not good, we have to send update twice
|
||||
accessory->SendMovementFlagUpdate();
|
||||
|
||||
@@ -86,13 +86,13 @@ struct VehicleSeat
|
||||
|
||||
struct VehicleAccessory
|
||||
{
|
||||
explicit VehicleAccessory(uint32 _uiAccessory, int8 _uiSeat, bool _bMinion, uint8 _uiSummonType, uint32 _uiSummonTime) :
|
||||
uiAccessory(_uiAccessory), uiSeat(_uiSeat), bMinion(_bMinion), uiSummonType(_uiSummonType), uiSummonTime(_uiSummonTime) {}
|
||||
uint32 uiAccessory;
|
||||
int8 uiSeat;
|
||||
uint32 bMinion;
|
||||
uint8 uiSummonType;
|
||||
uint32 uiSummonTime;
|
||||
VehicleAccessory(uint32 entry, int8 seatId, bool isMinion, uint8 summonType, uint32 summonTime) :
|
||||
AccessoryEntry(entry), SeatId(seatId), IsMinion(isMinion), SummonedType(summonType), SummonTime(summonTime) {}
|
||||
uint32 AccessoryEntry;
|
||||
int8 SeatId;
|
||||
uint32 IsMinion;
|
||||
uint8 SummonedType;
|
||||
uint32 SummonTime;
|
||||
};
|
||||
|
||||
struct VehicleScalingInfo
|
||||
@@ -118,8 +118,8 @@ class Vehicle
|
||||
|
||||
void Install();
|
||||
void Uninstall();
|
||||
void Reset();
|
||||
void InstallAllAccessories();
|
||||
void Reset(bool evading = false);
|
||||
void InstallAllAccessories(bool evading);
|
||||
|
||||
Unit *GetBase() const { return me; }
|
||||
VehicleEntry const *GetVehicleInfo() const { return m_vehicleInfo; }
|
||||
|
||||
Reference in New Issue
Block a user