Pawn generation dll?

Started by Em, May 24, 2016, 01:34:41 PM

Previous topic - Next topic

1000101

Look at Pawn.relations (Pawn_RelationsTracker) for social status with other pawns.

As to find a specific Pawn, You indeed want Find.MapPawns.  You will need a Linq query to get the pawn you want or iterate through all the pawns manually.

ie:
var bob = Find.MapPawns.AllPawns.Where( p => p.NameStringShort == "Bob" );
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

Fluffy (l2032)

Quote from: Em on June 01, 2016, 04:55:20 PM
I still haven't found the class that sets the relationships. I know there has to be a loop that checks:
If  (father of pawn 1 == father of pawn 2 && if mother of pawn 1 == mother of pawn 2){
setrelationship= siblings}

Something like that. No idea where it is =(
There's no list kept of relations (unless I'm missing something), they're all checked on the fly. If you look at the various PawnRelationWorker_xxx classes, you'll see exactly the kind of code you're describing. These workers are attached to PawnRelationDefs, and called whenever the code wants to figure out if pawn x and y are related.

Quote from: Em on June 01, 2016, 04:55:20 PM
Oh and another little thing:
Where do I find the getPawn command? If I want to get an existing pawn from the global pawn list? I found a list MapPawns, but it has no simple getPawn(Name x) or whatever. I don't get it. =(
There isn't. You generally get a pawn/targetinfo reference as input from whatever piece of code calls yours (usually a job/toil), or you are selecting down from the MapPawns list based on certain criteria. Finding pawns by name is highly unreliable, so there's no wonder there's no vanilla method for that. What are you trying to do? I have a sneaky suspicion this is one of those cases where you don't need an answer, you need to change the question ;).

Em

#17
I hope I'm not being annoying, but I need help again.
So, this is what I'd have to do if I wanted two Pawns to become siblings, right?
RimWorld.PawnRelationWorker_Sibling.CreateRelation(Find.MapPawns.AllPawns.Where( p => p.NameStringShort == "Bob" ), Find.MapPawns.AllPawns.Where( p => p.NameStringShort == "Bob2" ), ????);
Now, I have the problem that I don't know what PawnGenerationRequest is, and where I get one from. It's needed for CreateRelation:
public override void CreateRelation(Pawn generated, Pawn other, PawnGenerationRequest request)

What I want to do is create a relationship between two pawns at will. So, if I have two pawns ingame, I want to somehow be able to set their relationships. Prepare Carefully has no feature like that at the moment, so I'm  trying to implement a simple method for that. Though, I'm not even sure how I'd call that method ingame because there is no console. =(

I come from Java, so a few things still confuse me.

And what I want to do later on is implement new relationships, like Twins for example.

1000101

The best answer you will get is from within the game DLLs themselves.  Use the "Find Usages" and "Find References" functions of your decompiler (IlSpy, dotPeet, etc).

We can point you in the right direction but don't have the specific answers.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

Em

Quote from: 1000101 on June 02, 2016, 02:14:07 PM
The best answer you will get is from within the game DLLs themselves.  Use the "Find Usages" and "Find References" functions of your decompiler (IlSpy, dotPeet, etc).

We can point you in the right direction but don't have the specific answers.
Yes, I tried that.

b0rsuk

I don't speak C# at all.

Can someone inform me about
a) starting pawn skills ? I know some of it comes from Childhood, some from Adulthood, but part comes from base stats + age bonus. I want to understand the base skill levels and age.
b) chance that a given pawn is a kickstarter backer rather than a mix of Childhood + Adulthood ? It's from the file rimworld_creations.txt in resources.assets, but I don't know how program uses the .xml data.

I'm writing a script that calculates skill stats for various factions. I want to compare skill tendencies. I already know "Dumb Labor" is disabled on about 1/3 of all colonists but only on 10% of Tribals, that Tribals are really awful at Animals and Raiders are better builders than Civil pawns. Lots of quirks like that.

Em

