C# modding help with Rimworld structure

Started by crusader2010, January 24, 2018, 12:37:54 PM

Previous topic - Next topic

crusader2010

Hello,

I just started looking into how to mod Rimworld (decompiled the assembly, set up the programming environment + GIT, etc), but I need some help with understanding the inner structure of the code.

For now, my goal is the following: getting all the available buildable recipes for weapons and apparel (only), getting the stats of each of these items, then making a menu and displaying them there.

1. What mod do you suggest I take a look at that adds a new menu and is not very complicated?

2. How do I get a list of all the weapon&apparel recipes that are available to build at a certain point in the game (i.e. when the player clicks on the menu)?

Regarding this, I found a list that contains all of the Defs from the game, in the DefDatabase class:
DefDatabase<ThingDef>.AllDefsListForReading

In other methods I saw an iteration over each element of this list, and for that each element there seems to exist a list of recipes:

for (int i = 0; i < thingDefs.Count; i++)
{
    foreach (RecipeDef x in thingDefs[i].recipes)
    {
      //do something
    }
}


Questions: 

  • Is this the most efficient way to get all of the recipes?
  • How can you tell if a recipe is for a weapon/armor and not something else? There is a "IsWeapon" (also "IsApparel") property but it is under ThingDef. Should I first filter the defs using this property and then get the recipes?
  • In the DefDatabase class there is also a method called "AddAllInMods()" - do I need to call this method before checking for recipes, or is it called/cached when the game starts (or similar) ? I want to get all the recipes, not just the vanilla ones.
  • What does the property "AvailableNow" actually mean for instances of RecipeDef? Whether or not the recipe is suspended in the production table? If it's available to be built according to the technologies researched? Something else?

3. How do I get from a recipe to the item itself (even if not actually built), then to the item's stats (e.g. short accuracy, damage, burst shot count, blunt protection, social chat impact, etc ?

4. Is it possible to limit the recipes found above only to those that can be built (i.e. there are production tables on the map)?

Sorry for all the questions... just trying to understand the base structure of the code (and not being very successful)  :-X

Thanks
My mod pack: {A13} Mod Mega Pack

BrokenValkyrie

#1
That is pretty ambitious for first code project. Have you thought about how material influence factor in? What about quality? I think coming up with a plan and design first is important.

I can only answer a and  b.

a. This is general advice, don't worry about efficiency first, this is a common developer trap. Focus on getting the mod working first before thinking about efficiency. If you're only calling for the list once for the menu, I doubt efficiency is a concern.

b. Every weapon is classified into thingCategories, WeaponsRanged and WeaponsMelee. All apparel have <thingClass>Apparel</thingClass> . If you can find existing core code that already get all apparel/weapon function there will be no need to filter it out.

crusader2010

#2
Thanks for the answer! I do have a plan for at least 60-70% of what I want to do, this is why I want to keep it to a bare minimum for now. I know starting efficiency is a common developer trap, but having a double FOR loop to search in two seemingly large lists is something that I don't really like from the start (and leads me to think that there might be a better way to do it) :D

Looking over the code again, it seems that IsWeapon and IsApparel are the right way to go (at least for now), as I don't really care whether the weapons are melee or ranged (I want to create something dynamic, as much as possible). Now I just need to figure out how to get to the recipes and the items themselves. Then, most likely, there will be a list of <something> that should contain all the stats... or a few such lists if there are stat categories involved.

Regarding the quality/material, I do not want to think about it for now (just to keep things simple enough). When I get a better understanding of the structure, it will probably be easy to modify the code accordingly.

I did find something of interest (but for later down the road) : the ApparelLayers and ApparelProperties classes that will provide some of the stats about an item that I want to show. Also, by looking at the way the trading window is created, I might be able to create a crude version of what I need (using rectangles and widgets it seems).

Well, gonna look further and see what I find. Any help is appreciated :)

PS: found some stats in the methods "DoTable_WeaponsRanged" and "DoTablesInternal_Apparel" and "DoTablesInternal_Melee". These seem to be the links to the XMLs.
My mod pack: {A13} Mod Mega Pack

crusader2010

Unfortunately I'm not having much luck with this. Can anyone help with some answers to the questions from the first post? :(
My mod pack: {A13} Mod Mega Pack

Fereal

Disclaimer: I'm not familiar with the game's crafting system outside of the basics so I might be wrong in some areas here. I'm only reading through the game's source.

Quote from: crusader2010 on January 24, 2018, 12:37:54 PM
  • In the DefDatabase class there is also a method called "AddAllInMods()" - do I need to call this method before checking for recipes, or is it called/cached when the game starts (or similar) ? I want to get all the recipes, not just the vanilla ones.
All Defs from all mods are loading on game start. This is one of the reasons why the game restarts whenever you change your mod list.

Quote from: crusader2010 on January 24, 2018, 12:37:54 PM
  • What does the property "AvailableNow" actually mean for instances of RecipeDef? Whether or not the recipe is suspended in the production table? If it's available to be built according to the technologies researched? Something else?
Prerequisites like research are satisfied and item is ready for crafting.

Quote from: crusader2010 on January 24, 2018, 12:37:54 PM
3. How do I get from a recipe to the item itself (even if not actually built), then to the item's stats (e.g. short accuracy, damage, burst shot count, blunt protection, social chat impact, etc ?

recipeDef.products[0].thingDef
Will retrieve the ThingDef of that recipe, assuming the recipe only has one product output. From there, you can retrieve whatever stats you want.

Quote from: crusader2010 on January 24, 2018, 12:37:54 PM
2. How do I get a list of all the weapon&apparel recipes that are available to build at a certain point in the game (i.e. when the player clicks on the menu)?

DefDatabase<RecipeDef>.AllDefs.Where(recipeDef => recipeDef.AvailableNow && recipeDef.products.Count() == 1 && (recipeDef.products[0].thingDef.IsWeapon || recipeDef.products[0].thingDef.IsApparel)
There may be an easier built-in function somewhere in the code. Again, only works on one-output recipes.

Quote from: crusader2010 on January 24, 2018, 12:37:54 PM
4. Is it possible to limit the recipes found above only to those that can be built (i.e. there are production tables on the map)?
Recipes are global and not map-based. Maybe patch in AvailableNow to suit whatever your criteria?

crusader2010

Thank you very much! The code for point 2. was exactly how I assumed, except for the one-product-output thing. Never realized there could be multiple outputs from crafting (though I cannot think of an in-game example right now).

I think it's enough to go on and take a closer look on what I want to do now. Later on I'll research how to get all available production tables (or types of production tables) on the map, provided there is an easy way to do it.

Thank you again! :)
My mod pack: {A13} Mod Mega Pack