Finding vanilla allow sowing gizmo

Started by Jamestec, November 26, 2016, 11:54:27 PM

Previous topic - Next topic

Jamestec

When I detour Zone_Growing.GetGizmos(), the allow sowing button disappears. Even when I use the exact code from decompiled source, the button is not there: vanilla code (using Zhentar's ILSpy):

[DebuggerHidden]
public override IEnumerable<Gizmo> GetGizmos()
{
IEnumerator<Gizmo> enumerator = base.GetGizmos().GetEnumerator();
while (enumerator.MoveNext())
{
Gizmo current = enumerator.Current;
yield return current;
}
yield return PlantToGrowSettableUtility.SetPlantToGrowCommand(this);
yield break;
}


I investigated whether Zone_Growing.GetGizmos() should return the allow sowing button and it does;
I commented out the Zone_Growing.GetGizmos() detour and detoured Zone_Growing.SetPlantDefToGrow() with this:

        public void SetPlantDefToGrow(ThingDef plantDef)
        {
            plantDefToGrow = plantDef;


            MethodInfo method = GetType().GetMethod("GetGizmos", BindingFlags.Instance | BindingFlags.Public);
            if (method != null)
            {
                foreach (Gizmo g in (IEnumerable<Gizmo>)method.Invoke(this, null))
                {
                    if (g == null)
                    {
                        Log.Message("Test: gizmo was null");
                        continue;
                    }
                    if (g.ToString() != null)
                    {
                        Log.Message("ToString: " + g.ToString());
                    }
                    if (g.GetType() != null)
                    {
                        Log.Message("GetType: " + g.GetType());
                    }
                }

            }
            else
            {
                Log.Message("Test: can't get method");
            }
            Log.Message("Test: Only SetPlantToGrowCommand");
            Command_SetPlantToGrow but = PlantToGrowSettableUtility.SetPlantToGrowCommand(this);
            if (but.ToString() != null)
            {
                Log.Message("ToString: " + but.ToString());
            }
            if (but.GetType() != null)
            {
                Log.Message("GetType: " + but.GetType());
            }
        }

Which gave this:

ToString: Command(label=Rename, defaultDesc=Rename this zone.)
GetType: Verse.Command_Action
ToString: Command(label=Hide, defaultDesc=Hide/unhide this zone.)
GetType: Verse.Command_Toggle
ToString: Command(label=Delete, defaultDesc=Delete this zone.)
GetType: Verse.Command_Action
ToString: Command(label=Plant: rice plant, defaultDesc=Determine which plant should be sown here.)
GetType: Verse.Command_SetPlantToGrow
ToString: Command(label=Allow sowing, defaultDesc=When disabled, colonists will never sow plants in this zone. They will still harvest.)
GetType: Verse.Command_Toggle
Test: Only SetPlantToGrowCommand
ToString: Command(label=Plant: rice plant, defaultDesc=Determine which plant should be sown here.)
GetType: Verse.Command_SetPlantToGrow


Searching RimWorld's language translations for "allow sowing" gives:

  <CommandAllowSow>Allow sowing</CommandAllowSow>
  <CommandAllowSowDesc>When disabled, colonists will never sow plants in this zone. They will still harvest.</CommandAllowSowDesc>

But searching for CommandAllowSow or allow sowing in Core/Defs or decompiled Assembly-CSharp.dll gives nothing.
Interestingly when you analyse Zone_Growing.allowSow with ILSpy and expand Read By or Assigned By, it does list RimWorld.Zone_Growing.GetGizmos(), but when you look at RimWorld.Zone_Growing.GetGizmos(), it doesn't use Zone_Growing.allowSow as far as I can tell.

I tried JetBrains dotPeek, which gave this:

    [DebuggerHidden]
    public override IEnumerable<Gizmo> GetGizmos()
    {
      // ISSUE: object of a compiler-generated type is created
      // ISSUE: variable of a compiler-generated type
      Zone_Growing.\u003CGetGizmos\u003Ec__IteratorAC gizmosCIteratorAc = new Zone_Growing.\u003CGetGizmos\u003Ec__IteratorAC()
      {
        \u003C\u003Ef__this = this
      };
      // ISSUE: reference to a compiler-generated field
      gizmosCIteratorAc.\u0024PC = -2;
      return (IEnumerable<Gizmo>) gizmosCIteratorAc;
    }

Telerik JustDecompile, which gave this XD:

        [DebuggerHidden]
        public override IEnumerable<Gizmo> GetGizmos()
        {
            Zone_Growing.<GetGizmos>c__IteratorAC variable = null;
            return variable;
        }

ILSpy Version 2.4

[DebuggerHidden]
public override IEnumerable<Gizmo> GetGizmos()
{
Zone_Growing.<GetGizmos>c__IteratorAC <GetGizmos>c__IteratorAC = new Zone_Growing.<GetGizmos>c__IteratorAC();
<GetGizmos>c__IteratorAC.<>f__this = this;
Zone_Growing.<GetGizmos>c__IteratorAC expr_0E = <GetGizmos>c__IteratorAC;
expr_0E.$PC = -2;
return expr_0E;
}



Is the decompiler just missing the code for the button or is the button magicked in somewhere else?

1000101

You can select a member (field/property/method) or class and analyze it's usage.  That will tell you every place that references it.

That being said, the latest build of Zhentars' IlSpy gives me this for the decompile of RimWorld.Zone_Grow.GetGizmos():

public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo g in base.GetGizmos())
{
yield return g;
}
yield return PlantToGrowSettableUtility.SetPlantToGrowCommand(this);
yield return new Command_Toggle
{
defaultLabel = "CommandAllowSow".Translate(),
defaultDesc = "CommandAllowSowDesc".Translate(),
hotKey = KeyBindingDefOf.CommandItemForbid,
icon = TexCommand.Forbidden,
isActive = (() => this.<>f__this.allowSow),
toggleAction = delegate
{
this.<>f__this.allowSow = !this.<>f__this.allowSow;
}
};
}


So the allowSow toggle is being created in the GetGizmos method directly.
(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