Variable not being loaded properly

Started by projecttemp, June 26, 2015, 02:10:09 PM

Previous topic - Next topic

projecttemp

For some unknown reason, there is this ONE variable that refuse to load and just give me default value every time.


public override void ExposeData()
        {
            base.ExposeData();

            Scribe_Values.LookValue<int>(ref maxEnergyContrib, "maxEnergyContrib");
            Scribe_Values.LookValue<int>(ref resetCooldowContrib, "resetCooldowContrib");

            Scribe_Values.LookValue<int>(ref energiesPerIntervalContrib, "energiesPerIntervalContrib");
            Scribe_Values.LookValue<int>(ref intervalCounter, "intervalCounter");

            Scribe_Values.LookValue<float>(ref originalPowerCost, "originalPowerCost");
            Scribe_Values.LookValue<bool>(ref generatorEnabled, "generatorEnabled", false, true);
            Scribe_Values.LookValue<bool>(ref thisIsMainShield, "thisIsMainShield", false, true);

            if (thisIsMainShield)
            {
                Scribe_References.LookReference<Building_DimensionalShield>(ref mainShield, "Main_Shield");

                Scribe_Values.LookValue<DShieldStates>(ref shieldMode, "shieldMode");
                Scribe_Values.LookValue<bool>(ref energyToPowerCost, "energyToPowerCost");
                Scribe_Values.LookValue<bool>(ref stuffMultiplier, "stuffMultiplier");
                Scribe_Values.LookValue<bool>(ref cooldownScale, "cooldownScale");

                Scribe_Values.LookValue<int>(ref energy, "energy");
                Scribe_Values.LookValue<int>(ref maxEnergy, "maxEnergy");

                Scribe_Values.LookValue<int>(ref resetCooldown, "resetCooldown");
                Scribe_Values.LookValue<int>(ref resetCounter, "resetCounter");

                Scribe_Values.LookValue<int>(ref energiesPerInterval, "energiesPerInterval");
                Scribe_Values.LookValue<int>(ref ticksPerInterval, "ticksPerInterval");
            }
        }


The variable in this case is "generatorEnabled", i tried changing the name already and it still wouldn't load properly. This only seems to happen if "thisIsMainShield" is actually set. Sub shield with "thisIsMainShield" not set save and load "generatorEnabled" properly.

Edit: It seems this one variable is not being loaded across the board for all structure of this type, the save file show that it is being saved correctly, but when i load and then immediately save again, the variable is no longer true.

Even when i take out the if (thisIsMainShield), it still fail.

mrofa

Be sure that in class structure spawnsetup is above explose data
Since its read from up to bottom.
All i do is clutter all around.

projecttemp

ExposeData is actually the last function on my class

mrofa

All i do is clutter all around.

projecttemp


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using Verse;
using RimWorld;
using UnityEngine;

namespace IntergratedMods_DS
{
    public class Building_DimensionalShield : Building
    {
        #region Variables
        public enum DShieldStates
        {
            Disabled,
            Broken,
            Charging,
            Sustaining
        };

        //Global variables for all the shields combined
        public static int energy = 0;
        public static int maxEnergy = 0;

        private static int energiesPerInterval = 0;
        private static int ticksPerInterval = 0;

        private static int resetCooldown = 0;
        public static int resetCounter = 0;

        public static DShieldStates shieldMode = DShieldStates.Disabled;
        public static Building_DimensionalShield mainShield = null;

        private static bool energyToPowerCost = false;
        private static bool stuffMultiplier = false;
        private static bool cooldownScale = false;

        //Private variables for each individual shield building
        private int maxEnergyContrib = 0;
        private int resetCooldowContrib = 0;

        private int energiesPerIntervalContrib = 0;
        private int intervalCounter = 0;

        private CompPowerTrader powerComp = null;
        private float originalPowerCost = 0;

        private bool generatorEnabled = false;
        private bool thisIsMainShield = false;
        #endregion

