[A8] Hello? Any source code about StockGenerators?

Started by e39a562r, December 19, 2014, 09:35:08 AM

Previous topic - Next topic

e39a562r

I'm try to make a StockGenerator_Girls

But i got lots of compiler-generated things when i decompile the Assembly-CSharp.dll

Quote
   public class StockGenerator_Slaves : StockGenerator
   {
      [DebuggerHidden]
      public override IEnumerable<Thing> GenerateThings()
      {
         StockGenerator_Slaves.<GenerateThings>c__Iterator93 <GenerateThings>c__Iterator = new StockGenerator_Slaves.<GenerateThings>c__Iterator93();
         <GenerateThings>c__Iterator.<>f__this = this;
         StockGenerator_Slaves.<GenerateThings>c__Iterator93 expr_0E = <GenerateThings>c__Iterator;
         expr_0E.$PC = -2;
         return expr_0E;
      }
      public override bool HandlesThingDef(ThingDef thingDef)
      {
         return thingDef.category == EntityCategory.Pawn && thingDef.race.humanoid;
      }
   }

I can't figure out where the pawns are generated

Could someone help me?

Rikiki

I believe this part of the source code is encrypted.
There are other ones in the assembly. Tynan must protect some core functions?...

Haplo

Nope the code isn't really encrypted. The problem is, that the decompiler just can't decompile specific types of code back to readable c# code. You'll find a whole bunch of such code snippets as Tynan uses such functionality rather often :)

StorymasterQ

For me, one thing jumps out from that code.

Quote
f__this

It's always a proper reaction for any code.
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

unifex

Quote from: StorymasterQ on December 22, 2014, 12:13:00 AM
For me, one thing jumps out from that code.

Quote
f__this

It's always a proper reaction for any code.

Especially when dealing with complex generics. Completely agree.

skullywag

I really need this code, its the clue to fixing my issue of programmatical traders. Something is failing in trymakestockfor which is called from the generatethings method but i cant see what im not passing correctly as I cant see this code...
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

Wastelander

Make sure you have "show compiler-generated code" option enabled if you're using DotPeek.

The part we're interested in is here:

QuoteStockGenerator_Slaves<GenerateThings>c__IteratorA7 thingsCIteratorA7_1 = new StockGenerator_Slaves.<GenerateThings>c__IteratorA7();

search for c__IteratorA7 and if you have the show compiler-generated code option on you'll find a sealed class private to this class named c__IteratorA7.

The operative part of that class that you're interested in is this, I think:

QuoteIEnumerable<Faction> allFactionsVisible = Find.FactionManager.AllFactionsVisible;
if (StockGenerator_Slaves.<GenerateThings>c__IteratorA7.<>f__am$cache7 == null)
{
   // ISSUE: method pointer
   StockGenerator_Slaves.<GenerateThings>c__IteratorA7.<>f__am$cache7 = new Func<Faction, bool>((object) null, __methodptr(<>m__195));
}
Func<Faction, bool> predicate = StockGenerator_Slaves.<GenerateThings>c__IteratorA7.<>f__am$cache7;
this.<slaveFaction>__2 = GenCollection.RandomElement<Faction>(Enumerable.Where<Faction>(allFactionsVisible, predicate));
this.<pawn>__3 = PawnGenerator.GeneratePawn(PawnKindDefOf.Slave, this.<slaveFaction>__2);
this.$current = (Thing) this.<pawn>__3;
this.$PC = 1;
return true;

with the method pointer m__195 evaluating to:

Quoteprivate static bool <>m__195(Faction fac)
      {
        if (fac != Faction.OfColony)
          return fac.def.humanoidFaction;
        return false;
      }

So that's:
1) Getting a list of all visible factions
2) Filtering out the ones that are ofColony or non-humanoid
3) Picking a random faction from that list
4) Generating a pawn of KindDef Slave and of that faction using this line: PawnGenerator.GeneratePawn(PawnKindDefOf.Slave,this.<slaveFaction>E__2);

And I think that's pretty much it, rinse and repeat for however many pawns you need to generate.

What are you trying to do with your stock generator?

skullywag

Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

BBream

#8
This is successfully functioned code. It generate slaves. If you want to make girl, define PawnKindDef for girl and put into PawnGenerator.


        public override IEnumerable<Thing> GenerateThings()
        {
            StringBuilder sb = new StringBuilder();
            List<Thing> things = new List<Thing>();
            //ThingDef thingDef = DefDatabase<ThingDef>.GetNamed("Human");

            for(int i = 0; i < RandomCountOf(PawnKindDefOf.Slave.race); i++)
            {
                Thing thing = PawnGenerator.GeneratePawn(PawnKindDefOf.Slave, Faction.OfColony);
                things.Add(thing);
                sb.AppendLine(thing.Label);
                Log.Message("thing:" + thing.ThingID);
            }

            Log.Message("StockGenerator_Animals:");
            Log.Message(sb.ToString());
            return things as IEnumerable<Thing>;
        }

Tynan

This is the original code for all the StockGenerators.

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


