[Solved]Changing *each* weapon's equippedStatOffsets within comp

Started by Latta, April 30, 2015, 09:33:07 PM

Previous topic - Next topic

Latta

I'm trying to dynamically add stat offsets to weapons via additional comp.
Example: One gladius gives you movement bonus while another melee hit chance.
I can just edit parent's def but it will affect all same weapons at once so no.

Instead I'm trying a lot of workaround using StatPart, but it's really messy and I don't want to use something like Dictionary<Enum,Dictionary<StatDef,float>> in my utility class.

Anyone any thoughts, please?

BBream

I think you should use Initialize method in ThingComp.
Initialize() method called in PostMake() method. This PostMake()  method setup def value. So, you can make your mod by following this step.
1) In xml, add statOffset and this ThingComp.
2) In ThingComp.Initialize(), setup what you want stat.

public override void Initialize(Verse.CompProperties props)
{
   List<StatModifier> statModifiers = this.def.equippedStatOffsets;
   StatModifier selected = statModifiers.RandomElement();
   this.def.equippedStatOffsets = new List<StatModifier>();
   this.def.equippedStatOffsets.Add(selected);
}

Note: I use def.equippedStatOffsets temporary but I think you should make custom ThingDef. It cause to side-effect. And this code is not tested and it is pseudo-code. Use carefully.

Latta

Hm, editing this.def or parent.def is not a viable option for me as it will affect all weapons, game-wide.
I need it work like a CompQuality. Problem is that what my comp is trying to edit is not weapon's stat. MoveSpeed is not weapon's stat but pawn's isn't it? Thus I'm trying to add equippedStatOffsets.

BBream

Then, I think it need to find way to fully copy.
Initialize()
   ThingDef def = new ThingDef();
   def = parent.def;                      //I want to fully copy not shallow copy
   parent.def = def;                      //It will copy new object
   parent.def.statOffset = ...;        //Setup stat in fully copied thingDef

It will not work but important point is you should find way to fully copy. I'll also find.
Edit1:
You should make new method for copying thingDef one by one. This is other code for fully copying

In Class ThingDefGenerator_Buildings:

    private static ThingDef BaseBlueprintDef()
    {
      ThingDef thingDef = new ThingDef();
      thingDef.category = EntityCategory.Ethereal;
      thingDef.label = "Unspecified blueprint";
      thingDef.altitudeLayer = AltitudeLayer.Blueprint;
      thingDef.useHitPoints = false;
      thingDef.selectable = true;
      thingDef.seeThroughFog = true;
      return thingDef;
    }
    private static ThingDef NewBlueprintDef_Thing(ThingDef def)
    {
      ThingDef thingDef = ThingDefGenerator_Buildings.BaseBlueprintDef();
      thingDef.defName = def.defName + ThingDefGenerator_Buildings.BlueprintDefNameSuffix;
      thingDef.label = def.label + Translator.Translate("BlueprintLabelExtra");
      thingDef.size = def.size;
      thingDef.graphicOverdraw = def.graphicOverdraw;
      thingDef.linkFlags = def.linkFlags;
      thingDef.linkDrawerType = def.linkDrawerType;
      if (!GenText.NullOrEmpty(def.blueprintGraphicPath))
      {
        thingDef.graphic = GraphicDatabase.Get<Graphic_Single>(def.blueprintGraphicPath, ShaderDatabase.MetaOverlay, def.DrawSize, Color.white);
      }
      else
      {
        thingDef.graphicPath = def.graphicPath;
        thingDef.graphicClass = def.graphicClass;
        thingDef.shader = ShaderDatabase.Transparent;
        thingDef.defaultColor = ThingDefGenerator_Buildings.BlueprintColor;
        thingDef.defaultColorTwo = Color.white;
      }
      thingDef.thingClass = !def.Minifiable ? def.blueprintClass : typeof (Blueprint_Install);
      thingDef.drawerType = def.thingClass != typeof (Building_Door) ? DrawerType.MapMeshOnly : DrawerType.RealtimeOnly;
      thingDef.entityDefToBuild = (EntityDef) def;
      def.blueprintDef = thingDef;
      return thingDef;
    }


Edit2:
It need to check modified ThingDef is saved.

In class Thing:

    public virtual void ExposeData()
    {
        Scribe_Defs.LookDef<ThingDef>(ref this.def, "def");


I think it need to save in PostExpose() method by using Scribe_Deep.LookDeep or at least modified statModifier.

Latta


Latta

Finished. You can view my result in Release sub forum.
But I didn't use ThingDef copying, just used a enum and switches(a lot) instead...

BBream

Good. You achieved what you want. It is more smart way than what I suggested. Congraturation! Golden label looks good. Later, I can expect melee weapon with magical effect.