Ludeon Forums

RimWorld => Mods => Help => Topic started by: m1st4x on March 05, 2021, 05:09:07 PM

Title: Remove trait by patch
Post by: m1st4x on March 05, 2021, 05:09:07 PM
I want to get rid of a trait added by another mod, so I've applied a xml PatchOperationRemove to remove its definition.
This works, but now I'm getting errors by classes which use that definition:
"Failed to find RimWorld.TraitDef named <traitToRemove>. There are <num> defs of this type loaded."
Do I have to patch each class/method which is involved? What's best practice here?

-m1st4x
Title: Re: Remove trait by patch
Post by: LWM on April 23, 2021, 11:07:07 PM
...search through all the XML for everything that explicitly references this trait?

That's the most likely source of this error.
Title: Re: Remove trait by patch
Post by: Alenerel on April 24, 2021, 08:11:27 AM
I dont know how to mod, but what I do with some mods is just go to their files and change/remove what i dont like. In this case it would be to remove that trait. Just be careful when the mod gets updated again, since you would have to do this again
Title: Re: Remove trait by patch
Post by: RawCode on April 24, 2021, 02:17:06 PM
alternative method rely on code injection that will prevent blacklisted stuff selection (that can be anything) from database without actually removing anything from database.

this won't need updates as long as defname is same, but require some effort for initial setup.

Title: Re: Remove trait by patch
Post by: m1st4x on April 24, 2021, 04:03:31 PM
Hi guys, thanks for your thoughts.

There's no other xml-reference to the defname I removed.

So guess I've to 'blacklist' the corresponding code...
Is it worth the effort?
Can I do this with Harmony?
Examples?
Title: Re: Remove trait by patch
Post by: LWM on April 25, 2021, 12:05:53 AM
Hmm.  What's the XML you are using to remove it, what's the trait, and what's the full stack trace from the "Failed to find" error you got?

If you don't see any other references to its defName in any XML files, then something unusual is happening to the def.
Title: Re: Remove trait by patch
Post by: m1st4x on April 25, 2021, 06:03:32 AM
I want to remove VTE_Neat and VTE_Slob from VanillaTraitsExpanded.

patch operation:
Code: [Select]
  <Operation Class="PatchOperationRemove">
    <xpath>/Defs/TraitDef[defName="VTE_Neat"]</xpath>
  </Operation>

stack trace:
Code: [Select]
Failed to find RimWorld.TraitDef named VTE_Neat. There are 96 defs of this type loaded.
Verse.Log:Error(String, Boolean)
Verse.DefDatabase`1:GetNamed(String, Boolean)
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, Object[])
Verse.GenDefDatabase:GetDef(Type, String, Boolean)
RimWorld.DefOfHelper:BindDefsFor(Type)
RimWorld.DefOfHelper:RebindAllDefOfs(Boolean)
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()
Title: Re: Remove trait by patch
Post by: Canute on April 25, 2021, 06:47:50 AM
The Defname is ok.
I don't think you made the mistake and your mod is before VanillaTraitsExpanded ? :-)
I have no clue about the syntax, but does the xpath maybe need a / between TraitDef and [defName ?
Title: Re: Remove trait by patch
Post by: RawCode on April 25, 2021, 10:38:16 AM
this can be done with any code injection, just patch method that assign traits to pawn or pawn generation itself, most "effective" will be rerolling pawn completely if he happened to get blacklisted trait or any other blacklisted features.

*not effective, pawn generation is costly operation, but it's very simple to just reroll pawn instead of fixing it's attributes one by one.

Title: Re: Remove trait by patch
Post by: m1st4x on April 25, 2021, 01:31:17 PM
Code: [Select]
[DefOf]
public static class VTEDefOf
{
public static TraitDef VTE_Neat;
public static TraitDef VTE_Slob;
...
}

these objects are used by VTE for harmony patching in order to implement the behavior of the trait.

My mod gets loaded afterwards and removes the xml-definition of VTE_Neat and VTE_Slob.

It feels clear to me that I cannot remove XML when there is still code which refers to it.

That means I'd have to 're-patch' all VTE methods which use the deleted definitions.

-To avoid these traits being assigned to new generated pawns is a much better solution

Thanks RawCode


Title: Re: Remove trait by patch
Post by: LWM on April 25, 2021, 10:46:41 PM
Oh, good, you figured out what was going on :)
Title: Re: Remove trait by patch
Post by: m1st4x on April 26, 2021, 12:30:42 AM
Yes, and it's always the same :D
[email protected] for helping!
Title: Re: Remove trait by patch
Post by: Kopp on April 26, 2021, 09:47:10 PM
VTE has a option in the mod settings to disable traits.
Just in case you do not know and this would fix your problem.
Title: Re: Remove trait by patch
Post by: m1st4x on April 27, 2021, 08:37:28 AM
Yes indeed I didn't know and it fixes the problem, thanks :)