ServUO OnDeath(Container c) issue...

mitty2

Citizen
Mar 13, 2018
23
1
3
56
Hi guys a little messed up on this one. It compiles fine, and works fine, unless more than 1 person does damage to the creature. It is supposed to reward any player who does damage to it and helps kill it. It drops a reward token in their backpack. But if more than one player helps kill it (does damage to it) on death it crashes my test server. Here is the bit of code that i've messed up probably.

On Death...:
  public override void OnDeath(Container c)
        {
            if (Map == Map.Ilshenar)
            {
                  List<Mobile> toGive = new List<Mobile>();
                  List<DamageStore> rights = GetLootingRights();

            for (int i = rights.Count - 1; i >= 0; --i)
            {
                DamageStore ds = rights[i];

                if (ds.m_HasRight)
                    toGive.Add(ds.m_Mobile);

                    Mobile m = toGive[i % toGive.Count];

                    m.SendMessage("You have recieved a Dragon Reward Token for your efforts!");
                    m.AddToBackpack(new DragonRewardToken ());

                if (toGive.Count == 0)
                return;

                base.OnDeath(c);
                }
            }
        }
 

Falkor

Squire
Apr 11, 2018
332
115
43
wpshard.com
Shard Name
Whispering Pines
Running the server in debug mode will give you the line number of the crash which will help pinpoint the cause.
 

Lemke

Squire
Sep 26, 2015
147
16
18
38
Try this:
But is just for the real killer.
C#:
public override void OnKilledBy( Mobile mob )
{

     Mobile killer = this.LastKiller;

     if (killer is BaseCreature)
         {
         killer = ((BaseCreature)killer).GetMaster();
         }
    
     /*if (killer is BaseEvo)//This only if you are using xanthos evo pet.
         {
         killer = ((BaseEvo)killer).GetMaster();
         }*/
     double random = Utility.RandomDouble();
     if (0.1 >= random) //10% chance
     {
        switch ( Utility.Random(1) )
            {
            case 0: killer.AddToBackpack(new YourItemHere()); break;
            //More cases
            }
            killer.PublicOverheadMessage( MessageType.Regular, 1153, true, "Drop drop drop!" );
    }
      base.OnKilledBy( mob );
}
 

mitty2

Citizen
Mar 13, 2018
23
1
3
56
In the whole script running in debug mode this is the line that crashes the shard...

Line 177
Mobile m = toGive[i % toGive.Count];
 

GoldDraco13

Squire
Aug 1, 2014
335
218
43
48
Canada
mycy4.com
Donate
Donate money to this user
quick glance, try this

Code:
                PlayerMobile m = toGive[i % toGive.Count] as PlayerMobile;
I would also have a check for null added before trying to add the item in case the player comes up null

Code:
if (m != null)
{
m.SendMessage("You have recieved a Dragon Reward Token for your efforts!");
m.AddToBackpack(new DragonRewardToken ());
}
 

Falkor

Squire
Apr 11, 2018
332
115
43
wpshard.com
Shard Name
Whispering Pines
BaseChampion does pretty much the same thing and it has a couple of extra checks:

Code:
        public virtual void GivePowerScrolls()
        {
            if (this.Map != Map.Felucca)
                return;

            List<Mobile> toGive = new List<Mobile>();
            List<DamageStore> rights = GetLootingRights();

            for (int i = rights.Count - 1; i >= 0; --i)
            {
                DamageStore ds = rights[i];

                if (ds.m_HasRight && InRange(ds.m_Mobile, 100) && ds.m_Mobile.Map == this.Map)
                    toGive.Add(ds.m_Mobile);
            }

            if (toGive.Count == 0)
                return;

            for (int i = 0; i < toGive.Count; i++)
            {
                Mobile m = toGive[i];

                if (!(m is PlayerMobile))
                    continue;

<snip>
First there's a check in case the toGive.Count = 0 so it doesn't attempt to give anything to nobody.

Then it checks that m is PlayerMobile, and if not, it'll go to the next case.

BasePeerless does something simple in that if the count isn't > 0 then it just drops the reward with the corpse. Most uses of GetLootingRights have the check for 0.
 
  • Like
Reactions: GoldDraco13