good morning,

I uploaded a new resource, an old script that's quite fun, however there is one bug i can't squash and am hoping someone help can help.

scenario:

1. Regular mob gets killed by a zombie
2. new zombie is created, based on killed mob
3. all items from killed mob moved to new zombie (confirmed items are in new zombie's backpack)
4. on death of new zombie, its corpse contains any equipped items, but not the items from the backpack.

Any thoughts? would i be focusing on ondeath in basecreature? corpse.cs? I can confirm that backpack items are moved to corpses for regular mobs... just not for zombies. im stumpted.

ondeath in the zombie script just points to base.ondeath (container c) and adds some other loot.
 

Attachments

  • ZombieX.cs
    8.5 KB · Views: 6
  • BaseCreature.cs
    259.5 KB · Views: 1
  • Corpse.cs
    35.5 KB · Views: 1
I'm not sure if it's the issue, but it is an issue. I've discovered in the past that using AddItem for non-equipped items can cause client crashes.

I would change line 215 from

Code:
zomb.AddItem ( item );

to

Code:
zomb.PackItem ( item );

That way you specify what layer it's going on instead of leaving it up to the client to figure it out. It's my suspicion that while these things usually end up in the pack, they may actually have a different layer set, "technically" leaving you with multiple items equipped on the same layer.
 
Thanks falkor... I made the change and still hasn't worked. Maybe it's relevant to note that the killer is a basecreature (other mobiles killing the zombies).
Could you tell me where in basecreature/corpse/my mobile script the moving of items to the corpse happens? I found this in corpse.cs which *might* be the relevant part of the script?

C#:
        public static Container Mobile_CreateCorpseHandler( Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> initialContent, List<Item> equipItems )
        {
            bool shouldFillCorpse = true;

            //if ( owner is BaseCreature )
            //    shouldFillCorpse = !((BaseCreature)owner).IsBonded;

            Corpse c = new Corpse( owner, hair, facialhair, shouldFillCorpse ? equipItems : new List<Item>() );

            owner.Corpse = c;

            if ( shouldFillCorpse )
            {
                for ( int i = 0; i < initialContent.Count; ++i )
                {
                    Item item = initialContent[i];

                   
                    if ( Core.AOS && owner.Player && item.Parent == owner.Backpack )
                        c.AddItem( item );
                    else
                        c.DropItem( item );

                    if ( owner.Player && Core.AOS )
                        c.SetRestoreInfo( item, item.Location );
                }

The zombie Mobile has the items in its pack - i can see it as an admin and when i double click the backpack. MY code that creates the zombie doesn't "create a backpack... could that be the issue? or is a backpack created automatically?

I've tried everything from gold, to a gorget, to a scroll, to a sword - nothing makes it to the body of the zombie. in fact the body defaults to a poor loot with just a few gold, regardless if its a dragon zombie mobile.
 
Not sure if this helps or not but it might give you something to look at. I just tested it on my server which is servuo pub 57 with lots of extras added in and the loot gets transfered and I can loot it etc... with a non staff character. So you might look at some of the servuo files to find the fix to your issue.
 
Not sure if this helps or not but it might give you something to look at. I just tested it on my server which is servuo pub 57 with lots of extras added in and the loot gets transfered and I can loot it etc... with a non staff character. So you might look at some of the servuo files to find the fix to your issue.

Can you try and have a mobile kill a zombie (say, a dragon) and see if the zombie's loot is there?
Also, this isn't a first gen zombiex, it's a mobile that was killed and turned zombie.

How are you finding the script by the way? isn't it great? try putting a nest and playing with the values. and don't forget to change the change for the scrolls.
 
Yeah, if a non player kills them the extra loot vanishes, didn't try that the first time, doesn't if a player kills it though. I've had this script for a long time but I didn't have the BaseUndead file to go with it so it's always just been setup as a BaseCreature. It is a fun script for event type stuff.
 
Yeah, if a non player kills them the extra loot vanishes, didn't try that the first time, doesn't if a player kills it though. I've had this script for a long time but I didn't have the BaseUndead file to go with it so it's always just been setup as a BaseCreature. It is a fun script for event type stuff.

any idea on how to make the pack drop? reason is, if a player dies, and the zombie has all the player's items, and another mobile kills that zombie, then all the player's gear is gonzo.
 
I have just looked at the files for 10 seconds (no deeper analysis or testing).. it seems like you never add the items to the zombies actually backpack.

Edit: This is from your ZombieX.cs file.

-Grim

C#:
                //region moveitems
                if ( mob.Items != null && mob.Backpack != null )
                {

                    Container pack = zomb.Backpack; // <=== THIS LINE
                    ArrayList mobitems = new ArrayList(mob.Items);
                    foreach (Item item in mobitems)
                    {
                        if ((item.Insured == false) && (item.LootType != LootType.Blessed) && (item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack) && (item.Layer != Layer.Hair) && (item.Layer != Layer.FacialHair))
                        {
                            zomb.EquipItem( item );
                        }
                        if ((item.Insured == false) && (item.LootType != LootType.Blessed) && (item.Layer == Layer.Backpack) )
                        {
                            zomb.AddItem ( item ); // <=== pack.AddItem ( item );
                        }
                    }
 
Last edited:
the items drop to the corpse if a playermobile kills the zombie, but not if a mobile kills the zombie. that's a hint right there that there is an if statement in basecreature, corpse or somewhere else.

will try grimoric's suggestion!
Post automatically merged:

On second thought it might be pack.DropItem ( item ) I'm not sure if pack.AddItem ( item ) creates a new stack every time.

-Grim
On second thought it might be pack.DropItem ( item ) I'm not sure if pack.AddItem ( item ) creates a new stack every time.

-Grim

tried this this morning, and doesn't affect the drop - in fact using pack at all creates a backpack INSIDE the zombie's backpack with the original items, and on death it gets deleted like everything else. the issue is somewhere else, where a check is made if the zombie is killed by a player or a mobile.

basecreature and a few other scripts refer to

base.OnDeath( c );

where does this point to?? (this was taken from ondeath in BAseCreature)
Post automatically merged:

this is the entire ondeath routine in base creature

C#:
        public override void OnDeath( Container c )
        {
            Mobile killer = this.LastKiller;
            Map grave = killer.Map;

            Region reg = Region.Find( this.Location, this.Map );

            QuestTake.DropChest( this );

            // RESET SPAWNERS TIME TO MAX FOR SPAWNS WITH ONLY ONE CREATURE AND A NEARBY RANGE /////////////////////////////////////////////////////////////////////////////
            // THIS KEEPS TIMERS FROM COUNTING DOWN WHILE THE SPAWNER WAITS AND THUS KEEPS A   /////////////////////////////////////////////////////////////////////////////
            // TRUE TIME TO RESPAWN AGAIN ONCE THE MONSTER IS KILLED                           /////////////////////////////////////////////////////////////////////////////

            if ( this.Controlled == false && this.ControlMaster == null && this.Home.X > 0 && this.Home.Y > 0 && grave != null )
            {
                IPooledEnumerable eable = grave.GetItemsInRange( this.Home, 0 );

                foreach ( Item item in eable )
                {
                    if ( item is PremiumSpawner )
                    {
                        PremiumSpawner spwn = (PremiumSpawner)item;

                        if ( spwn.SpawnID == 99999 || ( spwn.Count + spwn.CountA + spwn.CountB + spwn.CountC + spwn.CountD + spwn.CountD ) == 1 && spwn.HomeRange < 10 && spwn.WalkingRange < 10 )
                        {
                            int minSeconds = (int)(spwn.MinDelay).TotalSeconds;
                            int maxSeconds = (int)(spwn.MaxDelay).TotalSeconds;
                            TimeSpan sDelay = TimeSpan.FromSeconds( Utility.RandomMinMax( minSeconds, maxSeconds ) );
                            spwn.DoTimer( sDelay );
                        }
                    }
                }

                eable.Free();
            }

            // WIZARD ADDED THIS FOR KILLS TO SHOW UP IN JOURNAL ///////////////////////////////////////////////////////////////////////////////////////////////////////////

            if (killer is BaseCreature)
            {
                BaseCreature bc_killer = (BaseCreature)killer;
                if(bc_killer.Summoned)
                {
                    if(bc_killer.SummonMaster != null)
                        killer = bc_killer.SummonMaster;
                }
                else if(bc_killer.Controlled)
                {
                    if(bc_killer.ControlMaster != null)
                        killer=bc_killer.ControlMaster;
                }
                else if(bc_killer.BardProvoked)
                {
                    if(bc_killer.BardMaster != null)
                        killer=bc_killer.BardMaster;
                }
            }

            if ( ( killer is PlayerMobile ) && (killer.AccessLevel < AccessLevel.GameMaster) )
            {
                LoggingFunctions.LogBattles( killer, this );
            }

            if ( killer is PlayerMobile )
            {
                AssassinFunctions.CheckTarget( killer, this );
                StandardQuestFunctions.CheckTarget( killer, this, null );
                FishingQuestFunctions.CheckTarget( killer, this, null );
                if ( killer.Backpack.FindItemByType( typeof ( MuseumBook ) ) != null && this.Fame >= 18000 )
                {
                    MuseumBook.FoundItem( killer, 1 );
                }
            }

            Server.Misc.DropRelic.DropSpecialItem( this, killer, c ); // SOME DROP RARE ITEMS

            if ( IsBonded )
            {
                int sound = this.GetDeathSound();

                if ( sound >= 0 )
                    Effects.PlaySound( this, this.Map, sound );

                Warmode = false;

                Poison = null;
                Combatant = null;

                Hits = 0;
                Stam = 0;
                Mana = 0;

                IsDeadPet = true;
                ControlTarget = ControlMaster;
                ControlOrder = OrderType.Follow;

                ProcessDeltaQueue();
                SendIncomingPacket();
                SendIncomingPacket();

                List<AggressorInfo> aggressors = this.Aggressors;

                for ( int i = 0; i < aggressors.Count; ++i )
                {
                    AggressorInfo info = aggressors[i];

                    if ( info.Attacker.Combatant == this )
                        info.Attacker.Combatant = null;
                }

                List<AggressorInfo> aggressed = this.Aggressed;

                for ( int i = 0; i < aggressed.Count; ++i )
                {
                    AggressorInfo info = aggressed[i];

                    if ( info.Defender.Combatant == this )
                        info.Defender.Combatant = null;
                }

                Mobile owner = this.ControlMaster;

                if ( owner == null || owner.Deleted || owner.Map != this.Map || !owner.InRange( this, 12 ) || !this.CanSee( owner ) || !this.InLOS( owner ) )
                {
                    if ( this.OwnerAbandonTime == DateTime.MinValue )
                        this.OwnerAbandonTime = DateTime.Now;
                }
                else
                {
                    this.OwnerAbandonTime = DateTime.MinValue;
                }

                CheckStatTimers();
            }
            else
            {
                if ( !Summoned && !m_NoKillAwards )
                {
                    int totalFame = Fame / 100;
                    int totalKarma = -Karma / 100;

                    List<DamageStore> list = GetLootingRights( this.DamageEntries, this.HitsMax );
                    List<Mobile> titles = new List<Mobile>();
                    List<int> fame = new List<int>();
                    List<int> karma = new List<int>();

                    bool givenQuestKill = false;
                    bool givenFactionKill = false;
                    bool givenToTKill = false;

                    for ( int i = 0; i < list.Count; ++i )
                    {
                        DamageStore ds = list[i];

                        if ( !ds.m_HasRight )
                            continue;

                        Party party = Engines.PartySystem.Party.Get( ds.m_Mobile );

                        if ( party != null )
                        {
                            int divedFame = totalFame / party.Members.Count;
                            int divedKarma = totalKarma / party.Members.Count;

                            for ( int j = 0; j < party.Members.Count; ++j )
                            {
                                PartyMemberInfo info = party.Members[ j ] as PartyMemberInfo;

                                if ( info != null && info.Mobile != null )
                                {
                                    int index = titles.IndexOf( info.Mobile );

                                    if ( index == -1 )
                                    {
                                        titles.Add( info.Mobile );
                                        fame.Add( divedFame );
                                        karma.Add( divedKarma );
                                    }
                                    else
                                    {
                                        fame[ index ] += divedFame;
                                        karma[ index ] += divedKarma;
                                    }
                                }
                            }
                        }
                        else
                        {
                            titles.Add( ds.m_Mobile );
                            fame.Add( totalFame );
                            karma.Add( totalKarma );
                        }

                        OnKilledBy( ds.m_Mobile );

                        if ( !givenFactionKill )
                        {
                            givenFactionKill = true;
                            Faction.HandleDeath( this, ds.m_Mobile );
                        }

                        Region region = ds.m_Mobile.Region;

                        if ( givenQuestKill )
                            continue;

                        PlayerMobile pm = ds.m_Mobile as PlayerMobile;

                        if ( pm != null )
                        {
                            QuestSystem qs = pm.Quest;

                            if ( qs != null )
                            {
                                qs.OnKill( this, c );
                                givenQuestKill = true;
                            }
                        }
                    }
                    for ( int i = 0; i < titles.Count; ++i )
                    {
                        Titles.AwardFame( titles[ i ], fame[ i ], true );
                        Titles.AwardKarma( titles[ i ], karma[ i ], true );
                    }
                }

                base.OnDeath( c );

                if ( DeleteCorpseOnDeath || ( ( this.Name == "a follower" || this.Name == "a sailor" || this.Name == "a pirate" ) && this.EmoteHue > 0 ) )
                    c.Delete();
            }
        }

however, the error was duplicated in servuo as well (per above), so this check is universal
 
Last edited:
I think i've identified where the corpse is being filled:

C#:
        public static Container Mobile_CreateCorpseHandler( Mobile owner, HairInfo hair, FacialHairInfo facialhair, [B]List<Item> initialContent, List<Item> equipItems [/B])
        {
            bool shouldFillCorpse = true;

            Corpse c = new Corpse( owner, hair, facialhair,[U] [/U][B][U]shouldFillCorpse ? equipItems : new List<Item>()[/U][/B] );

            owner.Corpse = c;

            if ( shouldFillCorpse )
            {
                for ( int i = 0; i < initialContent.Count; ++i )
                {
                    Item item = initialContent[i];

                  
[COLOR=rgb(184, 49, 47)][B]                    if ( Core.AOS && owner.Player && item.Parent == owner.Backpack )[/B][/COLOR]
                        c.AddItem( item );
                    else
                        c.DropItem( item );

                    if ( owner.Player && Core.AOS )
                        c.SetRestoreInfo( item, item.Location );
                }


            }

Looks like this line is making it so only the items in the backpack are moved to the corpse if the owner is a player??

if ( Core.AOS && owner.Player && item.Parent == owner.Backpack )

alternatively, the line

shouldFillCorpse ? equipItems : new List<Item>()

appears only to take into account equiped items? I"m a little out of my league on this one
 
update: i decided to brute force this issue. so in the basecreature ondeath method, i added
C#:
            if (killer is BaseCreature && this is Zombiex && this.Items != null)
            {
                ArrayList zombitems = new ArrayList(this.Items);
                foreach (Item item in zombitems)
                {
                    if ( (item.Insured == false) && (item.LootType != LootType.Blessed) && (item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack) && (item.Layer != Layer.Invalid) && (item.Layer != Layer.Hair) && (item.Layer != Layer.FacialHair))
                    {
                    }
                    else if ( (item.Insured == false) && (item.LootType != LootType.Blessed) )
                    {
                    c.AddItem ( item );
                    }
                    
                }
            }

and it works! the items from the zombie that weren't equipped appear in the corpse.
One issue: the items appear in a new backpack inside the corpse's pack. Anyone have any idea why?
Post automatically merged:

update: i decided to brute force this issue. so in the basecreature ondeath method, i added
C#:
            if (killer is BaseCreature && this is Zombiex && this.Items != null)
            {
                ArrayList zombitems = new ArrayList(this.Items);
                foreach (Item item in zombitems)
                {
                    if ( (item.Insured == false) && (item.LootType != LootType.Blessed) && (item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack) && (item.Layer != Layer.Invalid) && (item.Layer != Layer.Hair) && (item.Layer != Layer.FacialHair))
                    {
                    }
                    else if ( (item.Insured == false) && (item.LootType != LootType.Blessed) )
                    {
                    c.AddItem ( item );
                    }
                    
                }
            }

and it works! the items from the zombie that weren't equipped appear in the corpse.
One issue: the items appear in a new backpack inside the corpse's pack. Anyone have any idea why?
 
Back