SonicZentropy / PoE2Mods.pw

Patchwork Modding Framework for Pillars of Eternity 2
MIT License
22 stars 11 forks source link

Overriding static constructors #5

Open fireundubh opened 6 years ago

fireundubh commented 6 years ago

Any idea how to override static constructors (e.g., Game.Scripts.Scripts())?

SonicZentropy commented 6 years ago

Kinda behind on github notifications, sorry! We've been majorly refactoring. You can for sure override them, but it's slightly weird. In CECIL terms, static constructors are .cctor so you have to create a pair of methods for it. It'll look something like this:

[MemberAlias(".cctor", typeof(object))]
private void object_cctor() {
    //this is an alias for object::.cctor()
}

[ModifiesMember(".cctor")]
public void CCtorNew() {
    object_cctor(); //call the old static constructor if you want
    //do the new stuff here
}
fireundubh commented 6 years ago

Tried that. I get this error when compiling:

error CS1729: 'Scripts' does not contain a constructor that takes 0 arguments
SonicZentropy commented 6 years ago

It's a compiler annoyance because 'Scripts' doesn't have a NON-static parameterless constructor, which is what the compiler tries to call in the absence of a defined one.

You can read more about it here: https://stackoverflow.com/questions/7230544/c-sharp-error-parent-does-not-contain-a-constructor-that-takes-0-arguments

The way I work around it is by using [ModifiesType("Scripts")] attribute above your class declaration, then NOT directly inheriting from Scripts

fireundubh commented 6 years ago

NOT directly inheriting from Scripts

Does that mean I have to reimplement the entire Scripts class?

SonicZentropy commented 6 years ago

No, the [ModifiesType] Attribute will pull it into the right place anyway

fireundubh commented 6 years ago

I'm still have trouble with this.

Here's the mod: Change Strength Patch Mod.

Just some background: The mod is meant to be used in conjunction with a .gamedatabundle file to allow modifying disposition, reputation, and relationship change strengths independently.

The launcher is now throwing this exception:

2018-05-23 23:25:08.545 -07:00 [Information] Created patcher for assembly: Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
2018-05-23 23:25:08.584 -07:00 [Information] Implicitly creating type for: PoE2Mods.ChangeDispositionPatch/<>c__DisplayClass1_0.
2018-05-23 23:25:08.591 -07:00 [Information] Implicitly creating type for: PoE2Mods.CompanionAddRelationshipPatch/<>c__DisplayClass1_0.
2018-05-23 23:25:08.592 -07:00 [Information] Implicitly creating type for: PoE2Mods.ReputationAddPointsPatch/<>c__DisplayClass1_0.
2018-05-23 23:25:08.659 -07:00 [Information] =====Creating new fields=====
2018-05-23 23:25:08.920 -07:00 [Error] An error has occurred,
While trying to: Patch the game
Error type: A system error or some sort of bug. (ArgumentNullException)
Internal message: Value cannot be null.
Parameter name: key

System.ArgumentNullException: Value cannot be null.
Parameter name: key
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)
   at Patchwork.Engine.Utility.CustomAttributeHelper.GetAllCustomAttributes(ICustomAttributeProvider provider) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\Utility\Reflections and Cecil\CustomAttributeHelper.cs:line 37
   at Patchwork.Engine.Utility.CustomAttributeHelper.GetCustomAttributes[T](ICustomAttributeProvider provider) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\Utility\Reflections and Cecil\CustomAttributeHelper.cs:line 59
   at Patchwork.Engine.Utility.CustomAttributeHelper.GetCustomAttribute[T](ICustomAttributeProvider provider) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\Utility\Reflections and Cecil\CustomAttributeHelper.cs:line 69
   at Patchwork.Engine.AssemblyPatcher.TransferMethodBody(MethodDefinition targetMethod, MethodDefinition yourMethod) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\AssemblyPatcher\ModifyExisting.cs:line 296
   at Patchwork.Engine.AssemblyPatcher.ModifyMethod(TypeDefinition targetType, MethodDefinition yourMethod, MemberActionAttribute memberAction, MethodDefinition targetMethod) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\AssemblyPatcher\ModifyExisting.cs:line 200
   at Patchwork.Engine.AssemblyPatcher.UpdateMethods(SimpleTypeLookup`1 methodActions) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\AssemblyPatcher\AssemblyPatcher.cs:line 210
   at Patchwork.Engine.AssemblyPatcher.PatchManifest(PatchingManifest manifest, IProgressMonitor o) in E:\projects\PoE2Mods.pw-fireundubh\Patchwork.Engine\AssemblyPatcher\AssemblyPatcher.cs:line 419
   at PatchworkLauncher.LaunchManager.ApplyInstructions(IEnumerable`1 patchGroups, ProgressObject po) in E:\projects\PoE2Mods.pw-fireundubh\PatchworkLauncher\GUI\LaunchManager.cs:line 621
   at PatchworkLauncher.LaunchManager.<>c__DisplayClass46_1.<Command_Patch>b__0() in E:\projects\PoE2Mods.pw-fireundubh\PatchworkLauncher\GUI\LaunchManager.cs:line 314
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at PatchworkLauncher.LaunchManager.<Command_Patch>d__46.MoveNext() in E:\projects\PoE2Mods.pw-fireundubh\PatchworkLauncher\GUI\LaunchManager.cs:line 314