Pawn Gizmos due to Apparel ThingComps are not checked?

Started by randolphcherrypepper, July 29, 2017, 11:44:36 PM

Previous topic - Next topic

randolphcherrypepper

I am running v0.17.1557 and I'm trying to add a Gizmo to some Apparel via ThingComp.

I defined the following debug in my code which never gets called:

        public override IEnumerable<Gizmo> CompGetGizmosExtra()
        {
            Log.Message("Fetching Gizmos");
            ...
        }


I've read the Pawn.GetGizmos() code which my decompiler provides thusly:

public override IEnumerable<Gizmo> GetGizmos()
{
if (this.IsColonistPlayerControlled)
{
foreach (Gizmo c in base.GetGizmos())
{
yield return c;
}
if (this.drafter != null)
{
foreach (Gizmo c2 in this.drafter.GetGizmos())
{
yield return c2;
}
}
if (this.equipment != null)
{
foreach (Gizmo g in this.equipment.GetGizmos())
{
yield return g;
}
}
if (this.apparel != null)
{
foreach (Gizmo g2 in this.apparel.GetGizmos())
{
yield return g2;
}
}
if (this.playerSettings != null)
{
foreach (Gizmo g3 in this.playerSettings.GetGizmos())
{
yield return g3;
}
}
foreach (Gizmo g4 in this.mindState.GetGizmos())
{
yield return g4;
}
}
}


After reading through Pawn_EquipmentTracker.GetGizmos(), I understand how weapons and other equipment add gizmos. That all makes sense! Super! But I want to do that with apparel.

So how does Pawn_ApparelTracker.GetGizmos() work? According to my decompiler:


public IEnumerable<Gizmo> GetGizmos()
{
for (int i = 0; i < this.wornApparel.Count; i++)
{
foreach (Gizmo g in this.wornApparel[i].GetWornGizmos())
{
yield return g;
}
}
}


Easy enough. Clearly Apparel.GetWornGizmos() is what apparel will use to determine gizmos created by apparel Comps/Verbs. Except it doesn't do anything:


public virtual IEnumerable<Gizmo> GetWornGizmos()
{
}


Unless my decompiler messed that up, there does not appear to be any way in vanilla Rimworld to add gizmos through apparel, although there seem to be an awful lot of hooks to support it.

Did I miss anything?

Thanks to all those hooks, a quick postfix patch from Harmony should be easy to make. I'm trying to avoid dependencies on HugsLib or Harmony for now.

Jamestec

#1
You're suppose to override it with another class of your own for that apparel.

Look at the Rimworld.ShieldBelt class and maybe it's XML. Edit: yea, you need a <thingClass> tag to point it to the right class.

How I easily get an example to learn from, without knowing SheildBelt displays gizmos in-game:
In ILSpy, go to Pawn_ApparelTracker.GetGizmos() like you have, right click the thing you're interested in (in this case, where does this.wornApparel[//i].GetWornGizmos() get it's gizmos from? So right click GetWornGizmos()), click Analyze and expand Overriden By in the Analyzer box that appears at the bottom.
There you can see that ShieldBelt overrides GetWornGizmos, so just copy that behaviour and create a class for your apparel and override GetWornGizmos.

Edit: another thing that you may or may not know that helped me is that the modifier, virtual, allows the method to be overridden, so by design, what you want to look at isn't the virtual method.

randolphcherrypepper

Thanks for that.

Basically your edit covers my point: you need a <thingClass> whereas I was trying to keep it to ThingComps.

Of course subclassing Apparel is an option, but it isn't friendly to XML modders whereas there seems to be a hook ready to go and unimplemented right inside Apparel!