ServUO Version
Publish 57
Ultima Expansion
Endless Journey
Is there an easy way to change the corpse decay (make it much shorter) for certain areas of the map, such as a specific region, or a champ spawn, or things like that?
 
I do know know this to be a 100% working method but it might possible to change the corpse decay time for specific region.

To change the corpse decay time for specific regions of the map, you can modify the CheckCorpseDecay method in the Scripts/Mobiles/Corpse.cs file. Here's how you can do it:

  1. Open the file Scripts/Mobiles/Corpse.cs
  2. Find the following code inside the CheckDecay method:
    C#:
    else if (DateTime.UtcNow >= (m_TimeOfDeath + m_Map.CorpseDecayTime))
    {
        Delete();
     return;
    }
  3. Replace it with the following code:
    C#:
    else
    {
    int decayTime = m_Map.CorpseDecayTime; // get the default decay time for the map
    
    // Change corpse decay time for specific regions
    string regionName = m_Map.GetRegionName(m_Location);
    if (regionName == "YourRegionNameHere")
        {
    decayTime = 60; // set the decay time to 60 seconds (1 minute)
        }
    
    if (DateTime.UtcNow >= (m_TimeOfDeath + TimeSpan.FromSeconds(decayTime)))
        {
     Delete();
     return;
        }
    }
    Replace "YourRegionNameHere" with the name of the region where you want to change the corpse decay time.
  4. Save the file and restart your server.
With these changes, corpses in the specified region will decay much faster (in 60 seconds in this example), while corpses in other regions will decay according to the default time for the map

Again, I'm not sure about this, but it might work.
Always make backups before trying stuff out

Let me know how it goes for you.
 
Thanks for the reply, I've been working on it throughout the day and think I have it all working properly now...

In Corpse.cs I added a new function called GetDecayTime() which returns a TimeSpan based on whatever criteria I decide as follows:

Corpse.cs:
private TimeSpan GetDecayTime()
{
    if(m_Owner is BaseCreature && ((BaseCreature)m_Owner).IsChampionSpawn && !(m_Owner is BaseChampion))
    {
        return TimeSpan.FromSeconds(10);
    }
    else if(m_Owner is BaseCreature && !(m_Owner is [special boss type here]) && m_Owner.Region.IsPartOf("[name of region here]"))
    {
        return TimeSpan.FromSeconds(15);
    }
    else
    {
        return m_BoneDecayTime;
    }
}

Then, there's 2 places in the Corpse.cs file that I tweaked to use this new calculated decay time:

Corpse.cs > public Corpse(...) constructor, at the very end:
BeginDecay(GetDecayTime());          

DevourCorpse();

if (owner is PlayerMobile)
{
    if (PlayerCorpses == null)
        PlayerCorpses = new Dictionary<Corpse, int>();

    PlayerCorpses[this] = 0;
}

Corpse.cs > TurnToBones() method:
public void TurnToBones()
{
    if (Deleted)
    {
        return;
    }

    ProcessDelta();
    SendRemovePacket();
    ItemID = Utility.Random(0xECA, 9); // bone graphic
    Hue = 0;
    ProcessDelta();

    SetFlag(CorpseFlag.NoBones, true);
    SetFlag(CorpseFlag.IsBones, true);

    BeginDecay(GetDecayTime());
}

That seems to be working beautifully currently and lets me just add more conditions to a single function for future changes. One caveat is that this affects the Corpse > Bones and Bones > Nothing values. If you wanted different numbers for the two different stages, you'd have to write 2 separate function calls (one for each) and use them as necessary. However, for me, the same timings was fine!
 
Back