diff --git a/CLre/API/Utility/Logging.cs b/CLre/API/Utility/Logging.cs
index 8366b18..2c5d30f 100644
--- a/CLre/API/Utility/Logging.cs
+++ b/CLre/API/Utility/Logging.cs
@@ -79,7 +79,7 @@ namespace CLre.API.Utility
///
/// The object to log
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void MetaDebugLog(object obj)
+ internal static void MetaDebugLog(object obj)
{
#if DEBUG
MetaLog($"[MetaDebug]{obj.ToString()}");
diff --git a/CLre/API/Utility/Reflection.cs b/CLre/API/Utility/Reflection.cs
new file mode 100644
index 0000000..edcc6af
--- /dev/null
+++ b/CLre/API/Utility/Reflection.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Reflection;
+using HarmonyLib;
+using Svelto.DataStructures;
+using Svelto.ECS;
+
+namespace CLre.API.Utility
+{
+ public static class Reflection
+ {
+ // useful function & method prototypes
+ public delegate T Getter();
+
+ public delegate bool ExistsV1(EGID egid);
+
+ public delegate bool ExistsV2(int id, int groupid);
+
+ public delegate T QueryEntityViewV1(EGID egid);
+
+ public delegate T QueryEntityViewV2(int id, ExclusiveGroup.ExclusiveGroupStruct groupid);
+
+ public delegate ReadOnlyCollectionStruct QueryEntityViews(int group) where T : class, IEntityViewStruct;
+
+ public delegate T[] QueryEntitiesV2(int group, out int count) where T : IEntityStruct;
+
+ public delegate T[] QueryEntitiesV1(ExclusiveGroup.ExclusiveGroupStruct group, out int count) where T : IEntityStruct;
+
+ // useful reflection functions
+ public static TFuncProto BuildDelegate(MethodInfo method) where TFuncProto : Delegate
+ {
+ return (TFuncProto) Delegate.CreateDelegate(typeof(TFuncProto), method);
+ }
+
+ public static Delegate BuildDelegateRaw(MethodInfo method, Type TFuncProto)
+ {
+ return Delegate.CreateDelegate(TFuncProto, method);
+ }
+
+ public static TFuncProto BuildDelegate(MethodInfo method, object instance) where TFuncProto : Delegate
+ {
+ return (TFuncProto) Delegate.CreateDelegate(typeof(TFuncProto), instance, method, true);
+ }
+
+ public static Delegate BuildDelegateRaw(MethodInfo method, object instance, Type TFuncProto)
+ {
+ return Delegate.CreateDelegate(TFuncProto, instance, method, true);
+ }
+
+ public static TFuncProto MethodAsDelegate(Type class_, string methodName, Type[] parameters = null, Type[] generics = null, object instance = null) where TFuncProto : Delegate
+ {
+ MethodInfo method = AccessTools.Method(class_, methodName, parameters, generics);
+ if (instance != null)
+ {
+ return BuildDelegate(method, instance);
+ }
+ return BuildDelegate(method);
+ }
+
+ public static Delegate MethodAsDelegateRaw(Type class_, Type TFuncProto, string methodName, Type[] parameters = null, Type[] generics = null, object instance = null)
+ {
+ MethodInfo method = AccessTools.Method(class_, methodName, parameters, generics);
+ if (instance != null)
+ {
+ return BuildDelegateRaw(method, instance, TFuncProto);
+ }
+ return BuildDelegateRaw(method, TFuncProto);
+ }
+
+ public static TFuncProto MethodAsDelegate(string typeColonName, Type[] parameters = null, Type[] generics = null, object instance = null) where TFuncProto : Delegate
+ {
+ MethodInfo method = AccessTools.Method(typeColonName, parameters, generics);
+ if (instance != null)
+ {
+ return BuildDelegate(method, instance);
+ }
+ return BuildDelegate(method);
+ }
+
+ public static Delegate MethodAsDelegateRaw(string typeColonName, Type TFuncProto, Type[] parameters = null, Type[] generics = null, object instance = null)
+ {
+ MethodInfo method = AccessTools.Method(typeColonName, parameters, generics);
+ if (instance != null)
+ {
+ return BuildDelegateRaw(method, instance, TFuncProto);
+ }
+ return BuildDelegateRaw(method, TFuncProto);
+ }
+
+ public static PropertyInfo GetIndexer(this Type type, Type[] arguments = null, BindingFlags bindingFlags = BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.Static)
+ {
+ foreach (PropertyInfo p in type.GetProperties(bindingFlags))
+ {
+ if (arguments == null && p.GetIndexParameters().Length != 0) return p;
+ if (arguments != null)
+ {
+ uint count = 0;
+ foreach (ParameterInfo param in p.GetIndexParameters())
+ {
+ if (param.ParameterType != arguments[count])
+ {
+ break;
+ }
+
+ count++;
+ }
+ if (count == arguments.Length)
+ {
+ return p;
+ }
+ }
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CLre/CLre.cs b/CLre/CLre.cs
index 009a236..86e80e3 100644
--- a/CLre/CLre.cs
+++ b/CLre/CLre.cs
@@ -83,5 +83,13 @@ namespace CLre
sb.AppendFormat("-----------------------------\n");
API.Utility.Logging.Log(sb.ToString());
}
+
+ public override void OnGUI()
+ {
+ if (GUI.Button(new Rect(10, 10, 50, 50), "TEST"))
+ {
+
+ }
+ }
}
}
diff --git a/CLre/CLre.csproj b/CLre/CLre.csproj
index c0c3eee..68c98a3 100644
--- a/CLre/CLre.csproj
+++ b/CLre/CLre.csproj
@@ -3,7 +3,7 @@
net472
true
- 0.0.1
+ 0.0.2
NGnius
MIT
https://git.exmods.org/NGnius/CLre
@@ -281,6 +281,9 @@
..\..\cl\Cardlife_Data\Managed\IllusionPlugin.dll
+
+
+
diff --git a/CLre/Fixes/CooldownCrossSlotSync.cs b/CLre/Fixes/CooldownCrossSlotSync.cs
new file mode 100644
index 0000000..5e5235f
--- /dev/null
+++ b/CLre/Fixes/CooldownCrossSlotSync.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using CLre.API.Utility;
+using HarmonyLib;
+using Svelto.DataStructures;
+using Svelto.ECS;
+
+namespace CLre.Fixes
+{
+ [Bugfix(name = "CooldownCrossSlotSync",
+ more = "https://trello.com/c/65FPrTjK/12-no-cooldown-between-inventory-slots",
+ description = "Apply cooldown to all weapons",
+ component = BugfixType.HarmonyPatch, id = 4)]
+ [HarmonyPatch]
+ class WeaponCooldownEngine_OnQuickAttackStateChange_Patch
+ {
+ public static bool Enable = true;
+
+ private static bool isRunningTick = false;
+
+ [HarmonyPostfix]
+ public static void AfterMethodCall(object __instance, int characterId, bool isPerformingQuickAttack)
+ {
+ if (!Enable) return;
+ // TODO optimise this... a lot
+ // build functions for retrieving internal Game.Handhelds.CharacterWeaponCooldownEntityView object
+ IEntitiesDB entitiesDB = (IEntitiesDB)
+ AccessTools.PropertyGetter(AccessTools.TypeByName("Game.Handhelds.WeaponCooldownEngine"), "entitiesDB")
+ .Invoke(__instance, new object[0]);
+ Reflection.ExistsV2 cwcevExists =
+ Reflection.MethodAsDelegate(
+ "Svelto.ECS.IEntitiesDB:Exists",
+ new[] {typeof(int), typeof(int)},
+ new[] {AccessTools.TypeByName("Game.Handhelds.CharacterWeaponCooldownEntityView")},
+ entitiesDB);
+ Reflection.QueryEntityViewV2