Why is everyone raping my thread. =(

joaonunes

I am sorry, I created a new post so I would not disturb you with my own issues :(
Do you want your colonists to look manlier?
Get a free mustache sample here!

Em

Quote from: joaonunes on June 04, 2016, 06:43:23 PM
I am sorry, I created a new post so I would not disturb you with my own issues :(
I don't think anyone will help me anyways, so I guess it's okay...

joaonunes

Quote from: Em on June 05, 2016, 09:14:25 AM
Quote from: joaonunes on June 04, 2016, 06:43:23 PM
I am sorry, I created a new post so I would not disturb you with my own issues :(
I don't think anyone will help me anyways, so I guess it's okay...

Use ILSpy, open Assembly-CSharp and go to Verse.PawnGenerator.
Do you want your colonists to look manlier?
Get a free mustache sample here!

Em

Quote from: joaonunes on June 05, 2016, 11:52:21 AM
Quote from: Em on June 05, 2016, 09:14:25 AM
Quote from: joaonunes on June 04, 2016, 06:43:23 PM
I am sorry, I created a new post so I would not disturb you with my own issues :(
I don't think anyone will help me anyways, so I guess it's okay...

Use ILSpy, open Assembly-CSharp and go to Verse.PawnGenerator.
I already did that, otherwise I wouldn't have asked all those questions. =(

1000101

Quote from: Em on June 05, 2016, 09:14:25 AM
Quote from: joaonunes on June 04, 2016, 06:43:23 PM
I am sorry, I created a new post so I would not disturb you with my own issues :(
I don't think anyone will help me anyways, so I guess it's okay...

The first response in this thread, my first response told you exactly where you had to go and what to look at.

To recap:
1) The xml is in /Mods/Core/Defs/MapGeneratorDefs/MapGenerators.xml right at the bottom;
2) Open your decompiler and find the class Genstep_Colonists;
3) Write your own GenStep and update the xml to point to yours.

You did get help.  You not being able to figure out how to use the information is not the same thing at all.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

Em

#27
Quote from: 1000101 on June 05, 2016, 01:34:24 PM
Quote from: Em on June 05, 2016, 09:14:25 AM
Quote from: joaonunes on June 04, 2016, 06:43:23 PM
I am sorry, I created a new post so I would not disturb you with my own issues :(
I don't think anyone will help me anyways, so I guess it's okay...

The first response in this thread, my first response told you exactly where you had to go and what to look at.

To recap:
1) The xml is in /Mods/Core/Defs/MapGeneratorDefs/MapGenerators.xml right at the bottom;
2) Open your decompiler and find the class Genstep_Colonists;
3) Write your own GenStep and update the xml to point to yours.

You did get help.  You not being able to figure out how to use the information is not the same thing at all.
Okay, but what I don't get is, how does it find my new GenStep? What do I save it as? Do I create a new Assembly-CSharp.dll? But that would mean I'd have to replace all of the classes with the same code, which I don't have because of the decompiling errors. So it has to be a new dll, but how does the game know that it has to actually use that dll instead of Assembly-CSharp? I'm just confused as to how it works and what I need to do. The pure code I can write, but I don't know how everything refers to each other and how classes are actually used.

And I still don't know which class sets the bloodrelationships. There is a class that checks what parents pawns have and uses that information to set sibling, halfsibling etc. relationships. Where does that happen?

Oh god, I think it might happen in PawnRelationUtility, but it's not compiled:
public static class PawnRelationUtility
{
[DebuggerHidden]
public static IEnumerable<PawnRelationDef> GetRelations(this Pawn me, Pawn other)
{
PawnRelationUtility.<GetRelations>c__Iterator97 <GetRelations>c__Iterator = new PawnRelationUtility.<GetRelations>c__Iterator97();
<GetRelations>c__Iterator.me = me;
<GetRelations>c__Iterator.other = other;
<GetRelations>c__Iterator.<$>me = me;
<GetRelations>c__Iterator.<$>other = other;
PawnRelationUtility.<GetRelations>c__Iterator97 expr_23 = <GetRelations>c__Iterator;
expr_23.$PC = -2;
return expr_23;
}


I want to add the "Twin" relationship, though I'd have to know where it checks all the relationships and sets them in the game.

1000101

Quote from: EmOkay, but what I don't get is, how does it find my new GenStep?
Quote from: 10001013) ... update the xml to point to yours.


Quote from: EmWhat do I save it as? ... I'm just confused as to how it works and what I need to do.
Quote from: 10001013) Write your own GenStep ...
For specific details on how to do this (making your own DLL for a mod), follow the tutorials in this very sub-forum.  Specifically - [Tutorial] (Alpha 13) How to make a .dll-mod (Power Generation).  While that mod is making a power generator, the important part is that it's teaching you how to make a DLL to use with RimWorld.


