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:
Shauren
2011-04-22 21:59:37 +02:00
parent 7f73962c91
commit d73ffc9e81
14 changed files with 69 additions and 60 deletions
-2
View File
@@ -317,8 +317,6 @@ void VehicleAI::UpdateAI(const uint32 diff)
void VehicleAI::Reset()
{
me->SetVisible(true);
m_vehicle->Reset();
}
void VehicleAI::OnCharmed(bool apply)
+1 -1
View File
@@ -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)
+6 -1
View File
@@ -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);
}
}
+22 -1
View File
@@ -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);
}
}
}
+1
View File
@@ -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();
+20 -16
View File
@@ -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();
+9 -9
View File
@@ -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; }