Problems loading extra xml variables for an item.

Started by MonkeyWithAWrench, August 19, 2014, 07:59:21 PM

Previous topic - Next topic

MonkeyWithAWrench

Hello everybody. This is the first time I thought I'd try my hand at creating a mod, but I seem to have into a little snag.

I wanted to add the ability to load a variable for an item from it's xml so it didn't have to be hardcoded into the dll. I found a couple helpful posts about this in the forums here, as well as some good examples about this in a few other peoples mods. So thanks to everybody for that awesome work.

The thing is though, all that stuff was about buildings and the like. When I extend an item or thing class with that stuff it doesn't seem to load anything. Everything else seems to work fine and it doesn't throw any error messages. Does anyone know if this can be done with items or is this extra variable thing only available to buildings?

mrofa

Can you post your code ?
Also this is a link to my two .cs files from extended bullets, that use extra xml stuff.
All i do is clutter all around.

MonkeyWithAWrench

Sure, I'd be happy for the direct help. I'm always a little embarrassed doing things like showing off code just because I'm always afraid I'm doing an embarrassingly terrible job, but oh well.

oh, I made a couple edits to it first to bring it more inline with the example you provided above (thank you by the way). Still didn't seem to work though. anyway, here we go...

Here's the c# file in question, named FuelRod.cs:

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

using UnityEngine;         // Always needed
//using VerseBase;         // Material/Graphics handling functions are found here
using Verse;               // RimWorld universal objects are here (like 'Building')
using Verse.AI;            // Needed when you do something with the AI
//using Verse.Sound;       // Needed when you do something with the Sound
using RimWorld;            // RimWorld specific functions are found here (like 'Building_Battery')
//using RimWorld.Planet;   // RimWorld specific functions for world creation
//using RimWorld.SquadAI;  // RimWorld specific functions for squad brains

namespace Nuclear_Generator
{

    /// <summary>
    /// The ThingDef to define new variables for the "fuelrod" xml
    /// </summary>
    internal class ThingDef_FuelRod : ThingDef
    {
        /// <summary>
        /// Max "energy" level of rod. Generator removes "energy" at a fixed rate from the rod until it is spent.
        /// </summary>
        public int MaxEnergyLevel = 0;
    }

    /// <summary>
    /// Class for the FuelRod. Mainly just to track/show how much energy is left in it.
    /// </summary>
    public class FuelRod : ThingWithComponents
    {
        /// <summary>
        /// the max "energy" level. can never be less then 0.
        /// </summary>
        public int EnergyLevelMax { get; private set; }
        /// <summary>
        /// the current "energy" level. can never be less then 0.
        /// </summary>
        public int EnergyLevelCurrent { get; set; }

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

            ThingDef_FuelRod FuelRodDef = (ThingDef_FuelRod)this.def;
            EnergyLevelCurrent = FuelRodDef.MaxEnergyLevel;
        }

        /// <summary>
        /// Replaces/adds to the text that'll be shown in the lower left info box when the rod is selected.
        /// really just displays the percentage of energy remaining in the rod.
        /// </summary>
        /// <returns>the string of text for the info box</returns>
        public override string GetInspectString()
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append(base.GetInspectString());

            stringBuilder.Append("Current Energy Level: " + EnergyLevelCurrent);
            stringBuilder.AppendLine();
            stringBuilder.Append("Max Energy Level: " + EnergyLevelMax);

            return stringBuilder.ToString();
        }
    }

}


I'm sure you can guess at what kind of mod I'm working on now...

Here's the xml file for it as well:
<?xml version="1.0" encoding="utf-8" ?>
<Resources>

<ThingDef class="Nuclear_Generator.ThingDef_FuelRod"> <!--ParentName="ResourceBase"-->
<category>Item</category>
<eType>Item</eType>
<resourceReadoutPriority>Middle</resourceReadoutPriority>
<useStandardHealth>true</useStandardHealth>
<selectable>true</selectable>
<maxHealth>100</maxHealth>
<altitudeLayer>Item</altitudeLayer>
<stackLimit>1</stackLimit>
<tradersCarry>true</tradersCarry>
<comps>
<li><compClass>CompForbiddable</compClass></li>
</comps>
<beauty>Ugly</beauty>
<alwaysHaulable>true</alwaysHaulable>
<drawGUIOverlay>true</drawGUIOverlay>
<rotatable>false</rotatable>
<pathCost>15</pathCost>

<defName>FuelRod</defName>
<label>Fuel Rod</label>
<ThingClass>Nuclear_Generator.FuelRod</ThingClass>
<description>A uranium fuel rod for use in a reactor.</description>
<texturePath>Things/FuelRodTemp</texturePath>
<soundInteract>Metal_Drop</soundInteract>
<soundDrop>Metal_Drop</soundDrop>
<basePrice>5</basePrice>
<storeCategories>
<li>Manufactured</li>
</storeCategories>

<!--
Max amount of "energy" or "work" that the rod can do/handle.
The generator removes a set amount of "energy" from each rod every
so often.
Once empty it becomes "spent", and the generator can't use it anymore.
-->
<MaxEnergyLevel>1000</MaxEnergyLevel>
</ThingDef>

</Resources>


I did have it split between a "resource base" class and the main one, but I've stuck it all in one temporarily while trying to get this to work.

I get the distinct impression that I'm just missing something obvious and I'll probably feel really silly once it's pointed out  :-[

RawCode