Quote from: EmThe pure code I can write, but I don't know how everything refers to each other and how classes are actually used.
Most of the time the "entrance points" or "hooks" are in xml.  Anywhere you see a tag like "fooClass" or "barDriver", it's refering to a C# class.


Quote from: EmAnd I still don't know which class sets the bloodrelationships. There is a class that checks what parents pawns have and uses that information to set sibling, halfsibling etc. relationships. Where does that happen?
I also mentioned how the pawns relations are tracked in one of my responses.  (More on this below.)

Quote from: 1000101Look at Pawn.relations (Pawn_RelationsTracker) for social status with other pawns.


Quote from: EmOh god, I think it might happen in PawnRelationUtility, but it's not compiled:
public static class PawnRelationUtility
{
[DebuggerHidden]
public static IEnumerable<PawnRelationDef> GetRelations(this Pawn me, Pawn other)
{
PawnRelationUtility.<GetRelations>c__Iterator97 <GetRelations>c__Iterator = new PawnRelationUtility.<GetRelations>c__Iterator97();
<GetRelations>c__Iterator.me = me;
<GetRelations>c__Iterator.other = other;
<GetRelations>c__Iterator.<$>me = me;
<GetRelations>c__Iterator.<$>other = other;
PawnRelationUtility.<GetRelations>c__Iterator97 expr_23 = <GetRelations>c__Iterator;
expr_23.$PC = -2;
return expr_23;
}

Well, um...it is compiled?  That is the decompiled output.  Because the function returns an enumerable result, it's not going to decompile very well.  When you find something like this, you need to look at the class it's refering to.  In this case it's a compiler generated internal sealed class called "c__Iterator97".  What you want to look at in those classes is the "MoveNext" method.  It's not easy to decompile compiled code because the compiler will make optimizations which don't translate back into human-readable form.  This is one of those cases.

All that being said, in this case you really don't need to worry about what it's doing or that internal class, all you care about is that the method "GetRelations" exists for you to easily get the relationship defs between pawns.  So, just call the extension method on the pawn and iterate the results with another pawn.

foreach( var pawnRelationDef in pawn.GetRelations( otherPawn ) )
{
   if(
      ( pawnRelationDef == PawnRelationDefOf.Parent )&&
      ( otherPawn.gender == Gender.Male )
   )
   {
      Log.Message( string.Format( "{0} is {1}'s father", otherPawn.NameStringShort, pawn.NameStringShort ) );
   }
}


In addition to the aforementioned Pawn_RelationsTracker class which holds all the information about how pawns are interconnected (relate) to each other, there are many "helper" classes for specific relationships:

  • ChildRelationUtility
  • LoverRelationUtility
  • ParentRelationUtility
  • PawnRelationUtility - You already found this one
  • RelationsUtility
  • SpouseRelationUtility
Make sure you know how to use the tools you need.  All I did was type in "RelationUtility" into the class filter and dotPeek found all those classes for me.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

Em

Quote from: 1000101 on June 05, 2016, 06:22:45 PM
Quote from: EmOkay, but what I don't get is, how does it find my new GenStep?
Quote from: 10001013) ... update the xml to point to yours.