        //Do not re-read the data on load, else it will just mess up the calculation
        private void ReadXMLDatas()
        {
            if (def is Thing_DimensionalShield_Gen)
            {
                Thing_DimensionalShield_Gen given = this.def as Thing_DimensionalShield_Gen;

                if (shieldMode == DShieldStates.Disabled)
                {
                    energyToPowerCost = given.Shield_EnergyToPowerCost;
                    stuffMultiplier = given.Shield_StuffMultiplier;
                    cooldownScale = given.Shield_CooldownScale;

                    ticksPerInterval = given.Shield_TicksPerInterval;
                }

                if (stuffMultiplier && this.Stuff != null)
                {
                    maxEnergyContrib = (int)(given.Shield_MaxEnergy + this.Stuff.stuffProps.statOffsets.GetStatOffsetFromList(StatDefOf.MaxHitPoints));
                    maxEnergyContrib = (int)(maxEnergyContrib * this.Stuff.stuffProps.statFactors.GetStatFactorFromList(StatDefOf.MaxHitPoints));
                }
                else
                    maxEnergyContrib = given.Shield_MaxEnergy;

                if (cooldownScale)
                    resetCooldowContrib = maxEnergyContrib / 3;
                else
                    resetCooldowContrib = given.Shield_ResetCooldown;

                energiesPerIntervalContrib = given.Shield_EnergiesPerInterval;

                generatorEnabled = false;
                intervalCounter = 0;
            }
            else
            {
                Log.Error("The building is not of \"Thing_DimensionalShield_Gen\"");
            }
        }

        #region Disable Functions
        //Just in case some stupidity does occur for whatever reasons.
        private void SanityCheck()
        {
            if (energiesPerInterval < 0)
            {
                energiesPerInterval = 0;
            }

            if (maxEnergy < 0)
            {
                maxEnergy = 0;
            }

            if (resetCooldown < 0)
            {
                resetCooldown = 0;
            }
        }

        //Disabling the contribution provided by main generator
        private void MainDisableGen()
        {
            if (generatorEnabled)
            {
                mainShield = null;
                thisIsMainShield = false;
                generatorEnabled = false;

                energiesPerInterval -= energiesPerIntervalContrib;

                maxEnergy -= maxEnergyContrib;
                resetCooldown -= resetCooldowContrib;

                ShutdownShield();

                SanityCheck();
            }
        }

        //Disabling the contribution provided by sub generators
        private void SubDisableGen()
        {
            if (generatorEnabled)
            {
                generatorEnabled = false;

                maxEnergy -= maxEnergyContrib;
                resetCooldown -= resetCooldown;

                energy -= maxEnergyContrib;

                if (energy <= 0)
                {
                    BreakShield();
                }

                SanityCheck();
            }
        }
        #endregion

        #region Enable Functions
        //Turn this building into main shield and enable it's full contribution
        private void EnableMainGen()
        {
            mainShield = this;
            thisIsMainShield = true;

            //If the shield just started, then we add all the stuff to it
            if (!generatorEnabled)
            {
                generatorEnabled = true;

                energiesPerInterval += energiesPerIntervalContrib;

                maxEnergy += maxEnergyContrib;
                resetCooldown += resetCooldowContrib;
            }
            else
                //But if the shield is already sub and takeover, we just add regen
                energiesPerInterval += energiesPerIntervalContrib;

            energy = Math.Max((maxEnergy / 100), 1);
            shieldMode = DShieldStates.Charging;
        }

        //Enable only half the contribution this shield provides
        private void EnableSubGen()
        {
            if (!generatorEnabled)
            {
                thisIsMainShield = false;
                generatorEnabled = true;

                maxEnergy += maxEnergyContrib;
                resetCooldown += resetCooldowContrib;

                if (shieldMode == DShieldStates.Sustaining)
                {
                    shieldMode = DShieldStates.Charging;
                }
            }
        }
        #endregion

        #region Regular Functions
        //Simple function for doing reset counting.
        private void ResetShield()
        {
            resetCounter -= ticksPerInterval;

            if (resetCounter <= 0)
            {
                energy = Math.Max((maxEnergy / 100), 1);
                shieldMode = DShieldStates.Charging;
            }
        }

