ServUO - Death changes help request.

jaspen

New Member
Jan 1, 2019
4
0
58
There are some things I was able to read the code well enough to correct, simple things. The following are changes I would like to make, that I have attempted, and failed at, as well have attempted to find solutions online, but did not find any. I have the latest ServUO version as reference.


1. First off, if there are any good resources for learning to code, please share. I would like to be self sufficient in the future. I just need a little help on how to read what I see. I get some of it, like understanding && and !. Often my problem is understanding where some of the data is coming from as I will see something mentioned but not sure where it originated.

2. To assist him, I would like to have it where you keep all items upon death, after being Young wears off. If it is possible to keep everything equipped, even better, but totally optional. I think the changes needed are in PlayerMobile.cs? I see several death triggers in there, but I can’t quite understand them well enough to change.

3. If possible, having it where he portals to the New Haven healers upon death, regardless of where the death occurs. But priority is number 2.

If you need me to check anything, let me know. Any help is much appreciated.
 

jaspen

New Member
Jan 1, 2019
4
0
58
I think Item.cs and Mobile.cs might be involved as well. I am still trying to solve it myself. I do not want you guys thinking I am lazy! I found a program call grepWin which is amazing. Wish I had found this years ago.
[doublepost=1546817234][/doublepost]Looks like I have solved the items remaining in backpack part. It seems I was making the "correct" change but it was not taking effect upon server reset. I had to delete the entire ServUO folder and rebuild from scratch. This brings me to an important question, when editing files outside the config and script folder, which I assume takes effect after a server restart, what is the normal process to recompile again while retaining all character data? I had modified the Item.cs file under ServUO/Server.
[doublepost=1546829543][/doublepost]Seems I was wrong. While I no longer drop items upon death, mobs no longer drop loot... Guess I am at the mercy of one of your helping out! I tried! :/
 

Falkor

Well-Known Member
Apr 11, 2018
46
6
wpshard.com
Shard Name
Whispering Pines
The only file you should have to edit is PlayerMobile.cs, paying attention to the DeathMoveResult sections.

I would try changing this:

Code:
    public override DeathMoveResult GetParentMoveResultFor(Item item)
     {
       if (CheckInsuranceOnDeath(item) && !Young)
       {
         return DeathMoveResult.MoveToBackpack;
       }

       DeathMoveResult res = base.GetParentMoveResultFor(item);

       if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
       {
         res = DeathMoveResult.MoveToBackpack;
       }

       return res;
     }
To this:

Code:
    public override DeathMoveResult GetParentMoveResultFor(Item item)
     {
       return DeathMoveResult.MoveToBackpack;
     }
And the next part under it to this:
Code:
    public override DeathMoveResult GetInventoryMoveResultFor(Item item)
{
         return DeathMoveResult.MoveToBackpack;
    }
That should leave everything in their pack after they die, without any checks for Young or item insurance.

If you figure out which of these cases involves items that are equipped, you can also specify "DeathMoveResult.RemainEquiped" but I don't know what happens if those items aren't equipped in the first place and you tell it to do that.

I haven't tested this code but it should work properly!

Oh, and take a look at the free program Agent Ransack. It is killer for searching for text within files.
 
  • Like
Reactions: Lena80

jaspen

New Member
Jan 1, 2019
4
0
58
The only file you should have to edit is PlayerMobile.cs, paying attention to the DeathMoveResult sections.

I would try changing this:

Code:
    public override DeathMoveResult GetParentMoveResultFor(Item item)
     {
       if (CheckInsuranceOnDeath(item) && !Young)
       {
         return DeathMoveResult.MoveToBackpack;
       }

       DeathMoveResult res = base.GetParentMoveResultFor(item);

       if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
       {
         res = DeathMoveResult.MoveToBackpack;
       }

       return res;
     }
To this:

Code:
    public override DeathMoveResult GetParentMoveResultFor(Item item)
     {
       return DeathMoveResult.MoveToBackpack;
     }
And the next part under it to this:
Code:
    public override DeathMoveResult GetInventoryMoveResultFor(Item item)
{
         return DeathMoveResult.MoveToBackpack;
    }
That should leave everything in their pack after they die, without any checks for Young or item insurance.

If you figure out which of these cases involves items that are equipped, you can also specify "DeathMoveResult.RemainEquiped" but I don't know what happens if those items aren't equipped in the first place and you tell it to do that.

I haven't tested this code but it should work properly!

Oh, and take a look at the free program Agent Ransack. It is killer for searching for text within files.
Thanks for that. I will test it out. That is the section I was focusing on but didn't realize I could gut those parts out. Much appreciated. I tested modifying that in so many ways but never tested removing anything. For some reason, my ignorance, I thought those preceding lines were needed.

I will look into that utility as well to see how it compares to gretWin.
 

Fisher

Well-Known Member
Dec 24, 2014
78
6
42
The Boondocks
dawnuo.net
Shard Name
DawnUO
Usually you do not want to edit any of the files inside the Server folder. When you do, you will need to recompile. Virtually anything you want to change can be done by editing (or adding to) the files in the Scripts folder. After altering files in the Scripts folder you will only need to restart your server for the changes. There are tons of resources out there for learning C#. I would start with the "if" statement https://csharp.net-tutorials.com/control-structures/if-statement/ and keeping a good record of your changes. I started out by keeping a copy of every file I modified. The best/easiest way I have found to automate this process is by using a git repo. There is a learning curve but it is not as horribly complicated as it seems and it will track literally everything you do and save you a ton a time as you learn. Goggle is your best resource.

Look for features in the game that already do what you are looking to do, or things that have a similar function. Also search the internets. Odds are you are not the first person looking for this feature. This will give you an example of how to preform a function and you can copy or modify it to fit your needs. Knowing that young players already have the feature that you want gives you a good starting point.

