Research for recipes?

Started by henryheyhey123, September 01, 2014, 08:16:30 AM

Previous topic - Next topic

henryheyhey123

Is it possible to add research prerequisites for recipes? If so, where do I put it in my code?

Thanks in advance!  :)

Rikiki

Hey, got the same question! ;)

But no way for now, you have to put limitations via .DLL.

Shinzy

You could still have the recipes require certain level of crafting skill, to have that similar progression curve thingie or whatever

Rikiki

Yep but the problem is that you don't want a workbench being able to craft Item Mark III when you just researched Item Mark I.

Did not yet tested it but I would try this piece of code for a custom workbench class:


class MyCustomWorkbench : Building_WorkTable
{
   private bool itemMarkIIIRecipeIsAdded = false;

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

      if ((itemMarkIIIRecipeIsAdded == false) && (Find.ResearchManager.IsFinished(ResearchProjectDef.Named("ItemMarkIIIResearchName")) == true))
      {
         Thing abstractWorkbenchContainingAllMyRecipes = ThingMaker.MakeThing(ThingDef.Named("AbstractWorkbenchContainingAllMyRecipes"));
         RecipeDef recipeToAddDef = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "ItemMarkIIIRecipe");

         def.recipes.Add(recipeToAddDef);
         itemMarkIIIRecipeIsAdded = true;
      }
   }
}


You must define 2 workbenches in XML. One that contains all your custom recipes but is not buildable (remove the <DesignationCategory> line) and the other is your custom workbench which has only Item Mark I recipe and contains a <researchPrerequisite>ItemMarkIResearchName</researchPrerequisite>.

henryheyhey123

#4
Thank you for the help, but I've been getting does not exist in current context errors from this code:


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


using UnityEngine;
using RimWorld;
using Verse;
using VerseBase;

namespace ResourceDuplication
{
    public class ResourceDuplexer : Building_WorkTable
    {
        private bool itemMarkIIIRecipeIsAdded = false;

        private bool itemMarkIIRecipeIsAdded = false;

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

            if ((itemMarkIIRecipeIsAdded == false) && (Find.ResearchManager.IsFinished(ResearchProjectDef.Named("Unlock_RDUse1")) == true))
            {
                Thing abstractWorkbenchContainingAllMyRecipes = ThingMaker.MakeThing(ThingDef.Named("ResourceDuplexerDummy"));
                RecipeDef recipeToAddDefMkII1 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleWoodStack");
                RecipeDef recipeToAddDefMkII2 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleMedicine");
                RecipeDef recipeToAddDefMkII3 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleStoneBlocks");
                RecipeDef recipeToAddDefMkIIFour = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleRawAgave");

                def.recipes.Add(recipeToAddDefMKII2);
                def.recipes.Add(recipeToAddDefMKII4);
                def.recipes.Add(recipeToAddDefMKII3);
                def.recipes.Add(recipeToAddDefMKII1);
                itemMarkIIRecipeIsAdded = true;
            }
            if ((itemMarkIIIRecipeIsAdded == false) && (Find.ResearchManager.IsFinished(ResearchProjectDef.Named("Unlock_RDUse2")) == true))
            {
                Thing abstractWorkbenchContainingAllMyRecipes = ThingMaker.MakeThing(ThingDef.Named("ResourceDuplexerDummy"));
                RecipeDef recipeToAddDefMkIII1 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleAICore");
                RecipeDef recipeToAddDefMkIII2 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleLavishMeal");
                RecipeDef recipeToAddDefMkIII3 = abstractWorkbenchContainingAllMyRecipes.def.recipes.Find(myRecipe => myRecipe.defName == "DoubleUranium");

                def.recipes.Add(recipeToAddDefMKIII1);
                def.recipes.Add(recipeToAddDefMKIII2);
                def.recipes.Add(recipeToAddDefMKIII3);
                itemMarkIIIRecipeIsAdded = true;
            }

        }
    }

}

Rikiki

I tested it and it works.
I will give you the complete code example tomorrow, I need to sleep now... :P

I think there might be a bug in your XML if you cannot wait for the answer ;)

mrofa

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
using Verse.AI;
using Verse.Sound;
using RimWorld;
using System.Reflection;
using VerseBase;
using RimWorld.SquadAI;

namespace Clutter
{



    internal class ThinkerTable : Building_WorkTable
    {
        public bool Spoonge = false;

        public static void FindAndAdd()
        {
            ThingDef ThinkerTable = DefDatabase<ThingDef>.GetNamed("ClutterTechTable", true);
            ThinkerTable.recipes.Add(DefDatabase<RecipeDef>.GetNamed("MakeSpoongeGun", true));
            typeof(ThingDef).GetField("allRecipesCached", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ThinkerTable, null);

        }
        public override void SpawnSetup()
        {
            base.SpawnSetup();
            if(Find.ResearchManager.IsFinished(ResearchProjectDef.Named("AFS")) == true)
            {
                Spoonge = true;
            }

        }

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

            if (!Spoonge && (Find.ResearchManager.IsFinished(ResearchProjectDef.Named("AFS")) == true))
            {
                ThinkerTable.FindAndAdd();
                ThingDef Table = DefDatabase<ThingDef>.GetNamed("ClutterTechTable", true);

                if (Table.recipes.Contains(DefDatabase<RecipeDef>.GetNamed("MakeSpoongeGun", true)))
                {
                    Spoonge = true;

                }

            }
        }
    }
}

This is the working code, its mostly copy/place from rikikis source code, Spawnsetup is require so that recipes wont multiply in 
choose recipe option.

But rikiki i got a question, what  this line do ?
typeof(ThingDef).GetField("allRecipesCached", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ThinkerTable, null);
All i figure out is that it require this wierd thing "System.Reflection"
All i do is clutter all around.

Rikiki

From what I understood, System.Reflection is similar to the getContainerOf Linux macro.

So it basically gets the allRecipesCached member from your Building_Worktable object and set it to null.
=> typeof(ThingDef).GetField("allRecipesCached", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ThinkerTable, null);

If you look into the core code, setting allRecipesCached to null will force the worktable to refresh its recipes list. And the job is done! :D

The original code is from RawCode. I don't really know how System.Reflection works :P.

mrofa

Nahh its cool i doung i would understand what it do anyhow :D
Thanks alot :)
All i do is clutter all around.

StorymasterQ

System.Reflection is used for a check that, if it's null, then it your computer is a vampire.

...joking, but it's a good troll answer.
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