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!

[RunUO 2.0 RC2]Jako Leveling System (Balanced Pet Leveling)

deides

Traveler
Deimos, thanks for yourfile, howeverstill hving the sameproblem on my basecreature. I will try and work on this and will post mine here too
 

Jerbal

Sorceror
Glad to see many of you got it. Serialization is something that is really nasty, but not too bad when you finally understand how it works. As this is apparently the biggest problem with this script, let me try to help resolve this confusion:


The way a save works is it takes all of those numbers and types and puts them in one giant string, one after another, then writes it to disk. The reason the shard is crashing is because you are telling it to read a number that isn't there. This is because the version 'if tests' are not done correctly.

This version number is strictly to help it in deserializing when the time comes, nothing else. With out it, you would have this crashing issue every time you added something. When you make a change to the serialization of an object, you must increase the version number (by one is all that is needed) and have an if test in Deserialize around what you want to deserialze. Again, if you do not have the if test around deserialize, when the CURRENT shard save (which does not have these serialization changes) tries to load, it will try to deserialize data that does not exist and will crash.

Good luck! Past what I have already said, I don't know how I can help with out doing it for you. God speed! =P
 

Nomack

Sorceror
if pet decreased, level is -1 down. but ı have experience not level is +1.
ı think is bug. my bad is english sorry.:)
 

Lord_Velius

Sorceror
I'm having an issue with the levels on pets saving on world save.
They appear fine, but on rebook, they reset back to lvl 1.

My serilization looks fine, do you happen to know what bool is saved so they can remember the levels gained.
I'll go from there and check my end, I'm just not familiar with which it is on the saving.
 

Jerbal

Sorceror
Having not looked at this in some time, I can't think of any reason why this would happen unless it's de-serializing a wrong number. If it's invalid, I believe it sets it to one. Most monsters start at a higher level than one, so a reset to one doesn't make sense.

Is this "real" level, or displayed level?
 

Lord_Velius

Sorceror
It's their current level, not sure if its the displayed one or real one.

I can tame a ww, level it 4-5 times, then save/restart.
Come back and it is indeed lvl 1.
 

Jerbal

Sorceror
Check the experience before and after save. I'm pretty sure the "real" level is saved as an integer, but the the displayed is saved via a formula given experience. One of those is probably getting mangled in the save.

Did you modify any of the settings from default?
 

Lord_Velius

Sorceror
I kept all the default settings since it was dealing with saving data so I left it be.

I'll double check again to make sure I'm not overlooking anything.

After looking it looks good from what I'm seeing, even double checked serilize/deserilize and it matches up.

I put in the killer null check
Code:
        if (killer == null || killer is PlayerMobile || !this.JakoIsEnabled || (killer is BaseCreature && ((BaseCreature)killer).Controlled && ((BaseCreature)killer).ControlMaster != null || !((BaseCreature)killer).JakoIsEnabled))
 

Jerbal

Sorceror
Could you paste your serialize/deserialize? I honestly don't think it's the problem, but this is a new issue that hasn't come up yet, so I'm starting with the one that has caused the most problems. (when doesn't it...)
 

Lord_Velius

Sorceror
Code:
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)20); // version

            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);

            // Version 1
            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());
            }

            // Version 2
            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);

            // Version 3
            writer.Write((int)m_Loyalty);

            // Version 4
            writer.Write(m_CurrentWayPoint);

            // Verison 5
            writer.Write(m_SummonMaster);

            // Version 6
            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);

            // Version 7
            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);

            // Version 8
            writer.Write(m_Owners, true);

            // Version 10
            writer.Write((bool)m_IsDeadPet);
            writer.Write((bool)m_IsBonded);
            writer.Write((DateTime)m_BondingBegin);
            writer.Write((DateTime)m_OwnerAbandonTime);

            // Version 11
            writer.Write((bool)m_HasGeneratedLoot);

            // Version 12
            writer.Write((bool)m_Paragon);

            // Version 13
            writer.Write((bool)(m_Friends != null && m_Friends.Count > 0));

            if (m_Friends != null && m_Friends.Count > 0)
                writer.Write(m_Friends, true);

            // Version 14
            writer.Write((bool)m_RemoveIfUntamed);
            writer.Write((int)m_RemoveStep);

            #region Mondain's Legacy version 17
            writer.Write((bool)m_Allured);
            #endregion

            // Version 18
            if (IsStabled || (Controlled && ControlMaster != null))
                writer.Write(TimeSpan.Zero);
            else
                writer.Write(DeleteTimeLeft);

           // Version 19
           writer.Write((bool)m_Tyrant);

            // Version 20
            if (Tamable)
            {
                writer.Write(m_level);
                writer.Write(m_realLevel);
                writer.Write(m_experience);
                writer.Write(m_maxLevel);
                writer.Write(m_traits);
                m_jakoAttributes.Serialize(writer);
            }
        }
