diff --git a/Source/Game/AI/SmartScripts/SmartAIManager.cs b/Source/Game/AI/SmartScripts/SmartAIManager.cs index de15aee8c..bbb4bc5a0 100644 --- a/Source/Game/AI/SmartScripts/SmartAIManager.cs +++ b/Source/Game/AI/SmartScripts/SmartAIManager.cs @@ -3143,6 +3143,7 @@ namespace Game.AI public struct CorpseDelay { public uint timer; + public uint includeDecayRatio; } public struct DisableEvade { diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index d70153e3a..bee9f8f5a 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -2178,7 +2178,7 @@ namespace Game.AI { foreach (var target in targets) if (IsCreature(target)) - target.ToCreature().SetCorpseDelay(e.Action.corpseDelay.timer); + target.ToCreature().SetCorpseDelay(e.Action.corpseDelay.timer, e.Action.corpseDelay.includeDecayRatio == 0); break; } case SmartActions.SpawnSpawngroup: diff --git a/Source/Game/Entities/Creature/Creature.Fields.cs b/Source/Game/Entities/Creature/Creature.Fields.cs index f10170d92..a2eaf8f03 100644 --- a/Source/Game/Entities/Creature/Creature.Fields.cs +++ b/Source/Game/Entities/Creature/Creature.Fields.cs @@ -81,6 +81,7 @@ namespace Game.Entities long m_respawnTime; // (secs) time of next respawn uint m_respawnDelay; // (secs) delay between corpse disappearance and respawning uint m_corpseDelay; // (secs) delay between death and corpse disappearance + bool m_ignoreCorpseDecayRatio; float m_wanderDistance; uint m_boundaryCheckTime; // (msecs) remaining time for next evade boundary check uint m_combatPulseTime; // (msecs) remaining time for next zone-in-combat pulse diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index 848c71718..eee8875f7 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -2593,7 +2593,9 @@ namespace Game.Entities if (m_corpseRemoveTime <= now) return; - float decayRate = WorldConfig.GetFloatValue(WorldCfg.RateCorpseDecayLooted); + // Scripts can choose to ignore RATE_CORPSE_DECAY_LOOTED by calling SetCorpseDelay(timer, true) + float decayRate = m_ignoreCorpseDecayRatio ? 1.0f : WorldConfig.GetFloatValue(WorldCfg.RateCorpseDecayLooted); + // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update if (loot.loot_type == LootType.Skinning) m_corpseRemoveTime = now; @@ -3102,7 +3104,12 @@ namespace Game.Entities public ulong GetSpawnId() { return m_spawnId; } - public void SetCorpseDelay(uint delay) { m_corpseDelay = delay; } + public void SetCorpseDelay(uint delay, bool ignoreCorpseDecayRatio = false) + { + m_corpseDelay = delay; + if (ignoreCorpseDecayRatio) + m_ignoreCorpseDecayRatio = true; + } public uint GetCorpseDelay() { return m_corpseDelay; } public bool IsRacialLeader() { return GetCreatureTemplate().RacialLeader; } public bool IsCivilian()