[c#] How to determine if the building is used or not?

Started by Red192, September 19, 2019, 08:00:08 AM

Previous topic - Next topic

Red192

I'm new to modding and to c# and i find my self quite overwhelmed. I think it is a simple problem in reality but i wasn't able to figure it out and i'm quite ashamed from it, please be merciful, i'm new.

I tried a bit but i can't find how to define if the building is currently used for bill production or not. Can someone please help me?

EbonJaeger

If you mean if a pawn is currently working at it, you can use this:
building.Map.reservationManager.IsReservedByAnyoneOf(building, building.Faction)
Where `building` is an object of type Building.

Red192


EbonJaeger


Red192

To be totaly honest, it would better if there is a way to determine exactly when a building is used, and not just reserved. It kind of get lit all alone like is haunted or something.

but for the time being i will fine with it

LWM

You could always check the location of the pawn who has reserved it, and compare their Position to the position of the cell-you-use-to-access-the-building (whatever it's called)?  You wouldn't be 100% accurate, because they might be moving, or picking up items, putting down finished products, etc, but that might be closer.

LWM

If it's a building you can control in C#(*), you could always tie whatever it is you want to do if it's being used to the "UsedThisTick()" function.

(*) - i.e., a derived class from Building_Worktable, or, if you are feeling brave, a Harmony PostFix() for Building_WorkTable.cs's UsedThisTick().

LWM

Red192

If I recal it correctly (i'm on my phone rigjt now) usedThisTick () require that the building is flickable and mine isn't  :-\

LWM

As long as your building is a Building_Workbench, then UsedThisTick() works - it's called by way of the "DoRecipeWork" toil, and it doesn't test anything beyond "is this pawn doing a recipe here?" and "does UsedThisTick() exist?"

--LWM

Red192

public virtual void UsedThisTick()
{
if (this.refuelableComp != null)
{
this.refuelableComp.Notify_UsedThisTick();
}
}


it's work just with workbench with refuleable component i guess from here

LWM

If you can define the ThingClass for the workbench, you can make a derived class that does something like this:


public override void UsedThisTick()
{
  base.UsedThingTick();
  //put your stuff in here
}


If that's not an option for you, then adding a Harmony Postfix() should work:

[HarmonyPatch(typeof(Building_Workbench, "UsedThisTick")]
public class Patch_Workbench_UsedThisTick {
  public static void Postfix(Building_Workbench __instance) {
    //do your stuff


Assuming, of course, that having a hook every tick is actually useful to you.

Red192

#11
ok, now i see, UsedThisTick() is also a method from Building_workTable. I guess is called every time someone use it, even if i can't find when this happen.

QuoteIf you can define the ThingClass for the workbench, you can make a derived class that does something like this:

I should define a new class and the thingclass of the workbench, yes, i can do that, but i prefer to have something a bit more reusable.

Quotethen adding a Harmony Postfix() should work:

ok, now i found the wiki page about that, sound interesting, but, since i would add a flag every time someone use a building and that flag come from a mod, would that be a heavy hit for performance?

EDIT: I'm really new to programming, i'm not truly aware of what i'm doing

Red192

ok, today i returned on this part and i wasn't able to get something out of it: firstly i tried to create  a new thingclass, child of building_workshop, but the UsedThisTick was not called by doRecipeWork in that case.

After that I installed and tried the harmony ddl, but i need to add a public variable in Building_Workshop for being usable from the component. I cant even call a component attached to that building from the harmony patching.

now, i know is a bit embarrassing, but i need to ask about some programming basics on how to solve the problem, i'm quite new to this kind of stuff so I don't know how to make this thing work properly

LWM

Quote from: Red192 on September 24, 2019, 10:14:53 AM
ok, today i returned on this part and i wasn't able to get something out of it: firstly i tried to create  a new thingclass, child of building_workshop, but the UsedThisTick was not called by doRecipeWork in that case.

Is it possible to see your code?  I would have expected that to work!


Quote
After that I installed and tried the harmony ddl, but i need to add a public variable in Building_Workshop for being usable from the component. I cant even call a component attached to that building from the harmony patching.

There's probably a way to make it happen - again, having a close idea of what you're specifically trying to do would be helpful.  But I suspect you can reach it by one of the parameters passed to the Prefix or whatever?

--LWM

Red192

QuoteThere's probably a way to make it happen - again, having a close idea of what you're specifically trying to do would be helpful.  But I suspect you can reach it by one of the parameters passed to the Prefix or whatever?

Now i know that you need to add a reference to the original class into the preFix or PostFix parameters for work with it, i wasn't able to make it work for that probably. I did not touch that part since a while so o could return on that.

QuoteIs it possible to see your code?

yes, of course, i'm trying to say to a modified version of the component "fire overlay" to "fire overlay on use"

using System;
using UnityEngine;
using Verse;
using RimWorld;

namespace NoName
{
    // Token: 0x0200073A RID: 1850
    [StaticConstructorOnStartup]
    public class CompFireOverlayOnUse : ThingComp
    {

        // Token: 0x17000623 RID: 1571
        // (get) Token: 0x060028B9 RID: 10425 RVA: 0x00135B3C File Offset: 0x00133F3C
        public CompProperties_FireOverlayOnUse Props
        {
            get
            {
                return (CompProperties_FireOverlayOnUse)this.props;
            }
        }
        // Token: 0x060028BA RID: 10426 RVA: 0x00135B4C File Offset: 0x00133F4C !this.parent.Map.reservationManager.IsReservedByAnyoneOf(this.parent, this.parent.Faction
        public override void PostDraw()
        {
            base.PostDraw();
            if ((this.refuelableComp != null && !this.refuelableComp.HasFuel) || [color=red][b]!this.parent.Map.reservationManager.IsReservedByAnyoneOf(this.parent, this.parent.Faction)) [/b][/color]
            {
                return;
            }
            Vector3 drawPos = this.parent.DrawPos;
            drawPos.y += 0.046875f;
            CompFireOverlayOnUse.FireGraphic.Draw(drawPos, Rot4.North, this.parent, 0f);
            //itIsOn = false;
        }



        // Token: 0x060028BB RID: 10427 RVA: 0x00135BB5 File Offset: 0x00133FB5
        public override void PostSpawnSetup(bool respawningAfterLoad)
        {
            base.PostSpawnSetup(respawningAfterLoad);
        }

        // Token: 0x040016B5 RID: 5813
        protected CompRefuelable refuelableComp;

        // Token: 0x040016B6 RID: 5814
        public static readonly Graphic FireGraphic = GraphicDatabase.Get<Graphic_Flicker>("Things/Special/Fire", ShaderDatabase.TransparentPostLight, Vector2.one, Color.white);

    }
}



at the moment it just fire when reserved, as EbonJager suggested. Since it was a marginal part of the mod i simply put aside and move on, so i don't remember exactly what i tried and what not.

Right know i'm thinking to: Make a new building_worktable derived class, inside that i override UsedThisTick() to take the building, search if there is a FireOverlayOnUse component attached to it, if yes, change a public bool on it