Need help adding social fight variation

Started by kaeh, February 08, 2018, 03:20:45 AM

Previous topic - Next topic

kaeh

Hello,

I'm trying to do what author of https://ludeon.com/forums/index.php?topic=38966.0 asked but i'm confronted to a major problem.
I'm using Harmony and prefix patching StartSocialFighting(Pawn otherPawn) from PawnInteraction_XXXX (i'm at work and don't remember the exact class name, i'll update the post at 12:30PM Paris time, when i'll be at home).

Here is what i would like to do :
Before startSocialFight, check if another type of fight can happens (alcohol & both not teetotalers / both "violentable" etc etc), then applying a random number that will determine which event will really happens. If it's the basic social fight, then Prefix return true immediatly, if not, i'll call another class depending on which social fight happens and return false.

Problem is, i have the "otherPawn", it's nice, but i also need the social fight initiator pawn. I know it's in the base class BUT it's a private member... And that's where i'm blocked.
Is there a trick to access it ? Or maybe is there a way to override the base class and use a custom one instead ?

Another solution would be to patch another method containing both pawns, like in the JobGiver_SocialFighting but it's called EACH ticks, so perf would go mad. (PS: it does'nt contains both pawns but the pawn variable has access to ((Mental_State)otherPawn.mentalState).otherPawn).

I could also keep "otherPawn" variable in __state and postfix patch the StartSocialFighting method, that way i may have access to ((Mental_State)otherPawn.mentalState).otherPawn that would contains the initiator but i think it's kinda not clean as that would mean the base social fight's already started and that's not what i want.


This is my "second" mod attempt, my first was Markers mod and was abandonned.
I know how to code as this is my job so do not hesitate using "complicated" words / explanations.

Thanks in advance !
Kaeh

Fereal

#1
You can get (or set) any private field using Reflection.

Something along the lines of
typeof(ClassName).GetField("pawnStringName", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(classInstance)
as Pawn

kaeh

Hmmm i'll try this when i'll be at home. I didn't know that we can do that, if that works, you'll have enlighted my day <3.

kaeh

Sorry for double post but... It worked ! Thanks a lot buddy, i've learned something today <3