Code:
        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            m_CurrentAI = (AIType)reader.ReadInt();
            m_DefaultAI = (AIType)reader.ReadInt();

            m_iRangePerception = reader.ReadInt();
            m_iRangeFight = reader.ReadInt();

            m_iTeam = reader.ReadInt();

            m_dActiveSpeed = reader.ReadDouble();
            m_dPassiveSpeed = reader.ReadDouble();
            m_dCurrentSpeed = reader.ReadDouble();

            if (m_iRangePerception == OldRangePerception)
                m_iRangePerception = DefaultRangePerception;

            m_pHome.X = reader.ReadInt();
            m_pHome.Y = reader.ReadInt();
            m_pHome.Z = reader.ReadInt();

            if (version >= 1)
            {
                m_iRangeHome = reader.ReadInt();

                int i, iCount;

                iCount = reader.ReadInt();
                for (i = 0; i < iCount; i++)
                {
                    string str = reader.ReadString();
                    Type type = Type.GetType(str);

                    if (type != null)
                    {
                        m_arSpellAttack.Add(type);
                    }
                }

                iCount = reader.ReadInt();
                for (i = 0; i < iCount; i++)
                {
                    string str = reader.ReadString();
                    Type type = Type.GetType(str);

                    if (type != null)
                    {
                        m_arSpellDefense.Add(type);
                    }
                }
            }
            else
            {
                m_iRangeHome = 0;
            }

            if (version >= 2)
            {
                m_FightMode = (FightMode)reader.ReadInt();

                m_bControlled = reader.ReadBool();
                m_ControlMaster = reader.ReadMobile();
                m_ControlTarget = reader.ReadMobile();
                m_ControlDest = reader.ReadPoint3D();
                m_ControlOrder = (OrderType)reader.ReadInt();

                m_dMinTameSkill = reader.ReadDouble();

                if (version < 9)
                    reader.ReadDouble();

                m_bTamable = reader.ReadBool();
                m_bSummoned = reader.ReadBool();

                if (m_bSummoned)
                {
                    m_SummonEnd = reader.ReadDeltaTime();
                    new UnsummonTimer(m_ControlMaster, this, m_SummonEnd - DateTime.Now).Start();
                }

                m_iControlSlots = reader.ReadInt();
            }
            else
            {
                m_FightMode = FightMode.Closest;

                m_bControlled = false;
                m_ControlMaster = null;
                m_ControlTarget = null;
                m_ControlOrder = OrderType.None;
            }

            if (version >= 3)
                m_Loyalty = reader.ReadInt();
            else
                m_Loyalty = MaxLoyalty; // Wonderfully Happy

            if (version >= 4)
                m_CurrentWayPoint = reader.ReadItem() as WayPoint;

            if (version >= 5)
                m_SummonMaster = reader.ReadMobile();

            if (version >= 6)
            {
                m_HitsMax = reader.ReadInt();
                m_StamMax = reader.ReadInt();
                m_ManaMax = reader.ReadInt();
                m_DamageMin = reader.ReadInt();
                m_DamageMax = reader.ReadInt();
            }

            if (version >= 7)
            {
                m_PhysicalResistance = reader.ReadInt();
                m_PhysicalDamage = reader.ReadInt();

                m_FireResistance = reader.ReadInt();
                m_FireDamage = reader.ReadInt();

                m_ColdResistance = reader.ReadInt();
                m_ColdDamage = reader.ReadInt();

                m_PoisonResistance = reader.ReadInt();
                m_PoisonDamage = reader.ReadInt();

                m_EnergyResistance = reader.ReadInt();
                m_EnergyDamage = reader.ReadInt();
            }

            if (version >= 8)
                m_Owners = reader.ReadStrongMobileList();
            else
                m_Owners = new List<Mobile>();

            if (version >= 10)
            {
                m_IsDeadPet = reader.ReadBool();
                m_IsBonded = reader.ReadBool();
                m_BondingBegin = reader.ReadDateTime();
                m_OwnerAbandonTime = reader.ReadDateTime();
            }

            if (version >= 11)
                m_HasGeneratedLoot = reader.ReadBool();
            else
                m_HasGeneratedLoot = true;

            if (version >= 12)
                m_Paragon = reader.ReadBool();
            else
                m_Paragon = false;

            if (version >= 13 && reader.ReadBool())
                m_Friends = reader.ReadStrongMobileList();
            else if (version < 13 && m_ControlOrder >= OrderType.Unfriend)
                ++m_ControlOrder;

            if (version < 16 && Loyalty != MaxLoyalty)
                Loyalty *= 10;

            double activeSpeed = m_dActiveSpeed;
            double passiveSpeed = m_dPassiveSpeed;

            SpeedInfo.GetSpeeds(this, ref activeSpeed, ref passiveSpeed);

            bool isStandardActive = false;
            for (int i = 0; !isStandardActive && i < m_StandardActiveSpeeds.Length; ++i)
                isStandardActive = (m_dActiveSpeed == m_StandardActiveSpeeds[i]);

            bool isStandardPassive = false;
            for (int i = 0; !isStandardPassive && i < m_StandardPassiveSpeeds.Length; ++i)
                isStandardPassive = (m_dPassiveSpeed == m_StandardPassiveSpeeds[i]);

            if (isStandardActive && m_dCurrentSpeed == m_dActiveSpeed)
                m_dCurrentSpeed = activeSpeed;
            else if (isStandardPassive && m_dCurrentSpeed == m_dPassiveSpeed)
                m_dCurrentSpeed = passiveSpeed;

            if (isStandardActive && !m_Paragon)
                m_dActiveSpeed = activeSpeed;

            if (isStandardPassive && !m_Paragon)
                m_dPassiveSpeed = passiveSpeed;

            if (version >= 14)
            {
                m_RemoveIfUntamed = reader.ReadBool();
                m_RemoveStep = reader.ReadInt();
            }

            TimeSpan deleteTime = TimeSpan.Zero;


            if (version >= 18)
            {
                try
                {
                    deleteTime = reader.ReadTimeSpan();
                }
                catch(System.ArgumentOutOfRangeException excep)
                {
                    Console.WriteLine("Exception occured Timer");
                }
                finally
                {
                    deleteTime = TimeSpan.Zero;
                }
            }



            #region Mondain's Legacy version 15
            if (version >= 17)
                m_Allured = reader.ReadBool();
            #endregion

            if (version <= 14 && m_Paragon && Hue == 0x31)
            {
                Hue = Paragon.Hue; //Paragon hue fixed, should now be 0x501.
            }

            CheckStatTimers();

            ChangeAIType(m_CurrentAI);

            AddFollowers();


            if (IsAnimatedDead)
                Spells.Necromancy.AnimateDeadSpell.Register(m_SummonMaster, this);

            if (version >= 19)
                m_Tyrant = reader.ReadBool();

            if (version >= 20 & Tamable)
            {
                m_level = reader.ReadUInt();
                m_realLevel = reader.ReadUInt();
                m_experience = reader.ReadUInt();
                m_maxLevel = reader.ReadUInt();
                m_traits = reader.ReadUInt();
                m_jakoAttributes.Deserialize(reader);
            }
        }
 