You must extend thing def in your code with fields you like and define your thing def, not basic type.

Game load XML in very simple manner, it construct type and set fields of that type to values stored in XML.
If type does not have field - nothing happens.

MonkeyWithAWrench

I must definitely be missing the obvious here. I very much appreciate your taking the time to have a look at what I posted, but I'm afraid I'm just not seeing what I'm missing. Or probably more appropriately, I'm just not seeing where I'm missing it. Thanks for the pointers though,

Haplo

Hmm, I'm also not sure where you've done an error. It looks fine on a first look through.
The only problem I see is in your GetInspectionString():
Your variables need the extension .ToString()
            stringBuilder.Append("Current Energy Level: " + EnergyLevelCurrent.ToString());
            stringBuilder.AppendLine();
            stringBuilder.Append("Max Energy Level: " + EnergyLevelMax.ToString());

At least my VS always throws errors if I forget this..
But for the ThingDef:
-You've made your extended ThingDef-Class
-You've set the class in the XML
-You've converted the readout to your new class
So.. I don't really see a problem in your code right now...

Oh, here is something:
You've written:
internal public class ThingDef_FuelRod : ThingDef

I'm not sure internal works for a class that needs to be accessable by the Scribe...

mrofa

Well i got only one idea, and its the thingdef class, for additional options.
So in example in xml, with extra functins you need to change two things in the object.
Blue stuff is to link extra xml functions, and green stuff is for behavior function.
Red stuff are my extra functions.
If i dont put the blue stuff link then red stuff wont be read, and it wont generate error, atlast not the red type error.

<ThingDef Class="Extended_Bullet.NewThingDefs" ParentName="BaseBullet">
      <defName>BommerangOne</defName>
      <label>Pistol bullet</label>
      <thingClass>Extended_Bullet.Ex_Bullet</thingClass>
      <texturePath>Boomerang</texturePath>
      <projectile>
         <flyOverhead>false</flyOverhead>
      <damageDef>Bullet</damageDef>
         <DamageAmountBase>10</DamageAmountBase>
         <Speed>25</Speed>
      </projectile>
      <RotationSpeed>10</RotationSpeed>
      <ReturnToOwner>true</ReturnToOwner>
      <DmgEffOnImpact>true</DmgEffOnImpact>
      <ReturnThingdef>BommerangTwo</ReturnThingdef>
      <TryIgnite>true</TryIgnite>


All i do is clutter all around.

MonkeyWithAWrench

@Haplo:
It hasn't complained to me about the "ToString" thing, and when I set the values to something specific during testing it still displays it correctly. I can still add that though, I doubt it'll do any harm anyway.

On the internal/public thing, it was public until just before I copy/pasted the code. I made that small change when looking over the code mrofa was kind enough to link, just in case it made any difference. It didn't so I've changed it back since then.

@mrofa:
I do have the blue and green lines though, as:
<ThingDef class="Nuclear_Generator.ThingDef_FuelRod">
<ThingClass>Nuclear_Generator.FuelRod</ThingClass>

And the only variable I'm trying to add at the moment is:
<MaxEnergyLevel>1000</MaxEnergyLevel>

Though it is possible that maybe I'm missing the point of what your saying.

Thank you both for taking some more time to have a look at this problem for me. It is much appreciated.

mrofa

Ugh sorry didnt see you posted the code, nope your not missing the point :D
Anyways it might be just rimworlds odd behavior :D
Try to make 2 classes insted of putting everything to one






All i do is clutter all around.

MonkeyWithAWrench

A bunch of it's stuck together now that wasn't before, as a consequence of my shuffling it around repeatedly trying to solve this... issue. But yeah, I did intend to have it split up more.

If it really is just some odd behavior then I guess that means I'll just have to hard code the variables. sigh...

Haplo

I think your problem may be a rather dumb one:
Try it with Class="..." instead of class="..."

MonkeyWithAWrench

*Comes home after a looooong day.

*Checks forums and sees a suggestion.

*Fires up project and makes suggested alteration.

*Launches Rimworld and checks if fixed.

*SLAMS HEAD REPEATEDLY INTO TABLE.


really? REALLY!? The differing case of that one letter was the whole problem? What the hell language?! What the actual hell!!!???

StorymasterQ

C has always been finicky with casing. But, it's the way to go for a programmer.
I like how this game can result in quotes that would be quite unnerving when said in public, out of context. - Myself

The dubious quotes list is now public. See it here

Shinzy

Quote from: MonkeyWithAWrench on August 20, 2014, 11:48:19 PM
*Comes home after a looooong day.

*Checks forums and sees a suggestion.

*Fires up project and makes suggested alteration.

*Launches Rimworld and checks if fixed.

*SLAMS HEAD REPEATEDLY INTO TABLE.


really? REALLY!? The differing case of that one letter was the whole problem? What the hell language?! What the actual hell!!!???

haha, I've been following this thread (not because I understand anything of it) but out curiosity

my face is red and I got tears in me eyes just for seeing what the problem was =P
whew

Simple joys for simpletons! or how it goes ;D
I hope your table survived!

MonkeyWithAWrench

Quote from: StorymasterQ on August 21, 2014, 01:20:20 AM
C has always been finicky with casing. But, it's the way to go for a programmer.

In my defense, the problem was in the xml file. Using class in C usually requires lowercase, so I guess that carried over when I wrote the xml file.

@Shinzy
I'm glad you could get a good laugh out of that!  :)