[Solved] What's the best way I can get the name of a pawn doing X job using C#?

Started by Knight, July 26, 2018, 08:28:54 PM

Previous topic - Next topic

Knight

EDIT: Solution at bottom!

I need to get the billDoer for a medical bill (read: Surgeon). How could I do this in the simplest way? I thought that a simple Harmony patch to return the current billDoer would work but no class or method explicitly defines or returns the pawn that is currently doing the job, they usually only take the billDoer as a parameter and that comes with its own issues as shown below. I think I need a method with the billDoer parameter that is called before work has begun on a job although I'm not sure what method does that. Maybe a different, lower-level function will achieve what I need?

This is what I've got so far and the code works but it doesn't do what I need it to do:

[HarmonyPatch(typeof(Bill_Medical))]
[HarmonyPatch("Notify_DoBillStarted")]
public class GetSurgeonPatch
{
    public static Pawn Surgeon;

    static void Postfix(ref Pawn billDoer)
    {
        Pawn Surgeon = billDoer;
        Log.Message("Surgeon: " + Surgeon);
    }
}


The reason the above doesn't work is because it returns the surgeon for the medical bill but only when the work has begun. For example, when the 'yellow progress bar' begins ticking up beneath the Pawn. This isn't what I want, I need the surgeon to be returned before the work has begun / when the job has been assigned to that particular pawn - both will work. Essentially I need this:

1) Medical Bill assigned to Patient
2) Surgeon assigned to Medical Bill
2.5) Surgeon name given to my mod
3) Work begins
4) Work complete

So, is there something I'm missing? Perhaps there's a PostFix or Prefix patch using Harmony that'd return the billDoer or maybe a new method I can write that'd provide that information to me? Any help would be appreciated.

Cheers.

Solution:

The Harmony patch works but, as I thought, I was using the wrong method to implement the patch in-game. A few minor edits and information allowed me to get what I wanted working. I began using a Prefix patch to tap into TryStartNewDoBillJob and then do some checks before the original method was allowed to run:

[HarmonyPatch(typeof(WorkGiver_DoBill))]
[HarmonyPatch("TryStartNewDoBillJob")]
public class GiverAndDoer
{
    static bool Prefix(ref Pawn pawn, ref Bill bill, ref IBillGiver giver)
    {
        if (bill.ToString().Contains("Bill_Administer_SerumOne")) // This checks if the bill is the medical bill I don't want being done by the patient
        {
            if (pawn.ToString() == giver.ToString()) // This checks if the patient is the same as the surgeon
            {
                Log.Message("Patient + Surgeon the same for Bill_Administer_SerumOne");
                return false; // This prevents the original method from running if the above statement is true. Essentially stopping the job from being assigned
            }
            return true;
        }
        return true; // The above statements were false so the original method can be run without issue now!
    }
}


If you only want the name of both the billDoer and billGiver then simply Prefix patch the same method but get the value of Pawn and Giver and then compare. Giver is billGiver and Pawn is billDoer.

Mehni

Surgery is done through JobDriver_DoBill, unfortunately one of the more complex and very generic ones.

Karthas077

What exactly are you hoping to do with the name of the billDoer? Do you need to be able to cancel the bill or otherwise control its execution? More information would make it easier to offer a potential solution.

Knight

Quote from: Karthas077 on July 28, 2018, 05:34:59 AM
What exactly are you hoping to do with the name of the billDoer? Do you need to be able to cancel the bill or otherwise control its execution? More information would make it easier to offer a potential solution.

I need to interrupt a job if the billDoer is the same as the billGiver (e.g the Surgeon is the same as the Patient). This should never happen in the vanilla game but a specific change in my mod has allowed it to happen - this change is necessary for its function. So, I essentially need to get the name of the person doing X job and check if that person's name is the same as the one they're operating on. If it is then cancel that job and do some other stuff. Hope that makes sense.

EDIT: I've managed to do it using a Harmony patch that edits TryStartNewDoBillJob. Was a lot more simple than I imagined. Cheers though!