Hey, I want to detour this function that is on Bill_Medical.cs :
public override void Notify_IterationCompleted(Pawn billDoer, List<Thing> ingredients)
{
base.Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = this.GiverPawn;
if (this.recipe.Worker.GetPartsToApplyOn(giverPawn, this.recipe).Contains(this.Part))
{
this.recipe.Worker.ApplyOnPawn(giverPawn, this.Part, billDoer, ingredients);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
this.billStack.Delete(this);
}
I based myself on the CCL detour and detour injector source and saw all that is injected is written as internal static, so Im lost on how to deal with the "this" and how can I use this values on my version as they come from other parts of the file.
Its my first detour, spent more hours than I think its necessary on this, I need some help.
Maybe seeing a mod doing it might help:
https://github.com/Skullywag/ReclaimFabric/blob/master/Source/ReclaimFabric/_Thing.cs
all the source is there, hope it helps.
You simply need to write your method as a method extension for the original class. This means using "this ClasName foo". The other method is to use class inheritance which means you don't need to worry about "this" and you can access protected members.
I could easily have written CCLs detours to use class inheritance when possible but for consistency sake for when I could not I wrote them all as static extension methods. I don't think any of the detours need access to protected members and they need reflection anyway to access private members.
The help here made me move some more steps, but now Im too newbie to see what else is wrong, it should be something really simple Im sure of it, the CCL is already after core, and the core library dll at my references, my incredibly simple objective is to add a hediff at the end of a medical operation, just for testing im using foodpoisoning right after the applyonpawn, my files:
this is Bill_Medical.cs (in my project not the default one)
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Verse;
using Verse.AI;
namespace SC
{
public class _Bill_Medical : Bill
{
private BodyPartRecord part;
private int partIndex = -1;
public BodyPartRecord Part
{
get
{
if (this.part == null && this.partIndex >= 0)
{
this.part = this.GiverPawn.RaceProps.body.GetPartAtIndex(this.partIndex);
}
return this.part;
}
set
{
if (this.billStack == null)
{
Log.Error("Can only set Bill_Medical.Part after the bill has been added to a pawn's bill stack.");
return;
}
if (value != null)
{
this.partIndex = this.GiverPawn.RaceProps.body.GetIndexOfPart(value);
}
else
{
this.partIndex = -1;
}
this.part = value;
}
}
private Pawn GiverPawn
{
get
{
Pawn pawn = this.billStack.billGiver as Pawn;
Corpse corpse = this.billStack.billGiver as Corpse;
if (corpse != null)
{
pawn = corpse.innerPawn;
}
if (pawn == null)
{
throw new InvalidOperationException("Medical bill on non-pawn.");
}
return pawn;
}
}
public override bool ShouldDoNow()
{
return !this.suspended;
}
public override void Notify_IterationCompleted(Pawn billDoer, List<Thing> ingredients)
{
base.Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = this.GiverPawn;
if (this.recipe.Worker.GetPartsToApplyOn(giverPawn, this.recipe).Contains(this.Part))
{
this.recipe.Worker.ApplyOnPawn(giverPawn, this.Part, billDoer, ingredients);
giverPawn.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, giverPawn, null), null, null);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
this.billStack.Delete(this);
}
}
}
and the injector
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using RimWorld;
using Verse;
using Verse.AI;
using CommunityCoreLibrary;
namespace SC
{
public class DetourInjector : SpecialInjector
{
public override bool Inject()
{
MethodInfo RimWorld_Bill_Medic_IterationCompleted = typeof(Bill_Medical).GetMethod("Notify_IterationCompleted", BindingFlags.Instance | BindingFlags.Public);
MethodInfo MyCustomIterationCompleted = typeof(_Bill_Medical).GetMethod("Notify_IterationCompleted", BindingFlags.Instance | BindingFlags.Public);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_IterationCompleted, MyCustomIterationCompleted))
return false;
MethodInfo RimWorld_Bill_Medic_bodypart = typeof(Bill_Medical).GetMethod("BodyPartRecord", BindingFlags.Instance | BindingFlags.Public);
MethodInfo MyCustombodypart = typeof(_Bill_Medical).GetMethod("BodyPartRecord", BindingFlags.Instance | BindingFlags.Public);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_bodypart, MyCustombodypart))
return false;
MethodInfo RimWorld_Bill_Medic_giverpawn = typeof(Bill_Medical).GetMethod("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo MyCustomgiverpawn = typeof(_Bill_Medical).GetMethod("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_giverpawn, MyCustomgiverpawn))
return false;
return true;
}
}
}
It should be that kind of thing that someone experienced will see in seconds and I would take days, its almost there :)
It would help if you say what happens when you try to load and use this in RimWorld. :)
Hey Marvin :), nothing happens, no errors compiling or when opening rimworld, no errors when it is running, And when I do the medic operation it fixes the part like it should but no hediff like I want to, what makes me guess that the injection of my custom part is not actually replacing.
You cannot add fields or properties which would implicitly add new fields. Not without using a proper override and actually instantiating the new class. You can only add new methods.
Trying to access new fields in a detour when the object is not actually of that type will cause memory corruption as no memory as been allocated for those fields.
Ok, so where my limited knowlodge of a few days learning C# allow me to understand is that the bodypartrecord and giverpawn can not be detoured the way Im doing it without instantiating a new class. But in this case what is the most practical way of getting this mess and putting it to work properly? remove this properties? or doing a proper override?
- If it is doing a proper override and instantiating a new class how I do that?
- And if I need to remove the properties how can I make the Notify_IterationCompleted work without it?
Is this any closer?
internal static class _Bill_Medical
{
internal static BodyPartRecord part;
internal static int partIndex = -1;
internal static BillStack billStack;
internal static RecipeDef recipe;
internal static Bill b;
internal static BodyPartRecord Part
{
get
{
if (part == null && partIndex >= 0)
{
part = GiverPawn.RaceProps.body.GetPartAtIndex(partIndex);
}
return part;
}
set
{
if (billStack == null)
{
Log.Error("Can only set Bill_Medical.Part after the bill has been added to a pawn's bill stack.");
return;
}
if (value != null)
{
partIndex = GiverPawn.RaceProps.body.GetIndexOfPart(value);
}
else
{
partIndex = -1;
}
part = value;
}
}
internal static Pawn GiverPawn
{
get
{
Pawn pawn = billStack.billGiver as Pawn;
Corpse corpse = billStack.billGiver as Corpse;
if (corpse != null)
{
pawn = corpse.innerPawn;
}
if (pawn == null)
{
throw new InvalidOperationException("Medical bill on non-pawn.");
}
return pawn;
}
}
internal static void Notify_IterationCompleted(Pawn billDoer, List<Thing> ingredients)
{
Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = GiverPawn;
if (recipe.Worker.GetPartsToApplyOn(giverPawn, recipe).Contains(Part))
{
recipe.Worker.ApplyOnPawn(giverPawn, Part, billDoer, ingredients);
giverPawn.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, giverPawn, null), null, null);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
billStack.Delete(b);
}
}
and injector:
public class DetourInjector : SpecialInjector
{
public override bool Inject()
{
MethodInfo RimWorld_Bill_Medic_IterationCompleted = typeof(Bill_Medical).GetMethod("Notify_IterationCompleted", BindingFlags.Instance | BindingFlags.Public);
MethodInfo MyCustomIterationCompleted = typeof(_Bill_Medical).GetMethod("Notify_IterationCompleted", BindingFlags.Static | BindingFlags.NonPublic);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_IterationCompleted, MyCustomIterationCompleted))
return false;
MethodInfo RimWorld_Bill_Medic_bodypart = typeof(Bill_Medical).GetMethod("BodyPartRecord", BindingFlags.Instance | BindingFlags.Public);
MethodInfo MyCustombodypart = typeof(_Bill_Medical).GetMethod("BodyPartRecord", BindingFlags.Static | BindingFlags.NonPublic);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_bodypart, MyCustombodypart))
return false;
MethodInfo RimWorld_Bill_Medic_giverpawn = typeof(Bill_Medical).GetMethod("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo MyCustomgiverpawn = typeof(_Bill_Medical).GetMethod("GiverPawn", BindingFlags.Static | BindingFlags.NonPublic);
if (!Detours.TryDetourFromTo(RimWorld_Bill_Medic_giverpawn, MyCustomgiverpawn))
return false;
return true;
}
}
InternalGetHashCode() //must use internal one to get gmalloc handle.
+
hashmap()
+
[StructLayout(LayoutKind.Explicit,Size=64)]
public unsafe struct FieldExtension
{
[FieldOffset(dont) ] public int FieldA;
[FieldOffset(overlap) ] public int FieldB;
[FieldOffset(offsets)] public int FieldC;
}
using extension method its possible to write
YourOriginalObject.ExField(offset)
to get your AUX fields without memory corruption
I just gave some shots trying to cut down this fields and replace with Bill_Medical.GiverPawn inside the methods for example and all I get is that Bill_Medical does not have a definition, and the original GiverPawn is private so I don't have the smallest idea of how to do that (learning C# for 5 days) I need some level 1 easy clues (lol). edit: just noticed you said original object and not class, but I don't have idea how to do it either.
In some of CCLs detours you may notice regions which are called "Reflected Methods" (or something along those lines) which are used to get private fields and methods.
Ok, thanks to this tips, I made some progress and now I reached this:
internal static class _Bill_Medical
{
internal static FieldInfo _Part;
internal static FieldInfo _GiverPawn;
internal static MethodInfo _Delete;
internal static MethodInfo _GetPartsToApplyOn;
internal static MethodInfo _recipe;
internal static BodyPartRecord Part()
{
if( _Part == null )
{
_Part = typeof(BodyPartRecord).GetField("Part", BindingFlags.Instance | BindingFlags.Public);
}
return (BodyPartRecord)_Part.GetValue( null );
}
internal static Pawn GiverPawn()
{
if (_Part == null)
{
_Part = typeof(Pawn).GetField("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
}
return (Pawn)_GiverPawn.GetValue(null);
}
internal static BillStack Delete(Bill bill)
{
if (_Delete == null)
{
_Delete = typeof(BillStack).GetMethod("Delete", BindingFlags.Instance | BindingFlags.Public);
}
return (BillStack)_Delete.Invoke(null, new object[] { bill});
}
internal static RecipeWorker GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
{
if (_GetPartsToApplyOn == null)
{
_GetPartsToApplyOn = typeof(RecipeWorker).GetMethod("GetPartsToApplyOn", BindingFlags.Instance | BindingFlags.Public);
}
return (RecipeWorker)_GetPartsToApplyOn.Invoke(null, new object[] { pawn, recipe });
}
internal static Bill recipe()
{
if (_recipe == null)
{
_recipe = typeof(Bill).GetMethod("recipe", BindingFlags.Instance | BindingFlags.Public);
}
return (Bill)_recipe.Invoke(null, new object[] {});
}
internal static void Notify_IterationCompleted(Pawn billDoer, List<Thing> ingredients)
{
Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = GiverPawn();
if (_GetPartsToApplyOn(giverPawn, recipe).Contains(Part()))
{
recipe.Worker.ApplyOnPawn(giverPawn, Part(), billDoer, ingredients);
giverPawn.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, giverPawn, null), null, null);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
//Delete(); <- cannot figure how to do with this, used to be billstack.Delete(this) i made a method definition for it, still cannot
//figure how to get this Bill im in without calling "this"
}
}
2 problems on this:
1- I don't know how to deal with the if containing the _GetPartsToApplyOn as it always says "Non-invocable member _Bill_Medical._GetPartsToApplyOn cannot be used as a method. (But I made all the reflection with it as method info, why?)
2- the delete part i market with a comment. I did it with a methodinfo and it worked but I don't know how to bring back the original functionality of it that was "this.billStack.Delete(this);" if i call _Delete() it don't give errors just fine but how Im going to reference itself inside the _Delete if i cannot use "this"? will i have to create something for Bill as a reflection?
Because (a) you need a "this" and (b) you didn't specify "this".
internal static foo MyDetour( this Bar _this, the method paramters )
Only if the original member is static do you use not "this" and use "null" in it's place. If it's an instance member you need "this" as above.
I added what you said on my detour and a couple of .obj . where needed
internal static void Notify_IterationCompleted(this Bill_Medical obj,Pawn billDoer, List<Thing> ingredients)
{
obj.Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = GiverPawn();
if (GetPartsToApplyOn(giverPawn, obj.recipe).Contains(Part()))
{
obj.recipe.Worker.ApplyOnPawn(giverPawn, Part(), billDoer, ingredients);
giverPawn.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, giverPawn, null), null, null);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
Delete(obj);
}
I have no errors on my file anymore but it still does nothing ingame, Im almost sure it is because of the nulls on the invokes as none of the reflected methods and fields are static, still Im struggling to replace this nulls with anything, that is, if i need to replace them with anything:
example
internal static Pawn GiverPawn()
{
if (_GiverPawn == null)
{
_GiverPawn = typeof(Pawn).GetField("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
}
return (Pawn)_GiverPawn.GetValue(null);//<------------- this
}
tried to do something similiar:
internal static Pawn GiverPawn(this Pawn obj)
{
if (_GiverPawn == null)
{
_GiverPawn = typeof(Pawn).GetField("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
}
return (Pawn)_GiverPawn.GetValue(obj);
}
When doing this I get an error on the other calls that "there is no argument given that corresponds to the required formal parameter obj"
Almost there guys, sorry for disturbing so much and thanks for the help so far ;)
Where are you getting the error? It doesn't help if we don't know what method it's happening in. :P
You may need a rubber duck. Also, try some caveman debugging.
No errors, I can compile it and run it. But when testing ingame the thing I added to the detoured method don't happen what means that the it was not detoured, what I guess means i corrupted memory with something there, probably the nulls that I pointed on my last post that i can't replace full file:
using RimWorld;
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Verse;
using Verse.AI;
namespace SC
{
internal static class _Bill_Medical
{
internal static FieldInfo _Part;
internal static FieldInfo _GiverPawn;
internal static MethodInfo _Delete;
internal static MethodInfo _GetPartsToApplyOn;
internal static MethodInfo _recipe;
internal static BodyPartRecord Part()
{
if( _Part == null )
{
_Part = typeof(BodyPartRecord).GetField("Part", BindingFlags.Instance | BindingFlags.Public);
}
return (BodyPartRecord)_Part.GetValue( null );
}
internal static Pawn GiverPawn()
{
if (_GiverPawn == null)
{
_GiverPawn = typeof(Pawn).GetField("GiverPawn", BindingFlags.Instance | BindingFlags.NonPublic);
}
return (Pawn)_GiverPawn.GetValue(null);
}
internal static BillStack Delete(Bill bill)
{
if (_Delete == null)
{
_Delete = typeof(BillStack).GetMethod("Delete", BindingFlags.Instance | BindingFlags.Public);
}
return (BillStack)_Delete.Invoke(null, new object[] { bill});
}
internal static IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
{
if (_GetPartsToApplyOn == null)
{
_GetPartsToApplyOn = typeof(IEnumerable<BodyPartRecord>).GetMethod("GetPartsToApplyOn", BindingFlags.Instance | BindingFlags.Public);
}
return (IEnumerable<BodyPartRecord>)_GetPartsToApplyOn.Invoke(null, new object[] { pawn, recipe });
}
internal static void Notify_IterationCompleted(this Bill_Medical obj,Pawn billDoer, List<Thing> ingredients)
{
obj.Notify_IterationCompleted(billDoer, ingredients);
Pawn giverPawn = GiverPawn();
if (GetPartsToApplyOn(giverPawn, obj.recipe).Contains(Part()))
{
obj.recipe.Worker.ApplyOnPawn(giverPawn, Part(), billDoer, ingredients);
giverPawn.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, giverPawn, null), null, null);
if (giverPawn.RaceProps.IsFlesh)
{
giverPawn.records.Increment(RecordDefOf.OperationsReceived);
billDoer.records.Increment(RecordDefOf.OperationsPerformed);
}
}
Delete(obj);
}
}
}
If CCL didn't return an error on the detour, then it was detoured.
As I already suggested, stick in some log messages.
Sorry, I forgot, there it is the output log:
Initialize engine version: 5.3.4f1 (fdbb5133b820)
GfxDevice: creating device client; threaded=1
Direct3D:
Version: Direct3D 9.0c [aticfx32.dll 8.17.10.1474]
Renderer: AMD Radeon (TM) R9 200 Series
Vendor: ATI
VRAM: 2026 MB (via DXGI)
Caps: Shader=30 DepthRT=1 NativeDepth=1 NativeShadow=1 DF16=1 INTZ=1 NULL=1 RESZ=1 SlowINTZ=1
Begin MonoManager ReloadAssembly
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\Assembly-CSharp-firstpass.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\Assembly-CSharp-firstpass.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\Assembly-CSharp.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\Assembly-CSharp.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.UI.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.UI.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.Networking.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\UnityEngine.Networking.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\System.Xml.Linq.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\System.Xml.Linq.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\NAudio.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\NAudio.dll into Unity Child Domain
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\NVorbis.dll (this message is harmless)
Loading E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\NVorbis.dll into Unity Child Domain
- Completed reload, in 0.046 seconds
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\System.Core.dll (this message is harmless)
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\System.dll (this message is harmless)
Platform assembly: E:\Jogos do E\RimWorld.Alpha.14e\RimWorld1249Win_Data\Managed\System.Xml.dll (this message is harmless)
<RI> Initializing input.
<RI> Input initialized.
desktop: 1280x1024 60Hz; virtual: 1280x1024 at 0,0
<RI> Initialized touch support.
UnloadTime: 0.562249 ms
RimWorld 0.14.1249 rev955
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Non platform assembly: data-10E85B88 (this message is harmless)
Fallback handler could not load library E:/Jogos do E/RimWorld.Alpha.14e/RimWorld1249Win_Data/Mono/data-10E85B88.dll
Community Core Library :: v0.14.1
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Non platform assembly: data-10EEA390 (this message is harmless)
Fallback handler could not load library E:/Jogos do E/RimWorld.Alpha.14e/RimWorld1249Win_Data/Mono/data-10EEA390.dll
Community Core Library :: Queueing Library Initialization
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Library Core :: Validations :: Validated
ModHelperDef :: Community Core Library :: Passed validation, requesting v0.14.1
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Advanced Research :: Validations :: Validated
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Minimap Controller :: Validations :: Validated
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Injection Controller :: Initialization :: Initialized
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Advanced Research :: Initialization :: No advanced research defined, hybernating...
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Help System :: Completed in 00:00:00.2830162
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Help Generator :: Initialization :: Initialized
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Library Core :: Initialization :: Mod Configuration Menus initialized
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Minimap Controller :: Initialization :: Initialized
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Initialized
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Unloading 5 Unused Serialized files (Serialized files now loaded: 0)
UnloadTime: 1.113092 ms
Unloading 22 unused Assets to reduce memory usage. Loaded Objects now: 5937.
Total: 15.922208 ms (FindLiveObjects: 0.111369 ms CreateObjectMapping: 0.277372 ms MarkObjects: 15.508250 ms DeleteObjects: 0.024915 ms)
Initializing map from file Rhine with mods Core, Community Core Library, and SC
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Community Core Library :: Injection Controller :: Update :: Updated
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
Everything seems fine to me in this log "Community Core Library :: Injection Controller :: Initialization :: Initialized".
I will quote your caveman debugging message on my sig, cause every time I remember it makes me laugh :)
edit: And any example on the ccl that detour something with a method inaccessible due to protection inside?
as for this attempt of detouring Im going to retire. detour 1 callmedio 0, no regrets.
I gave up on the last and tried detouring something else... surprise,it also does nothing. Do i need holy water and a priest or is there some basic usage of CCL that im skipping?
I added CCL in references, did the injector class on my namespace like a posted previously and I have CCL on my mod folder loading after Core.
I mean you should add your own caveman debugging messages.
Log.Message( "Method Entered" );
...
Log.Message( "Checking for foo" );
...
Log.Message( "Checked bar" );
etc
Yea, I did some, one inside my custom method(didn't fired), other after injecting (didn't fired too)so i guess the injection returned false.
Edit: Forgot to mention i fixed some stupid errors I made, still not working, but no problem, I want to stop disturbing you guys, Im going to figure this sooner or later using caveman debugging and advanced guessing techniques.
OMG...... The thing that was wrong (among some other small things of course) is so stupid that Im feeling a little bit embarassed to post this, but for use of everybody I must share. My mod didn't had a ModHelperDefs folder with the proper xml... just saw on skullywag's fabric reclaim that he said to look at... I made the folder and the file, and after that with some little fixes it finally worked! Now I have so many ideas, creative time! Thanks everybody!
No worries, we're all allowed a derpy moment once in a while. ;)