How to make Apparel color ignore the material it's made of?

Started by battlemage64, April 19, 2020, 08:58:06 PM

Previous topic - Next topic

battlemage64

I want to make a piece of apparel have fully random colors without being tinted based on what it's made out of. Currently my def has this code:
    <colorGenerator Class="ColorGenerator_Options">
      <options>
        <li>
          <weight>1</weight>
          <min>(0.5,0.5,0.5,1)</min>
          <max>(1.0,1.0,1.0,1)</max>
        </li>
      </options>
    </colorGenerator>


I thought this would make the color random and not material-tinted because it doesn't use ColorGenerator_Apparel, but this is not the case. The color of the apparel is still primarily based on the material, which looks okay but not very colorful because most of the materials are drab leather. Is there a way (XML or C#/Harmony) I can make the apparel color ignore its material?
I love to mod and boy am I bad at it

LWM

Can you use the color generator to just give it a flat cobalt blue color?

If so, then your options may need work, or worst case scenario, you need a new color generator?

If not, you may need to patch <allowColorGenerators>true</...> into resource base or something.

battlemage64

I can't make it a particular color. I'm now working on making either a ColorGenerator or a CompColorable subclass. Will update if anything works.
I love to mod and boy am I bad at it

battlemage64

I made a custom ColorGenerator that always outputs the same color. The game still assigned the default Stuff color to each. Trying an edited version of CompColorable now.
I love to mod and boy am I bad at it

battlemage64

Update again: I used Harmony to patch Thing.DrawColor (get) to return a random color if the Thing is my item's def. This works well except it's called every tick so the texture is flashing rainbow in GUIs and randomized every time a pawn moves it. As cool as that is, it's not what I want, but it should mean I just have to store the color as a variable and only generate it once, which should be fairly easy. I'm not going to mark this as solved since I haven't really found a good general solution, though.
I love to mod and boy am I bad at it

battlemage64

Final update: it works now and I'm not sure why. Basically the patch's code sets the ThingWithComps.DrawColor to a random color, then sets __result equal to the DrawColor. For whatever reason (I'm honestly not sure why) this only sets the color once and then maintains it indefinitely. Anyway, here's my patch code in case anyone else ever needs it:

namespace Umbrellas {
[HarmonyPatch(typeof(Thing), "DrawColor",MethodType.Getter)]
class CompColorableRegardlessOfStuff {
        private static Color RandomColor() {
            return new Color(Random.Range(0f,1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1f);
        }
static void Postfix (Thing __instance, ref Color __result) {
            if (__instance.def.Equals(UmbrellaDefOf.Parasol)) {
                __instance.DrawColor = RandomColor();
                __result = __instance.DrawColor;
            }
        }
}
}

(oh yeah btw the mod adds umbrellas in case you couldn't tell)
I love to mod and boy am I bad at it

LWM

If it's ONLY your things, you might consider making a custom Thing that overrides DrawColor?

Then you could store the preferred color once and be done with harmony patches entirely?


battlemage64

That would probably be a better way of doing it, but I expect making a new version of ThingWithComps that's otherwise supposed to function exactly the same would cause some problems. I might try it if my current method stops working, though.
I love to mod and boy am I bad at it

LWM

I mean, that's the point of derived classes and object oriented programing, right?  So it should behave exactly like a ThingWithComps because it IS a ThingWithComps?

battlemage64

probably? I don't know enough about programming to be sure and my current solution already works so I just left it
I love to mod and boy am I bad at it

LWM

If you'd like to see how it'd be done:


public class MyFantasticModItemType : ThingWithComps // it's a subclass of ThingsWithComps
{
  public MyFantatsicModItemType() { // your constructor
    color=new random color; // you know how to do this better than I do
  }
  public override Color DrawColor(whatever was here) { // instead of doing usual ThingWithComp's DrawColor
    return color; // just return mine!
  }
  private Color color; // a variable for the object to store the fixed color in.
}

battlemage64

Hmmm, that does look like a simpler way of doing it. I'll try it out. Thank you!
I love to mod and boy am I bad at it