        //Simple function for doing regular shield charging.
        private void ChargeShield()
        {
            energy += energiesPerInterval;

            if (energy > maxEnergy)
            {
                shieldMode = DShieldStates.Sustaining;
                energy = maxEnergy;
            }
        }
        #endregion

        #region State Functions
        //Support function for stopping the shield.
        public static void ShutdownShield()
        {
            shieldMode = DShieldStates.Disabled;
            energy = 0;
        }

        //Support function for when the shield is broken throught.
        public static void BreakShield()
        {
            shieldMode = DShieldStates.Broken;
            resetCounter = resetCooldown;
            energy = 0;
        }
        #endregion

        #region Damage Function
        //Function for everything to damage the shield
        public static void DamageShield(int amount)
        {
            energy -= amount;

            if (energy < 0)
            {
                BreakShield();
            }
            else
            {
                shieldMode = DShieldStates.Charging;
            }
        }
        #endregion

        //On spawn, get the power component reference
        public override void SpawnSetup()
        {
            base.SpawnSetup();

            powerComp = GetComp<CompPowerTrader>();

            ReadXMLDatas();

            if (energyToPowerCost)
                originalPowerCost = -maxEnergyContrib;
            else
                originalPowerCost = powerComp.PowerOutput;
        }

        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            if (thisIsMainShield)
                MainDisableGen();
            else
                SubDisableGen();

            base.Destroy(mode);
        }