Jerbal

Sorceror
Please make sure that the creature that you're leveling is marked as tamable (It shouldn't be leveling if it isn't).Did you [add-ed it and then just 'a mobile obey'? If it is not tamable, the level will reset to 1, and never save or load the level from the save.

Do you get the animal lore gump change on this mobile?
 

Lord_Velius

Sorceror
Please make sure that the creature that you're leveling is marked as tamable (It shouldn't be leveling if it isn't).Did you [add-ed it and then just 'a mobile obey'? If it is not tamable, the level will reset to 1, and never save or load the level from the save.

Do you get the animal lore gump change on this mobile?

No I'm talking everything from chickens to drakes, all tamed not obeyed.

@Duplex
Tried that with no luck.
 

Jerbal

Sorceror
What's the value of [get experience before and after a world save load?

And The animal lore gump is still a valid question. Do you get the one when you're not the owner and when you are? (you may have to be a non-GM for that to work, I don't remember if it will auto-show GMs)
 

Lord_Velius

Sorceror
I didn't even see the animal lore gump question, I can still get the modified animal lore gump as both player and staff.
So we are using your animal lore gump setup, let me do a get on exp real quick.

Exp seems to be savign now, and as of last restart levels on what I did check didn't reset.
If it helps sometimes I can restart a few times before they reset.

Exp seems to be saving though.
 

Lord_Velius

Sorceror
yes it appears to be working now, I haven't implemented any changes it just decided to work.
I have no clue whay it wasn't beforehand, I haven't edited any scripts since I placed this in, nor did I add or remove any.

It is indeed working, and so we'll just go with it.
I'll keep my eye out and if things change again I'll let you know.

I'll look and see if it was a specific pet that wouldn't save exp, or if it was an attribute associated to it (like paragon ect) that maybe kept it from keeping level data.
 

Lord_Velius

Sorceror
Ok I have a player informing me that his pets that were out when the server was restarted didn't level reset, but those when shrunk were reset.
No one stables pets so were going to level a few up and stable them and check
 

Jerbal

Sorceror
Ok I have a player informing me that his pets that were out when the server was restarted didn't level reset, but those when shrunk were reset.
No one stables pets so were going to level a few up and stable them and check

This makes sense. Edit the serialize/deserialze of the shrink script to add the Jako information and it will be all magic and ponies.
 
Top