Quote from: EmWhat do I save it as? ... I'm just confused as to how it works and what I need to do.
Quote from: 10001013) Write your own GenStep ...
For specific details on how to do this (making your own DLL for a mod), follow the tutorials in this very sub-forum.  Specifically - [Tutorial] (Alpha 13) How to make a .dll-mod (Power Generation).  While that mod is making a power generator, the important part is that it's teaching you how to make a DLL to use with RimWorld.


Quote from: EmThe pure code I can write, but I don't know how everything refers to each other and how classes are actually used.
Most of the time the "entrance points" or "hooks" are in xml.  Anywhere you see a tag like "fooClass" or "barDriver", it's refering to a C# class.


Quote from: EmAnd I still don't know which class sets the bloodrelationships. There is a class that checks what parents pawns have and uses that information to set sibling, halfsibling etc. relationships. Where does that happen?
I also mentioned how the pawns relations are tracked in one of my responses.  (More on this below.)

Quote from: 1000101Look at Pawn.relations (Pawn_RelationsTracker) for social status with other pawns.


Quote from: EmOh god, I think it might happen in PawnRelationUtility, but it's not compiled:
public static class PawnRelationUtility
{
[DebuggerHidden]
public static IEnumerable<PawnRelationDef> GetRelations(this Pawn me, Pawn other)
{
PawnRelationUtility.<GetRelations>c__Iterator97 <GetRelations>c__Iterator = new PawnRelationUtility.<GetRelations>c__Iterator97();
<GetRelations>c__Iterator.me = me;
<GetRelations>c__Iterator.other = other;
<GetRelations>c__Iterator.<$>me = me;
<GetRelations>c__Iterator.<$>other = other;
PawnRelationUtility.<GetRelations>c__Iterator97 expr_23 = <GetRelations>c__Iterator;
expr_23.$PC = -2;
return expr_23;
}

Well, um...it is compiled?  That is the decompiled output.  Because the function returns an enumerable result, it's not going to decompile very well.  When you find something like this, you need to look at the class it's refering to.  In this case it's a compiler generated internal sealed class called "c__Iterator97".  What you want to look at in those classes is the "MoveNext" method.  It's not easy to decompile compiled code because the compiler will make optimizations which don't translate back into human-readable form.  This is one of those cases.

All that being said, in this case you really don't need to worry about what it's doing or that internal class, all you care about is that the method "GetRelations" exists for you to easily get the relationship defs between pawns.  So, just call the extension method on the pawn and iterate the results with another pawn.

foreach( var pawnRelationDef in pawn.GetRelations( otherPawn ) )
{
   if(
      ( pawnRelationDef == PawnRelationDefOf.Parent )&&
      ( otherPawn.gender == Gender.Male )
   )
   {
      Log.Message( string.Format( "{0} is {1}'s father", otherPawn.NameStringShort, pawn.NameStringShort ) );
   }
}


In addition to the aforementioned Pawn_RelationsTracker class which holds all the information about how pawns are interconnected (relate) to each other, there are many "helper" classes for specific relationships:

  • ChildRelationUtility
  • LoverRelationUtility
  • ParentRelationUtility
  • PawnRelationUtility - You already found this one
  • RelationsUtility
  • SpouseRelationUtility
Make sure you know how to use the tools you need.  All I did was type in "RelationUtility" into the class filter and dotPeek found all those classes for me.
Thank you.

But I've looked into Pawn_RelationsTracker, and the code I think I need is not decompiled properly:
public IEnumerable<Pawn> FamilyByBlood
{
get
{
Pawn_RelationsTracker.<>c__IteratorA5 <>c__IteratorA = new Pawn_RelationsTracker.<>c__IteratorA5();
<>c__IteratorA.<>f__this = this;
Pawn_RelationsTracker.<>c__IteratorA5 expr_0E = <>c__IteratorA;
expr_0E.$PC = -2;
return expr_0E;
}
}

And the helper classes don't seem to have anything related to Sibling relations. I'll do the tutorial, but I don't think it'll help me find the relationship classes I need.