Removing ForcedMissRadius via xml Patch results in error on startup

Started by Currently_Fortifying, March 28, 2020, 10:54:29 PM

Previous topic - Next topic

Currently_Fortifying

If forcedMissRadius is removed via xml patch, I.E.
<Operation Class="PatchOperationRemove">
   <xpath>Defs/ThingDef[defName="Gun_DoomsdayRocket"]/verbs/li/forcedMissRadius</xpath>
</Operation>
The user will get an error on startup. The error is:

Config error in Gun_TripleRocket: verb 0: has incorrect forcedMiss settings; explosive projectiles and only explosive projectiles should have forced miss enabled
Verse.Log:Error(String, Boolean)
Verse.DefDatabase`1:ErrorCheckAllDefs()
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.GenGeneric:InvokeStaticMethodOnGenericType(Type, Type, String)
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.<>c:<Start>b__6_1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.<>c:<UpdateCurrentAsynchronousEvent>b__27_0()
System.Threading.ThreadHelper:ThreadStart_Context(Object)
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.ExecutionContext:Run(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.ExecutionContext:Run(ExecutionContext, ContextCallback, Object)
System.Threading.ThreadHelper:ThreadStart()


Anyone know how to fix this? It doesn't prevent the game from being ran, and as far as I can tell FMR is removed after test firing weapons that use it.

Homez

Verse.VerbProperties.ConfigErrors is the source of that error. As the name suggests, the method is responsible in part for validating Verb properties, e.g. forcedMissRadius.

The code responsible is:
if (LaunchesProjectile && defaultProjectile != null && forcedMissRadius > 0f != CausesExplosion)
{
yield return "has incorrect forcedMiss settings; explosive projectiles and only explosive projectiles should have forced miss enabled";
}


and specifically this clause:
forcedMissRadius > 0f != CausesExplosion

So, unfortunately, if CausesExplosion is true, forcedMissRadius must be greater than zero or this method will yield an error message. That said, it's not clear to me exactly what the practical repercussions of this yielded error are. There may be none. It may simply be informational. That would line up with your observation that FMR appears to have been removed successfully.

I haven't used Harmony yet, but you may be able to patch Verse.VerbProperties.ConfigErrors to filter out that error, or something. Can't help with the details there.

Currently_Fortifying

Thank you, I'll see about making a prefix patch and just preventing the original function from running, because transpilers scare me.
I was worried for a moment as a c++ developer when I read through and noticed forcedMissRadius didn't have a default value. Then I realized this is c#.

I'll also make a bug report given the fix is as easy as changing this.forcedMissRadius > 0f != this.CausesExplosion to
this.forcedMissRadius >= 0f != this.CausesExplosion. Since it's only a problem when the miss radius is negative
Thanks again for rooting around in the source for me.

Homez

No problem.  :)

Yeah, the message implies he wants to keep non-explosives from having an FMR; looks like forcing explosives to have one is just a side effect that only reveals itself when modding (which, for a game that officially supports modding, I think would be a bug).

That said, I think the clause would need to be changed from
forcedMissRadius > 0f != CausesExplosion
to
!CausesExplosion && forcedMissRadius > 0f

If it's changed to
forcedMissRadius >= 0f != CausesExplosion
then the error will throw for any non-explosive gun, as they all have FMR of 0. So 'forcedMissRadius >= 0f' would be true, 'CausesExplosion' would be false, and the resulting 'true != false' would be true, resulting in the error. I think. Could be wrong.