aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp59
-rw-r--r--src/server/game/Entities/Creature/Creature.h4
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp2
3 files changed, 31 insertions, 34 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 55b45a53f7b..f423df31901 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -140,7 +140,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(): Unit(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0),
-m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0),
+m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
@@ -212,7 +212,7 @@ void Creature::DisappearAndDie()
//ObjectAccessor::UpdateObjectVisibility(this);
if (isAlive())
setDeathState(JUST_DIED);
- RemoveCorpse();
+ RemoveCorpse(false);
}
void Creature::SearchFormation()
@@ -229,12 +229,12 @@ void Creature::SearchFormation()
formation_mgr.AddCreatureToGroup(frmdata->second->leaderGUID, this);
}
-void Creature::RemoveCorpse()
+void Creature::RemoveCorpse(bool setSpawnTime)
{
if ((getDeathState() != CORPSE && !m_isDeadByDefault) || (getDeathState() != ALIVE && m_isDeadByDefault))
return;
- m_deathTimer = 0;
+ m_corpseRemoveTime = time(NULL);
setDeathState(DEAD);
UpdateObjectVisibility();
loot.clear();
@@ -242,7 +242,9 @@ void Creature::RemoveCorpse()
if (IsAIEnabled)
AI()->CorpseRemoved(respawnDelay);
- m_respawnTime = time(NULL) + m_respawnDelay;
+ // Should get removed later, just keep "compatibility" with scripts
+ if(setSpawnTime)
+ m_respawnTime = time(NULL) + respawnDelay;
float x,y,z,o;
GetRespawnCoord(x, y, z, &o);
@@ -485,16 +487,15 @@ void Creature::Update(uint32 diff)
}
else m_groupLootTimer -= diff;
}
- else if (m_deathTimer <= diff)
+ else if (m_corpseRemoveTime <= time(NULL))
{
- RemoveCorpse();
+ RemoveCorpse(false);
sLog.outStaticDebug("Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY));
}
else
{
// for delayed spells
m_Events.Update(diff);
- m_deathTimer -= diff;
}
break;
@@ -503,15 +504,11 @@ void Creature::Update(uint32 diff)
{
if (m_isDeadByDefault)
{
- if (m_deathTimer <= diff)
+ if (m_corpseRemoveTime <= time(NULL))
{
- RemoveCorpse();
+ RemoveCorpse(false);
sLog.outStaticDebug("Removing alive corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY));
}
- else
- {
- m_deathTimer -= diff;
- }
}
Unit::Update(diff);
@@ -1476,7 +1473,8 @@ void Creature::setDeathState(DeathState s)
{
if ((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault))
{
- m_deathTimer = m_corpseDelay*IN_MILLISECONDS;
+ m_corpseRemoveTime = time(NULL) + m_corpseDelay;
+ m_respawnTime = time(NULL) + m_respawnDelay + m_corpseDelay;
// always save boss respawn time at death to prevent crash cheating
if (sWorld.getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss())
@@ -1565,7 +1563,7 @@ void Creature::Respawn(bool force)
setDeathState(CORPSE);
}
- RemoveCorpse();
+ RemoveCorpse(false);
if (getDeathState() == DEAD)
{
@@ -1631,7 +1629,7 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn)
if (isAlive())
setDeathState(JUST_DIED);
- RemoveCorpse();
+ RemoveCorpse(false);
}
bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo)
@@ -1768,7 +1766,7 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const
{
if (GetEntry() == VISUAL_WAYPOINT)
return false;
- return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState == CORPSE));
+ return (isAlive() || m_corpseRemoveTime > time(NULL) || (m_isDeadByDefault && m_deathState == CORPSE));
}
// Dead player see creatures near own corpse
@@ -1988,10 +1986,7 @@ void Creature::SaveRespawnTime()
if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData))
return;
- if (m_respawnTime > time(NULL)) // dead (no corpse)
- sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
- else if (m_deathTimer > 0) // dead (corpse)
- sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/IN_MILLISECONDS);
+ sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
}
// this should not be called by petAI or
@@ -2215,10 +2210,8 @@ bool Creature::HasSpell(uint32 spellID) const
time_t Creature::GetRespawnTimeEx() const
{
time_t now = time(NULL);
- if (m_respawnTime > now) // dead (no corpse)
+ if (m_respawnTime > now)
return m_respawnTime;
- else if (m_deathTimer > 0) // dead (corpse)
- return now+m_respawnDelay+m_deathTimer/IN_MILLISECONDS;
else
return now;
}
@@ -2254,20 +2247,24 @@ void Creature::AllLootRemovedFromCorpse()
{
if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
{
- uint32 nDeathTimer;
+ time_t now = time(NULL);
+ if(m_corpseRemoveTime <= now)
+ return;
+ float decayRate;
CreatureInfo const *cinfo = GetCreatureInfo();
// corpse was not skinnable -> apply corpse looted timer
if (!cinfo || !cinfo->SkinLootId)
- nDeathTimer = (uint32)((m_corpseDelay * IN_MILLISECONDS) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED));
+ decayRate = sWorld.getRate(RATE_CORPSE_DECAY_LOOTED);
// corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
else
- nDeathTimer = 0;
+ decayRate = 0.0f;
+
+ uint32 diff = (m_corpseRemoveTime - now) * decayRate;
- // update death timer only if looted timer is shorter
- if (m_deathTimer > nDeathTimer)
- m_deathTimer = nDeathTimer;
+ m_corpseRemoveTime -= diff;
+ m_respawnTime -= diff;
}
}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 6fce4565222..43ba4c4892c 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -589,7 +589,7 @@ class Creature : public Unit, public GridObject<Creature>
bool IsVisibleInGridForPlayer(Player const* pl) const;
- void RemoveCorpse();
+ void RemoveCorpse(bool setSpawnTime = true);
bool isDeadByDefault() const { return m_isDeadByDefault; };
void ForcedDespawn(uint32 timeMSToDespawn = 0);
@@ -684,7 +684,7 @@ class Creature : public Unit, public GridObject<Creature>
uint64 m_lootRecipient;
/// Timers
- uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance
+ uint32 m_corpseRemoveTime; // (msecs)timer for death or corpse disappearance
time_t m_respawnTime; // (secs) time of next respawn
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index cf7c9da778f..fb370bac80c 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -499,7 +499,7 @@ void Pet::Update(uint32 diff)
{
case CORPSE:
{
- if (getPetType() != HUNTER_PET || m_deathTimer <= diff)
+ if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= time(NULL))
{
Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
return;