namespace RimWorld{

public class StockGenerator_SingleDef : StockGenerator
{
private ThingDef thingDef = null;

public override IEnumerable<Thing> GenerateThings()
{
Thing newThing = TryMakeForStock( thingDef, RandomCountOf( thingDef ) );
if( newThing != null )
yield return newThing;
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return thingDef == this.thingDef;
}
}


public class StockGenerator_Category : StockGenerator
{
private ThingCategoryDef categoryDef = null;
private IntRange thingDefCountRange = IntRange.one;


public override IEnumerable<Thing> GenerateThings()
{
List<ThingDef> generatedDefs = new List<ThingDef>();
int numThingDefsToUse = thingDefCountRange.RandomInRange;
for( int i=0; i<numThingDefsToUse; i++ )
{
ThingDef chosenThingDef;
if( !categoryDef.DescendantThingDefs
.Where( t=> t.tradeability == Tradeability.Stockable && !generatedDefs.Contains(t) )
.TryRandomElement(out chosenThingDef) )
{
//Trader is already carrying every possible thingdef in this set
continue;
}

Thing newThing = TryMakeForStock( chosenThingDef, RandomCountOf( chosenThingDef ) );
if( newThing != null )
{
generatedDefs.Add(newThing.def);
yield return newThing;
}
}
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return categoryDef.DescendantThingDefs.Contains(thingDef);
}
}


public class StockGenerator_Tag : StockGenerator
{
private string tradeTag = null;
private IntRange thingDefCountRange = IntRange.one;

public override IEnumerable<Thing> GenerateThings()
{
List<ThingDef> generatedDefs = new List<ThingDef>();
int numThingDefsToUse = thingDefCountRange.RandomInRange;
for( int i=0; i<numThingDefsToUse; i++ )
{
ThingDef chosenThingDef;
if( !DefDatabase<ThingDef>.AllDefs.Where( d=>d.tradeTags != null
&& d.tradeability == Tradeability.Stockable
&& d.tradeTags.Contains(tradeTag)
&& !generatedDefs.Contains(d) )
.TryRandomElement(out chosenThingDef) )
yield break;

Thing newThing = TryMakeForStock( chosenThingDef, RandomCountOf( chosenThingDef ) );
if( newThing != null )
{
generatedDefs.Add(newThing.def);
yield return newThing;
}
}
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return thingDef.tradeTags != null && thingDef.tradeTags.Contains(tradeTag);
}
}



public class StockGenerator_Slaves : StockGenerator
{
public override IEnumerable<Thing> GenerateThings()
{
int count = countRange.RandomInRange;
for(int i=0; i<count; i++)
{
Faction slaveFaction = Find.FactionManager.AllFactionsVisible
.Where( fac => fac != Faction.OfColony && fac.def.humanlikeFaction )
.RandomElement();

Pawn pawn = PawnGenerator.GeneratePawn( PawnKindDefOf.Slave, slaveFaction );
yield return pawn;
}
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return thingDef.category == EntityCategory.Pawn && thingDef.race.Humanlike;
}
}

public class StockGenerator_WeaponsRanged : StockGenerator
{
public override IEnumerable<Thing> GenerateThings()
{
int count = countRange.RandomInRange;
for(int i=0; i<count; i++)
{
ThingDef gunDef = DefDatabase<ThingDef>.AllDefs
.Where( t=>t.IsRangedWeapon && t.tradeability == Tradeability.Stockable )
.RandomElement();

var gun = (ThingWithComps)ThingMaker.MakeThing( gunDef );
yield return gun;
}
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return thingDef.IsRangedWeapon;
}
}


public class StockGenerator_Art : StockGenerator
{
public override IEnumerable<Thing> GenerateThings()
{
int count = countRange.RandomInRange;
for(int i=0; i<count; i++)
{
ThingDef artDef = DefDatabase<ThingDef>.AllDefs
.Where( t=> t.tradeability == Tradeability.Stockable && t.IsArtBuilding )
.RandomElement();

Thing art = ThingMaker.MakeThing( artDef, GenStuff.RandomStuffFor(artDef) );

yield return art;
}
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return thingDef.IsArtBuilding;
}
}


public class StockGenerator_Armor : StockGenerator
{
public override IEnumerable<Thing> GenerateThings()
{
int count = countRange.RandomInRange;
for(int i=0; i<count; i++)
{
ThingDef thingDef = DefDatabase<ThingDef>.AllDefs
.Where( td=> IsValidThing(td) )
.RandomElement();

Thing thing = ThingMaker.MakeThing( thingDef, GenStuff.RandomStuffFor( thingDef ) );
yield return thing;
}
}

private bool IsValidThing(ThingDef td )
{
return td.tradeability == Tradeability.Stockable
&& td.IsApparel
&& (td.GetStatValueAbstract( StatDefOf.ArmorRating_Blunt ) > 0.15f
|| td.GetStatValueAbstract( StatDefOf.ArmorRating_Sharp ) > 0.15f );
}

public override bool HandlesThingDef(ThingDef thingDef)
{
return IsValidThing(thingDef);
}
}
}
Tynan Sylvester - @TynanSylvester - Tynan's Blog

BBream

Example is good and good example is great!
Thanks Tynan! It has a lot of things to learn.