Take a look in Scripts/Mobiles/playermobile.cs and do a search for "young". at around line 3623 you should find this:

Code:
public override DeathMoveResult GetParentMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetParentMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
        }

        public override DeathMoveResult GetInventoryMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetInventoryMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
}
What you are wanting to accomplish may be done by removing the two "&& Young" conditions like this:

Code:
public override DeathMoveResult GetParentMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetParentMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable) //<---<<< && Young removed
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
        }

        public override DeathMoveResult GetInventoryMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetInventoryMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable) //<---<<< && Young removed
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
}
There are probably thousands of ways to get the result you are working for and I did test the example but there is always the chance of undesirable results to any change you make. That is why it is very important to track your work. Good luck!
 

jaspen

New Member
Jan 1, 2019
4
0
58
Usually you do not want to edit any of the files inside the Server folder. When you do, you will need to recompile. Virtually anything you want to change can be done by editing (or adding to) the files in the Scripts folder. After altering files in the Scripts folder you will only need to restart your server for the changes. There are tons of resources out there for learning C#. I would start with the "if" statement https://csharp.net-tutorials.com/control-structures/if-statement/ and keeping a good record of your changes. I started out by keeping a copy of every file I modified. The best/easiest way I have found to automate this process is by using a git repo. There is a learning curve but it is not as horribly complicated as it seems and it will track literally everything you do and save you a ton a time as you learn. Goggle is your best resource.

Look for features in the game that already do what you are looking to do, or things that have a similar function. Also search the internets. Odds are you are not the first person looking for this feature. This will give you an example of how to preform a function and you can copy or modify it to fit your needs. Knowing that young players already have the feature that you want gives you a good starting point.

Take a look in Scripts/Mobiles/playermobile.cs and do a search for "young". at around line 3623 you should find this:

Code:
public override DeathMoveResult GetParentMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetParentMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
        }

        public override DeathMoveResult GetInventoryMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetInventoryMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
}
What you are wanting to accomplish may be done by removing the two "&& Young" conditions like this:

Code:
public override DeathMoveResult GetParentMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetParentMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable) //<---<<< && Young removed
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
        }

        public override DeathMoveResult GetInventoryMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item) && !Young)
            {
                return DeathMoveResult.MoveToBackpack;
            }

            DeathMoveResult res = base.GetInventoryMoveResultFor(item);

            if (res == DeathMoveResult.MoveToCorpse && item.Movable) //<---<<< && Young removed
            {
                res = DeathMoveResult.MoveToBackpack;
            }

            return res;
}
There are probably thousands of ways to get the result you are working for and I did test the example but there is always the chance of undesirable results to any change you make. That is why it is very important to track your work. Good luck!
I never tried removing young. I think at one point I tried adding ( Young || !Young )) to account for both scenarios. If I am understanding the usage of || correctly. I did a search for an or statement.

Thank you for the information. I have learned a lot from this one little adventure. I will have to look into how to recompile while retaining character data. I guess I should do a search about restoring from backup. That might give me an idea how the data is being stored.
 

Fisher

Well-Known Member
Dec 24, 2014
78
6
42
The Boondocks
dawnuo.net
Shard Name
DawnUO
Your last 3 auto saves should be in the Backups folder. \Backups\Automatic\Most Recent Just drop the files in your Saves folder (clear the Saves folder first, or overwrite) and the server should load your last save.
 

Lena80

Member
Jan 23, 2018
15
0
43
I dont mean to steal the thead.. but we are talking about death changes so.. what about a 1% to drop a key?
is this the correct way?

Code:
  public override DeathMoveResult GetParentMoveResultFor(Item item)
        {
            if (CheckInsuranceOnDeath(item))
                return DeathMoveResult.MoveToBackpack;

            DeathMoveResult res = base.GetParentMoveResultFor(item);
             if (Utility.RandomDouble() <= 0.01) //1% drop a key
                {
                if (item is Key)
                {
                  Key key = (Key)item;
             if (res == DeathMoveResult.MoveToCorpse && key.KeyValue != 0 || key.KeyValue != -1)
                res = DeathMoveResult.MoveToBackpack;
            Console.WriteLine("item is Key");
                }
                }
            if (res == DeathMoveResult.MoveToCorpse && item.Movable && Young)
                res = DeathMoveResult.MoveToBackpack;

            return res;
        }

        public override DeathMoveResult GetInventoryMoveResultFor( Item item )
        {
            if( CheckInsuranceOnDeath( item ) )
                return DeathMoveResult.MoveToBackpack;

            DeathMoveResult res = base.GetInventoryMoveResultFor( item );
  if (Utility.RandomDouble() <= 0.01) //1% drop a key
                {
                if (item is Key)
                {
                  Key key = (Key)item;
             if (res == DeathMoveResult.MoveToCorpse && key.KeyValue != 0 || key.KeyValue != -1)
                res = DeathMoveResult.MoveToBackpack;
            Console.WriteLine("item is Key");
                }
                }
            if( res == DeathMoveResult.MoveToCorpse && item.Movable && Young )
                res = DeathMoveResult.MoveToBackpack;

            return res;
        }
 

Falkor

Well-Known Member
Apr 11, 2018
46
6
wpshard.com
Shard Name
Whispering Pines
Your key drop code should work but it would give them a 1% chance for each item in their pack. Players with more in their packs would have more chances at the drop.

If you just wanted an overall 1% chance at death, you'll want to find this section of playermobile.cs:

Code:
  public override bool OnBeforeDeath()
  {
  NetState state = NetState;

  if (state != null)
  {
  state.CancelAllTrades();
  }
...
Insert your key drop code somewhere inside there; after the NetState line would be fine.