Blue numbers in FoodTypeFlags

Started by CrazyMalk, February 01, 2018, 12:13:39 PM

Previous topic - Next topic

CrazyMalk

Hello! I'm a big newbie when the subject is programming, and while exploring the game with ILSpy, i decided to try learning how DendrovoreAnimal works, and it led me to FoodTypeFlags. But i cannot understand what the numbers in front of each type of food means (Eg.: Tree = 128, or  DendrovoreAnimal = 2705,)

This can be something really basic, but as I said, I am a big newbie to this subject ._. Can anyone help me?

jamaicancastle

Flags are stored as the bits of a single integer. So imagine you have eight different kinds of food, and you refer to them as 00000001, 00000010, 00000100, etc. Then you can have a diet of say food types 1 and 3 that you refer to as 00000101. To check whether a particular food falls into the diet, it simply has to compare the bit(s) in question, which is much much faster than tag strings or another equivalent system. When ILSpy encounters the flags, it interprets them as a number, converting the binary representation into an int.

In this case DendrovoreAnimal is 2705, which is composed of 2048, 512, 128, 16, and 1. 128 as you've noticed is Tree; the others are different types of food that are considered part of that diet.

CrazyMalk

#2
Wow... Smart. But, is it possible to add another kind of food? Because, if you do, wouldn't it mess up the calculations?

Edit: With "another kind of food", I mean things that are not commonly used as food, like stone chunks or ores, for example.

jamaicancastle

It wouldn't mess it up, provided the new food type is its own bit (or, equivalently, its value is a unique power of 2). The highest value right now is 2048, so the next one would be 4096 and so on. None of the existing diets would be affected because the highest a diet can possibly be now, if it includes every type of food, is 4095.

With that said, I don't know how easy it would be to actually modify or patch the FoodTypeFlags class to add new values. But in terms of the underlying flag logic, it's simple enough.

CrazyMalk

Oh, now i get it! I did not think that way. Well, there's no way of knowing if it works without trying, so here i go! Thanks for the explanation!

CrazyMalk

Ok, so... The names used (Tree; Meal; Processed; Seed; Meat; Etc.) are from the Core Defs, or are they "generated" in the codes?

jamaicancastle

They are defined in the FoodTypeFlags class (in code), and then referred to by the defs. When the XML parser reads in each def, it takes the name of the food type and checks it against the list of FoodTypeFlags (and presumably complains if it doesn't find it, I'd have to check though).

CrazyMalk

I created a class in my project, and added:
using System;
using RimWorld;
using Verse;

namespace KingkillerCreatures
{
    [Flags]
    public enum FoodTypeFlags
    {
        StoneChunks = 4096,
        DendrovoreAnimalGastroliths = 6801
    }
}


Then, I created a copy of the vanilla Various_Stone.xml and deleted everything, except for the "ChunkBase". There, i added to the file:

<ingestible>
      <foodType>StoneChunks</foodType>
</ingestible>

I tested the game, and the debug log said that "DendrovoreAnimalGastroliths" was not valid for "FoodType", and listed the vanilla 'tags' (DendrovoreAnimal, etc). So, i tried looking into the code with ILSpy again. Under FoodTypeFlags, i saw each tag divided into separated classes.

I copied one of them, so that i could paste it into one of my own classes on my own project, but Visual Studio wont accept classes without the normal structure of a C# project. What can i do?

Ps.: Sorry for the giant image, i don't know how to resize it :/

jamaicancastle

What you're seeing in ILSpy is the different attributes of FoodTypeFlags. You can pull them out into separate views in ILSpy, which is useful in the case of bigger fields like methods, but they're still part of the same class. (Actually I think it's a struct. Data structures are not my strong suit.)

The reason why it's not finding the new flags is because of the namespace. RimWorld.FoodTypeFlags and KingkillerCreatures.FoodTypeFlags are different. However I don't know how you would go about detouring this specific piece of code.