        public override void Tick()
        {
            base.Tick();

            intervalCounter++;

            if (intervalCounter >= ticksPerInterval)
            {
                intervalCounter = 0;

                if (shieldMode == DShieldStates.Charging)
                {
                    #region Charging State
                    if (thisIsMainShield)
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                MainDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost;
                            }
                        }

                        ChargeShield();
                    }
                    else
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                SubDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost;
                                EnableSubGen();
                            }
                        }
                    }
                    #endregion
                }
                else if (shieldMode == DShieldStates.Sustaining)
                {
                    #region Sustaining State
                    if (thisIsMainShield)
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                MainDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost / 5.0f;
                            }
                        }
                    }
                    else
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                SubDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost / 5.0f;
                                EnableSubGen();
                            }
                        }
                    }
                    #endregion
                }
                else if (shieldMode == DShieldStates.Broken)
                {
                    #region Broken State
                    if (thisIsMainShield)
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                MainDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost;
                            }
                        }

                        ResetShield();
                    }
                    else
                    {
                        if (powerComp != null)
                        {
                            if (!powerComp.PowerOn)
                            {
                                SubDisableGen();
                                return;
                            }
                            else
                            {
                                powerComp.powerOutputInt = originalPowerCost;
                                EnableSubGen();
                            }
                        }
                    }
                    #endregion
                }
                else if (shieldMode == DShieldStates.Disabled)
                {
                    #region Disabled State
                    if (powerComp != null)
                    {
                        if (powerComp.PowerOn)
                        {
                            EnableMainGen();
                        }
                    }
                    else
                    {
                        EnableMainGen();
                    }

                    return;
                    #endregion
                }
            }
        }

        public override string GetInspectString()
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.AppendLine(base.GetInspectString());

            if (thisIsMainShield)
            {
                stringBuilder.AppendLine("Main Shield!");

                if (shieldMode == DShieldStates.Disabled)
                {
                    stringBuilder.AppendLine("Shield State: Disabled");
                }
                else if (shieldMode == DShieldStates.Broken)
                {
                    stringBuilder.AppendLine("Shield State: Broken");
                    stringBuilder.AppendLine("Reform Time: " + resetCounter);
                }
                else if (shieldMode == DShieldStates.Charging)
                {
                    stringBuilder.AppendLine("Shield State: Charging");
                    stringBuilder.AppendLine("Energy: " + energy + "/" + maxEnergy);
                }
                else if (shieldMode == DShieldStates.Sustaining)
                {
                    stringBuilder.AppendLine("Shield State: Sustaining");
                    stringBuilder.AppendLine("Energy: " + energy + "/" + maxEnergy);
                }
            }
            else
            {
                if (generatorEnabled)
                {
                    stringBuilder.AppendLine("Sub Shield: Enabled");

                    if (shieldMode == DShieldStates.Disabled)
                    {
                        stringBuilder.AppendLine("Shield State: Disabled");
                    }
                    else if (shieldMode == DShieldStates.Broken)
                    {
                        stringBuilder.AppendLine("Shield State: Broken");
                        stringBuilder.AppendLine("Reform Time: " + resetCounter);
                    }
                    else if (shieldMode == DShieldStates.Charging)
                    {
                        stringBuilder.AppendLine("Shield State: Charging");
                        stringBuilder.AppendLine("Energy: " + energy + "/" + maxEnergy);
                    }
                    else if (shieldMode == DShieldStates.Sustaining)
                    {
                        stringBuilder.AppendLine("Shield State: Sustaining");
                        stringBuilder.AppendLine("Energy: " + energy + "/" + maxEnergy);
                    }
                }
                else
                    stringBuilder.AppendLine("Sub Shield: Disabled");
            }

            return stringBuilder.ToString();
        }

        public override void ExposeData()
        {
            base.ExposeData();

            Scribe_Values.LookValue<int>(ref maxEnergyContrib, "maxEnergyContrib");
            Scribe_Values.LookValue<int>(ref resetCooldowContrib, "resetCooldowContrib");

            Scribe_Values.LookValue<int>(ref energiesPerIntervalContrib, "energiesPerIntervalContrib");
            Scribe_Values.LookValue<int>(ref intervalCounter, "intervalCounter");

            Scribe_Values.LookValue<float>(ref originalPowerCost, "originalPowerCost");
            Scribe_Values.LookValue<bool>(ref generatorEnabled, "generatorEnabled");
            Scribe_Values.LookValue<bool>(ref thisIsMainShield, "thisIsMainShield");

            Scribe_References.LookReference<Building_DimensionalShield>(ref mainShield, "Main_Shield");

            Scribe_Values.LookValue<DShieldStates>(ref shieldMode, "shieldMode");
            Scribe_Values.LookValue<bool>(ref energyToPowerCost, "energyToPowerCost");
            Scribe_Values.LookValue<bool>(ref stuffMultiplier, "stuffMultiplier");
            Scribe_Values.LookValue<bool>(ref cooldownScale, "cooldownScale");

            Scribe_Values.LookValue<int>(ref energy, "energy");
            Scribe_Values.LookValue<int>(ref maxEnergy, "maxEnergy");

            Scribe_Values.LookValue<int>(ref resetCooldown, "resetCooldown");
            Scribe_Values.LookValue<int>(ref resetCounter, "resetCounter");

            Scribe_Values.LookValue<int>(ref energiesPerInterval, "energiesPerInterval");
            Scribe_Values.LookValue<int>(ref ticksPerInterval, "ticksPerInterval");
        }
    }
}

mrofa

All i do is clutter all around.

Haplo

The problem is most likely this in your ReadXMLDatas() part:
generatorEnabled = false;

SpawnSetup() is called AFTER ExposeData() when you load a game..

projecttemp

Quote from: Haplo on June 26, 2015, 04:38:41 PM
The problem is most likely this in your ReadXMLDatas() part:
generatorEnabled = false;

SpawnSetup() is called AFTER ExposeData() when you load a game..

Thank you, this help fixed. I always thought SpawnSetup was only called during first time it was created. I wish they have a wiki for modding this like for skyrim.

Haplo

SpawnSetup is called once when the object is spawned into the world.
So if you load something it's data comes from ExposeData and only when that is done will it be spawned according to the read data.

projecttemp

Knowing this, it was a very easy fix to it. Now i can release my mod.

mipen

Off topic, but remember that the value of a static member is shared by all instances of that class, so changing it in one class will change it for all of them. Just letting you know if that wasn't how you intended it