RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

A Contagious Zombie

peepeetree

Sorceror
I just tested it and it works perfectly, thanks again Thagoras!

The_Man when you look in basecreature under serialize you can scroll down and see what the last version is currently at. You then add one number above that, so in my case it was 18, see the stuff highlighted below.

Code:
public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            [COLOR=#ff0000]writer.Write( (int) 18 ); // version[/COLOR]
 
            writer.Write( (int)m_CurrentAI );
            writer.Write( (int)m_DefaultAI );
 
            writer.Write( (int)m_iRangePerception );
            writer.Write( (int)m_iRangeFight );
 
            writer.Write( (int)m_iTeam );
 
            writer.Write( (double)m_dActiveSpeed );
            writer.Write( (double)m_dPassiveSpeed );
            writer.Write( (double)m_dCurrentSpeed );
 
            writer.Write( (int) m_pHome.X );
            writer.Write( (int) m_pHome.Y );
            writer.Write( (int) m_pHome.Z );
 
            [COLOR=#ff0000]// Version 1[/COLOR]
            writer.Write( (int) m_iRangeHome );
 
            int i=0;
 
            writer.Write( (int) m_arSpellAttack.Count );
            for ( i=0; i< m_arSpellAttack.Count; i++ )
            {
                writer.Write( m_arSpellAttack[i].ToString() );
            }
 
            writer.Write( (int) m_arSpellDefense.Count );
            for ( i=0; i< m_arSpellDefense.Count; i++ )
            {
                writer.Write( m_arSpellDefense[i].ToString() );
            }
 
            [COLOR=#ff0000]// Version 2[/COLOR]
            writer.Write( (int) m_FightMode );
 
            writer.Write( (bool) m_bControlled );
            writer.Write( (Mobile) m_ControlMaster );
            writer.Write( (Mobile) m_ControlTarget );
            writer.Write( (Point3D) m_ControlDest );
            writer.Write( (int) m_ControlOrder );
            writer.Write( (double) m_dMinTameSkill );
            // Removed in version 9
            //writer.Write( (double) m_dMaxTameSkill );
            writer.Write( (bool) m_bTamable );
            writer.Write( (bool) m_bSummoned );
 
            if ( m_bSummoned )
                writer.WriteDeltaTime( m_SummonEnd );
 
            writer.Write( (int) m_iControlSlots );
 
            [COLOR=#ff0000]// Version 3[/COLOR]
            writer.Write( (int)m_Loyalty );
 
         [COLOR=#ff0000]   // Version 4[/COLOR]
            writer.Write( m_CurrentWayPoint );
 
           [COLOR=#ff0000] // Verison 5[/COLOR]
            writer.Write( m_SummonMaster );
 
            [COLOR=#ff0000]// Version 6[/COLOR]
            writer.Write( (int) m_HitsMax );
            writer.Write( (int) m_StamMax );
            writer.Write( (int) m_ManaMax );
            writer.Write( (int) m_DamageMin );
            writer.Write( (int) m_DamageMax );
 
            [COLOR=#ff0000]// Version 7[/COLOR]
            writer.Write( (int) m_PhysicalResistance );
            writer.Write( (int) m_PhysicalDamage );
 
            writer.Write( (int) m_FireResistance );
            writer.Write( (int) m_FireDamage );
 
            writer.Write( (int) m_ColdResistance );
            writer.Write( (int) m_ColdDamage );
 
            writer.Write( (int) m_PoisonResistance );
            writer.Write( (int) m_PoisonDamage );
 
            writer.Write( (int) m_EnergyResistance );
            writer.Write( (int) m_EnergyDamage );
 
           [COLOR=#ff0000] // Version 8[/COLOR]
            writer.Write( m_Owners, true );
 
          [COLOR=#ff0000]  // Version 10[/COLOR]
            writer.Write( (bool) m_IsDeadPet );
            writer.Write( (bool) m_IsBonded );
            writer.Write( (DateTime) m_BondingBegin );
            writer.Write( (DateTime) m_OwnerAbandonTime );
 
          [COLOR=#ff0000]  // Version 11[/COLOR]
            writer.Write( (bool) m_HasGeneratedLoot );
 
           [COLOR=#ff0000] // Version 12[/COLOR]
            writer.Write( (bool) m_Paragon );
 
            [COLOR=#ff0000]// Version 13[/COLOR]
            writer.Write( (bool) ( m_Friends != null && m_Friends.Count > 0 ) );
 
            if ( m_Friends != null && m_Friends.Count > 0 )
                writer.Write( m_Friends, true );
 
            [COLOR=#ff0000]// Version 14[/COLOR]
            writer.Write( (bool)m_RemoveIfUntamed );
            writer.Write( (int)m_RemoveStep );
 
         [COLOR=#ff0000]   // Version 17[/COLOR]
            if ( IsStabled || ( Controlled && ControlMaster != null ) )
                writer.Write( TimeSpan.Zero );
            else
                writer.Write( DeleteTimeLeft );
           
   [COLOR=#99cc00]         // Version 18       [/COLOR]    
            //Start Zombiex edit
                    writer.Write( (bool) m_CanInfect);
            //End Zombitx edit
        }
 

Thagoras

Sorceror
And how do you know what version something is or should be?

That's a little more tricky. Any time you alter your serializers there is potential for problems.
Most people who post here (if they've modified an existing scripts' serializers) will have updated the version number in favor of their shard or the current distro release (usually the latter).

The version number is merely a reference to how many changes the serializers have undergone. It's usually the first line in the serializer and the last entry in the deserializer (which also lets you find the correct entrie(s) in the serializer at the bottom. The reason for this is when you add more data to save, any EXISTING objects of that type on your shard need to be updated...and the version is a way to prevent a crash followed by the deletion of all instances of that older version. It allows the older versions to load their data...without trying to load the newer versions' data. They then update (or at least start saving the new versions' data) and "bam", they're the newer version too.
 

EvilJason

Sorceror
This is a very fun script on a server. I used it on my own in the past and i'll be looking at it again now that I'm getting back into RunUO.

Good job and very creative!
 

Eteri

Traveler
First I'll explain more about Serialize/Deserialize only because it helps with understanding the concept a little better in my opinion.

Alright, when you enter / exit play mode or change a script RunUo has to reload the mono assemblies, that is the dll’s associated with RunUo.
On the user side this is a 3 step process:
  • Pull all the serializable data out of managed area, creating an internal representation of the data on the C# side of RunUo.
  • Destroy all memory / information associated with the managed side of RunUo, and reload the assemblies.
  • Reserialize the data that was saved in C# back into managed land.
What this means is that for your data structures / information to survive an assembly reload you need to ensure that it can get serialized into and out of c# memory properly. Doing this also means that (with some minor modifications) you can save this data structure to an asset file and reload it at a later date.

So to figure out a versions amount by comparing how many files you have that need to serialize during a reload of runuo. Being that we use RunUo and all the files are ready for us from the get go, the beginning amount of version are all there for the .cs files that need it. Now if you ever need to add another you can see the version number they have provided. If you don't have a version number you have to keep checking through the processes til you see where each serialize/deserialize happens.

Hope that helps answer your question, if I missed something just let me know and I'll try to make sure I can help you out.
 

peepeetree

Sorceror
Just to again give this script praise, this is the best monster in the game, I am making an entire dungeon out of these guys.
 

fcondon

Sorceror
I was testing this script last night and I had a couple questions.

1.) I was under the impression that this script would attack other NPCs (I thought that was the point for all the undead checks, so it didn't attack them) but I couldn't actually get it to attack another NPC, was I wrong?

2.) Are GM Robes not blessed? I went into player mode, and after the zombie killed me, the guy guy that spawned had a GM robe on him. lol

3.) I was also under the impression that the mob that spawned has all the (non blessed) items you had, including gear. but when the spawned mob died, he has 2 of every item you had. (one on his corpse, and another in a backpack on his corpse) How do I make it so this can't be an easy way to dupe items?
 

Thagoras

Sorceror
I'll start with question 3.
These aren't duped items. They are cloned items with no special abilities...infact, they're JUST basetype item. You can wear and wield the items only because they happen to reflect the same layer as the item they've been cloned from. The zombie colored backpack contains all the actual gear your playermobile had before becoming a zombie. I did this back before I knew a whole lot about scripting. If I were to do it now: upon death, I'd have the zombie 'put on' all the gear so the pack wasn't necessary.

Question 2. Blessed depends on your shard. I'd like to say yes...but... not always. However, when the zombie infects you, it clones everything you're wearing. If it happens to be a GM robe....it will be an item that looks like a gm robe and can be worn...but isn't even a robe. Again...perhaps someday I'll go back and have it 'put on' all the original gear. I didn't want to give the zombies any special advantage...just wanted them to look like who they infected...so you know who has your stuff.

Question 1. Mine all do. But I also have all the bells and whistles installed so they don't infect npcs unless the caninfect variable is set to true. By attack method and IsEnemy module, they should be attacking npcs. Perhaps the npcs are blessed or not moving? Just trying to think why they wouldn't be attacking npcs.
 

fcondon

Sorceror
I'll play with this some more tonight and try and figure out why it's not properly attacking other npcs. Maybe the easy way would be to just make the items that are just the base items (not your actual gear) blessed to the clone so that when players go to loot them they wont even see the base items? I'm not good enough at the language to try and sort that out, is that an easier solution that you could tell me what to change? Thanks for the great script man. It really is awesome.

EDIT: They seem to attack other NPCs fine. It must have been an issue with the environment from when I originally tested it. Apologies.
 

richardpt

Wanderer
can someone post the playermobile.cs and basecreature.cs and corpse.cs, got mine all messed up would love to set this one up. thank you
 

peepeetree

Sorceror
Here is mine richardpt, but you are going to have to remove the other mods I have added or just copy the ZombieX script out of it into yours. I hope this helps!
 

Attachments

  • PlayerMobile.cs
    111.4 KB · Views: 15
  • BaseCreature.cs
    133.7 KB · Views: 16
  • Corpse.cs
    31.7 KB · Views: 13
Top