[c12602] Reorder handling in Creature::SetDeathState(JUST_ALIVE) case

This commit is contained in:
Schmoozerd 2013-05-31 11:35:36 +01:00 committed by Antz
parent 09063c60ae
commit ecb5342ed8
3 changed files with 119 additions and 83 deletions

View file

@ -2,7 +2,7 @@ This file contains the authors of the C(ontinued) MaNGOS project.
The project is currently hosted at http://cmangos.net The project is currently hosted at http://cmangos.net
The code of CMaNGOS is shipped as it is without any form of warrenty, The code of MaNGOS is shipped as it is without any form of warranty,
and - except for third party libraries - licensed under the GPL 2.0, and - except for third party libraries - licensed under the GPL 2.0,
which you can read from the file "COPYING" which you can read from the file "COPYING"

View file

@ -23,6 +23,7 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "SQLStorages.h"
#include "SpellMgr.h" #include "SpellMgr.h"
#include "QuestDef.h" #include "QuestDef.h"
#include "GossipDef.h" #include "GossipDef.h"
@ -50,7 +51,7 @@
#include "CreatureLinkingMgr.h" #include "CreatureLinkingMgr.h"
// apply implementation of the singletons // apply implementation of the singletons
#include "Policies/SingletonImp.h" #include "Policies/Singleton.h"
ObjectGuid CreatureData::GetObjectGuid(uint32 lowguid) const ObjectGuid CreatureData::GetObjectGuid(uint32 lowguid) const
{ {
@ -88,8 +89,11 @@ bool VendorItemData::RemoveItem(uint32 item_id, uint8 type)
VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint8 type, uint32 extendedCost) const VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint8 type, uint32 extendedCost) const
{ {
for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i) for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
{
// Skip checking for conditions, condition system is powerfull enough to not require additional entries only for the conditions
if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost && (*i)->type == type) if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost && (*i)->type == type)
return *i; return *i;
}
return NULL; return NULL;
} }
@ -158,6 +162,7 @@ bool CreatureCreatePos::Relocate(Creature* cr) const
Creature::Creature(CreatureSubtype subtype) : Unit(), Creature::Creature(CreatureSubtype subtype) : Unit(),
i_AI(NULL), i_AI(NULL),
loot(this),
lootForPickPocketed(false), lootForBody(false), lootForSkin(false), lootForPickPocketed(false), lootForBody(false), lootForSkin(false),
m_groupLootTimer(0), m_groupLootId(0), m_groupLootTimer(0), m_groupLootId(0),
m_lootMoney(0), m_lootGroupRecipientId(0), m_lootMoney(0), m_lootGroupRecipientId(0),
@ -170,6 +175,7 @@ Creature::Creature(CreatureSubtype subtype) : Unit(),
m_creatureInfo(NULL) m_creatureInfo(NULL)
{ {
m_regenTimer = 200; m_regenTimer = 200;
m_holyPowerRegenTimer = REGEN_TIME_HOLY_POWER;
m_valuesCount = UNIT_END; m_valuesCount = UNIT_END;
for (int i = 0; i < CREATURE_MAX_SPELLS; ++i) for (int i = 0; i < CREATURE_MAX_SPELLS; ++i)
@ -178,7 +184,7 @@ Creature::Creature(CreatureSubtype subtype) : Unit(),
m_CreatureSpellCooldowns.clear(); m_CreatureSpellCooldowns.clear();
m_CreatureCategoryCooldowns.clear(); m_CreatureCategoryCooldowns.clear();
SetWalk(true); SetWalk(true, true);
} }
Creature::~Creature() Creature::~Creature()
@ -234,6 +240,13 @@ void Creature::RemoveCorpse()
float x, y, z, o; float x, y, z, o;
GetRespawnCoord(x, y, z, &o); GetRespawnCoord(x, y, z, &o);
GetMap()->CreatureRelocation(this, x, y, z, o); GetMap()->CreatureRelocation(this, x, y, z, o);
// forced recreate creature object at clients
UnitVisibility currentVis = GetVisibility();
SetVisibility(VISIBILITY_REMOVE_CORPSE);
UpdateObjectVisibility();
SetVisibility(currentVis); // restore visibility state
UpdateObjectVisibility();
} }
/** /**
@ -327,7 +340,7 @@ bool Creature::InitEntry(uint32 Entry, CreatureData const* data /*=NULL*/, GameE
UpdateSpeed(MOVE_WALK, false); UpdateSpeed(MOVE_WALK, false);
UpdateSpeed(MOVE_RUN, false); UpdateSpeed(MOVE_RUN, false);
SetLevitate(CanFly()); SetLevitate(cinfo->InhabitType & INHABIT_AIR);
// checked at loading // checked at loading
m_defaultMovementType = MovementGeneratorType(cinfo->MovementType); m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
@ -392,10 +405,15 @@ bool Creature::UpdateEntry(uint32 Entry, Team team, const CreatureData* data /*=
SetPvP(false); SetPvP(false);
} }
// Try difficulty dependend version before falling back to base entry
CreatureTemplateSpells const* templateSpells = sCreatureTemplateSpellsStorage.LookupEntry<CreatureTemplateSpells>(GetCreatureInfo()->Entry);
if (!templateSpells)
templateSpells = sCreatureTemplateSpellsStorage.LookupEntry<CreatureTemplateSpells>(GetEntry());
if (templateSpells)
for (int i = 0; i < CREATURE_MAX_SPELLS; ++i) for (int i = 0; i < CREATURE_MAX_SPELLS; ++i)
m_spells[i] = GetCreatureInfo()->spells[i]; m_spells[i] = templateSpells->spells[i];
SetVehicleId(GetCreatureInfo()->vehicleId); SetVehicleId(GetCreatureInfo()->vehicleId, 0);
// if eventData set then event active and need apply spell_start // if eventData set then event active and need apply spell_start
if (eventData) if (eventData)
@ -940,9 +958,6 @@ void Creature::PrepareBodyLootState()
{ {
loot.clear(); loot.clear();
// only dead
if (!isAlive())
{
// if have normal loot then prepare it access // if have normal loot then prepare it access
if (!lootForBody) if (!lootForBody)
{ {
@ -965,7 +980,6 @@ void Creature::PrepareBodyLootState()
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
return; return;
} }
}
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
@ -1298,6 +1312,7 @@ bool Creature::LoadFromDB(uint32 guidlow, Map* map)
if (!Create(guidlow, pos, cinfo, TEAM_NONE, data, eventData)) if (!Create(guidlow, pos, cinfo, TEAM_NONE, data, eventData))
return false; return false;
SetRespawnCoord(pos);
m_respawnradius = data->spawndist; m_respawnradius = data->spawndist;
m_respawnDelay = data->spawntimesecs; m_respawnDelay = data->spawntimesecs;
@ -1312,7 +1327,7 @@ bool Creature::LoadFromDB(uint32 guidlow, Map* map)
m_deathState = DEAD; m_deathState = DEAD;
if (CanFly()) if (CanFly())
{ {
float tz = GetTerrain()->GetHeight(data->posX, data->posY, data->posZ, false); float tz = GetTerrain()->GetHeightStatic(data->posX, data->posY, data->posZ, false);
if (data->posZ - tz > 0.1) if (data->posZ - tz > 0.1)
Relocate(data->posX, data->posY, tz); Relocate(data->posX, data->posY, tz);
} }
@ -1342,7 +1357,7 @@ bool Creature::LoadFromDB(uint32 guidlow, Map* map)
// Just set to dead, so need to relocate like above // Just set to dead, so need to relocate like above
if (CanFly()) if (CanFly())
{ {
float tz = GetTerrain()->GetHeight(data->posX, data->posY, data->posZ, false); float tz = GetTerrain()->GetHeightStatic(data->posX, data->posY, data->posZ, false);
if (data->posZ - tz > 0.1) if (data->posZ - tz > 0.1)
Relocate(data->posX, data->posY, tz); Relocate(data->posX, data->posY, tz);
} }
@ -1421,7 +1436,6 @@ bool Creature::HasInvolvedQuest(uint32 quest_id) const
return false; return false;
} }
struct CreatureRespawnDeleteWorker struct CreatureRespawnDeleteWorker
{ {
explicit CreatureRespawnDeleteWorker(uint32 guid) : i_guid(guid) {} explicit CreatureRespawnDeleteWorker(uint32 guid) : i_guid(guid) {}
@ -1460,6 +1474,7 @@ void Creature::DeleteFromDB(uint32 lowguid, CreatureData const* data)
WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid=%u", lowguid); WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid=%u", lowguid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_creature_data WHERE guid=%u", lowguid); WorldDatabase.PExecuteLog("DELETE FROM game_event_creature_data WHERE guid=%u", lowguid);
WorldDatabase.PExecuteLog("DELETE FROM creature_battleground WHERE guid=%u", lowguid); WorldDatabase.PExecuteLog("DELETE FROM creature_battleground WHERE guid=%u", lowguid);
WorldDatabase.PExecuteLog("DELETE FROM creature_linking WHERE guid=%u OR master_guid=%u", lowguid, lowguid);
WorldDatabase.CommitTransaction(); WorldDatabase.CommitTransaction();
} }
@ -1534,21 +1549,16 @@ void Creature::SetDeathState(DeathState s)
if (s == JUST_ALIVED) if (s == JUST_ALIVED)
{ {
CreatureInfo const* cinfo = GetCreatureInfo(); clearUnitState(UNIT_STAT_ALL_STATE);
SetHealth(GetMaxHealth());
SetLootRecipient(NULL);
SetWalk(true);
if (GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_RESPAWN)
ClearTemporaryFaction();
Unit::SetDeathState(ALIVE); Unit::SetDeathState(ALIVE);
clearUnitState(UNIT_STAT_ALL_STATE); SetHealth(GetMaxHealth());
i_motionMaster.Initialize(); SetLootRecipient(NULL);
if (GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_RESPAWN)
ClearTemporaryFaction();
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool));
// Dynamic flags may be adjusted by spells. Clear them // Dynamic flags may be adjusted by spells. Clear them
// first and let spell from *addon apply where needed. // first and let spell from *addon apply where needed.
@ -1557,8 +1567,11 @@ void Creature::SetDeathState(DeathState s)
// Flags after LoadCreatureAddon. Any spell in *addon // Flags after LoadCreatureAddon. Any spell in *addon
// will not be able to adjust these. // will not be able to adjust these.
SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); SetUInt32Value(UNIT_NPC_FLAGS, GetCreatureInfo()->npcflag);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
SetWalk(true, true);
i_motionMaster.Initialize();
} }
} }
@ -1566,13 +1579,6 @@ void Creature::Respawn()
{ {
RemoveCorpse(); RemoveCorpse();
// forced recreate creature object at clients
UnitVisibility currentVis = GetVisibility();
SetVisibility(VISIBILITY_RESPAWN);
UpdateObjectVisibility();
SetVisibility(currentVis); // restore visibility state
UpdateObjectVisibility();
if (IsDespawned()) if (IsDespawned())
{ {
if (HasStaticDBSpawnData()) if (HasStaticDBSpawnData())
@ -1594,43 +1600,45 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn)
if (isAlive()) if (isAlive())
SetDeathState(JUST_DIED); SetDeathState(JUST_DIED);
RemoveCorpse(); m_corpseDecayTimer = 1; // Properly remove corpse on next tick (also pool system requires Creature::Update call with CORPSE state
SetHealth(0); // just for nice GM-mode view SetHealth(0); // just for nice GM-mode view
} }
bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo) bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf)
{ {
if (!spellInfo) if (!spellInfo)
return false; return false;
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->GetMechanic() - 1))) if (!castOnSelf && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->GetMechanic() - 1)))
return true; return true;
return Unit::IsImmuneToSpell(spellInfo); return Unit::IsImmuneToSpell(spellInfo, castOnSelf);
} }
bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const
{ {
SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index); SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index);
if (!spellEffect)
return false;
if (spellEffect && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellEffect->EffectMechanic - 1))) if (!castOnSelf && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellEffect->EffectMechanic - 1)))
return true; return true;
// Taunt immunity special flag check // Taunt immunity special flag check
if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NOT_TAUNTABLE) if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NOT_TAUNTABLE)
{ {
// Taunt aura apply check // Taunt aura apply check
if (spellEffect && spellEffect->Effect == SPELL_EFFECT_APPLY_AURA) if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA)
{ {
if (spellEffect && spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_TAUNT) if (spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_TAUNT)
return true; return true;
} }
// Spell effect taunt check // Spell effect taunt check
else if (spellEffect && spellEffect->Effect == SPELL_EFFECT_ATTACK_ME) else if (spellEffect->Effect == SPELL_EFFECT_ATTACK_ME)
return true; return true;
} }
return Unit::IsImmuneToSpellEffect(spellInfo, index); return Unit::IsImmuneToSpellEffect(spellInfo, index, castOnSelf);
} }
SpellEntry const* Creature::ReachWithSpellAttack(Unit* pVictim) SpellEntry const* Creature::ReachWithSpellAttack(Unit* pVictim)
@ -1714,12 +1722,13 @@ SpellEntry const* Creature::ReachWithSpellCure(Unit* pVictim)
for (int j = 0; j < MAX_EFFECT_INDEX; ++j) for (int j = 0; j < MAX_EFFECT_INDEX; ++j)
{ {
SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j)); SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j));
if( spellEffect && (spellEffect->Effect == SPELL_EFFECT_HEAL) ) if (spellEffect && spellEffect->Effect == SPELL_EFFECT_HEAL)
{ {
bcontinue = false; bcontinue = false;
break; break;
} }
} }
if (bcontinue) if (bcontinue)
continue; continue;
@ -2228,32 +2237,31 @@ time_t Creature::GetRespawnTimeEx() const
void Creature::GetRespawnCoord(float& x, float& y, float& z, float* ori, float* dist) const void Creature::GetRespawnCoord(float& x, float& y, float& z, float* ori, float* dist) const
{ {
if (CreatureData const* data = sObjectMgr.GetCreatureData(GetGUIDLow())) x = m_respawnPos.x;
{ y = m_respawnPos.y;
x = data->posX; z = m_respawnPos.z;
y = data->posY;
z = data->posZ;
if (ori)
*ori = data->orientation;
if (dist)
*dist = GetRespawnRadius();
}
else
{
float orient;
GetSummonPoint(x, y, z, orient);
if (ori) if (ori)
*ori = orient; *ori = m_respawnPos.o;
if (dist) if (dist)
*dist = GetRespawnRadius(); *dist = GetRespawnRadius();
}
// lets check if our creatures have valid spawn coordinates // lets check if our creatures have valid spawn coordinates
MANGOS_ASSERT(MaNGOS::IsValidMapCoord(x, y, z) || PrintCoordinatesError(x, y, z, "respawn")); MANGOS_ASSERT(MaNGOS::IsValidMapCoord(x, y, z) || PrintCoordinatesError(x, y, z, "respawn"));
} }
void Creature::ResetRespawnCoord()
{
if (CreatureData const* data = sObjectMgr.GetCreatureData(GetGUIDLow()))
{
m_respawnPos.x = data->posX;
m_respawnPos.y = data->posY;
m_respawnPos.z = data->posZ;
m_respawnPos.o = data->orientation;
}
}
void Creature::AllLootRemovedFromCorpse() void Creature::AllLootRemovedFromCorpse()
{ {
if (lootForBody && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE)) if (lootForBody && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
@ -2437,6 +2445,13 @@ void Creature::SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags)
{ {
m_temporaryFactionFlags = tempFactionFlags; m_temporaryFactionFlags = tempFactionFlags;
setFaction(factionId); setFaction(factionId);
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_NON_ATTACKABLE)
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_OOC_NOT_ATTACK)
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PASSIVE)
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
} }
void Creature::ClearTemporaryFaction() void Creature::ClearTemporaryFaction()
@ -2447,8 +2462,17 @@ void Creature::ClearTemporaryFaction()
if (isCharmed()) if (isCharmed())
return; return;
m_temporaryFactionFlags = TEMPFACTION_NONE; // Reset to original faction
setFaction(GetCreatureInfo()->faction_A); setFaction(GetCreatureInfo()->faction_A);
// Reset UNIT_FLAG_NON_ATTACKABLE, UNIT_FLAG_OOC_NOT_ATTACKABLE or UNIT_FLAG_PASSIVE flags
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_NON_ATTACKABLE && GetCreatureInfo()->unit_flags & UNIT_FLAG_NON_ATTACKABLE)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_OOC_NOT_ATTACK && GetCreatureInfo()->unit_flags & UNIT_FLAG_OOC_NOT_ATTACKABLE && !isInCombat())
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PASSIVE && GetCreatureInfo()->unit_flags & UNIT_FLAG_PASSIVE)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
m_temporaryFactionFlags = TEMPFACTION_NONE;
} }
void Creature::SendAreaSpiritHealerQueryOpcode(Player* pl) void Creature::SendAreaSpiritHealerQueryOpcode(Player* pl)
@ -2548,8 +2572,20 @@ bool Creature::HasStaticDBSpawnData() const
return sObjectMgr.GetCreatureData(GetGUIDLow()) != NULL; return sObjectMgr.GetCreatureData(GetGUIDLow()) != NULL;
} }
void Creature::SetWalk(bool enable) void Creature::SetWalk(bool enable, bool asDefault)
{ {
if (asDefault)
{
if (enable)
clearUnitState(UNIT_STAT_RUNNING);
else
addUnitState(UNIT_STAT_RUNNING);
}
// Nothing changed?
if (enable == m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE))
return;
if (enable) if (enable)
m_movementInfo.AddMovementFlag(MOVEFLAG_WALK_MODE); m_movementInfo.AddMovementFlag(MOVEFLAG_WALK_MODE);
else else

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "12601" #define REVISION_NR "12602"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__