diff --git a/RogueLibsCore.Test/RogueLibsCore.Test.csproj b/RogueLibsCore.Test/RogueLibsCore.Test.csproj
index 2ef4daff2..6a45ffd01 100644
--- a/RogueLibsCore.Test/RogueLibsCore.Test.csproj
+++ b/RogueLibsCore.Test/RogueLibsCore.Test.csproj
@@ -36,7 +36,8 @@
True
Resources.resx
-
+
+
diff --git a/RogueLibsCore.Test/TestPlugin.cs b/RogueLibsCore.Test/TestPlugin.cs
index 7cf045caa..744badc98 100644
--- a/RogueLibsCore.Test/TestPlugin.cs
+++ b/RogueLibsCore.Test/TestPlugin.cs
@@ -23,11 +23,14 @@ public void Awake()
{
Log = Logger;
Instance = this;
+
LootBox.Test();
Converter.Test();
Duplicator.Test();
NuclearBriefcase.Test();
+ GiantAbility.Test();
+
Smoker.Test();
}
}
diff --git a/RogueLibsCore.Test/Tests/GiantAbility.cs b/RogueLibsCore.Test/Tests/GiantAbility.cs
new file mode 100644
index 000000000..367d6f210
--- /dev/null
+++ b/RogueLibsCore.Test/Tests/GiantAbility.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace RogueLibsCore.Test
+{
+ public class GiantAbility : CustomAbility, IDoUpdate
+ {
+ public static void Test()
+ {
+ RogueLibs.CreateCustomAbility()
+ .WithName(new CustomNameInfo("Giant"))
+ .WithDescription(new CustomNameInfo("Transform into a giant and crush your enemies!"))
+ .WithSprite(Properties.Resources.Batteries)
+ .WithUnlock(new AbilityUnlock { UnlockCost = 15, CharacterCreationCost = 10, });
+ }
+
+ public override void SetupDetails() { }
+ public override string GetCountString() => recharge != 0f ? recharge.ToString() : base.GetCountString();
+
+ public override void OnAdded() { }
+ public override void OnHeld(OnAbilityHeldArgs e) { }
+ public override void OnReleased(OnAbilityReleasedArgs e) { }
+ public override void OnUpdated(OnAbilityUpdatedArgs e) { }
+ public override PlayfieldObject FindTarget() => null;
+
+ private float recharge;
+ public void Update() => recharge = Mathf.Max(recharge - Time.deltaTime, 0f);
+
+ public override void OnPressed()
+ {
+ if (recharge > 0f) return;
+
+ Owner.statusEffects.AddStatusEffect("Giant", 15);
+ Owner.statusEffects.AddStatusEffect("Enraged", 15);
+
+ recharge = 30f;
+ }
+ }
+}
diff --git a/RogueLibsCore.Test/Smoker.cs b/RogueLibsCore.Test/Tests/Smoker.cs
similarity index 97%
rename from RogueLibsCore.Test/Smoker.cs
rename to RogueLibsCore.Test/Tests/Smoker.cs
index 15375a28f..8a78dfda5 100644
--- a/RogueLibsCore.Test/Smoker.cs
+++ b/RogueLibsCore.Test/Tests/Smoker.cs
@@ -22,6 +22,7 @@ public static void Test()
public override void OnAdded()
{
+ RogueFramework.LogDebug("");
Owner.SetEndurance(Owner.enduranceStatMod - 1);
Owner.SetSpeed(Owner.speedStatMod - 1);
}
diff --git a/RogueLibsCore/CustomName.cs b/RogueLibsCore/CustomName.cs
index e04b0d5f9..277c6f6c1 100644
--- a/RogueLibsCore/CustomName.cs
+++ b/RogueLibsCore/CustomName.cs
@@ -140,7 +140,10 @@ public static void RegisterLanguageCode(string languageName, LanguageCode code)
if (languageName is null) throw new ArgumentNullException(nameof(languageName));
if (languages.ContainsKey(languageName))
throw new ArgumentException($"The specified {nameof(languageName)} is already taken.", nameof(languageName));
- RogueFramework.Logger.LogDebug($"Registered \"{languageName}\" language ({(int)code})");
+
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Names))
+ RogueFramework.Logger.LogDebug($"Registered \"{languageName}\" language ({(int)code})");
+
languages.Add(languageName, code);
languageNames.Add(code, languageName);
}
@@ -165,6 +168,9 @@ public void GetName(string name, string type, ref string result)
}
public CustomName AddName(string name, string type, CustomNameInfo info)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Names))
+ RogueFramework.LogDebug($"Added \"{name}\" name ({type}): {info.English}");
+
CustomName customName = new CustomName(name, type, info);
if (!CustomNames.TryGetValue(type, out Dictionary category))
CustomNames.Add(type, category = new Dictionary());
diff --git a/RogueLibsCore/Hooks/Effects/CustomEffect.cs b/RogueLibsCore/Hooks/Effects/CustomEffect.cs
index 08a3aa5e4..bd7102d17 100644
--- a/RogueLibsCore/Hooks/Effects/CustomEffect.cs
+++ b/RogueLibsCore/Hooks/Effects/CustomEffect.cs
@@ -61,6 +61,8 @@ public override bool TryCreate(StatusEffect instance, out IHook ho
public EffectInfo AddEffect() where T : CustomEffect, new()
{
EffectInfo info = EffectInfo.Get();
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Effects))
+ RogueFramework.LogDebug($"Created custom effect {typeof(T)} ({info.Name}).");
effectsDict.Add(info.Name, new EffectEntry { Initializer = () => new T(), EffectInfo = info });
return info;
}
diff --git a/RogueLibsCore/Hooks/Items/CustomItem.cs b/RogueLibsCore/Hooks/Items/CustomItem.cs
index 84e3a99aa..7de03701e 100644
--- a/RogueLibsCore/Hooks/Items/CustomItem.cs
+++ b/RogueLibsCore/Hooks/Items/CustomItem.cs
@@ -106,6 +106,8 @@ public override bool TryCreate(InvItem instance, out IHook hook)
public ItemInfo AddItem() where T : CustomItem, new()
{
ItemInfo info = ItemInfo.Get();
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug($"Created custom item {typeof(T)} ({info.Name}).");
itemsDict.Add(info.Name, new ItemEntry { Initializer = () => new T(), ItemInfo = info });
return info;
}
diff --git a/RogueLibsCore/Hooks/Items/InventoryChecks.cs b/RogueLibsCore/Hooks/Items/InventoryChecks.cs
index f26b0ca6b..8aa9cd6df 100644
--- a/RogueLibsCore/Hooks/Items/InventoryChecks.cs
+++ b/RogueLibsCore/Hooks/Items/InventoryChecks.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UnityEngine;
namespace RogueLibsCore
{
@@ -11,13 +12,32 @@ public static class InventoryChecks
internal static readonly RogueEvent onItemUsing = new RogueEvent();
internal static readonly RogueEvent onItemsCombining = new RogueEvent();
internal static readonly RogueEvent onItemTargeting = new RogueEvent();
+ internal static readonly RogueEvent onItemTargetingAnywhere = new RogueEvent();
public static void AddItemUsingCheck(string name, RogueEventHandler check)
- => onItemUsing.Subscribe(name, check);
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug($"Added \"{name}\" usage inventory check.");
+ onItemUsing.Subscribe(name, check);
+ }
public static void AddItemsCombiningCheck(string name, RogueEventHandler check)
- => onItemsCombining.Subscribe(name, check);
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug($"Added \"{name}\" combining inventory check.");
+ onItemsCombining.Subscribe(name, check);
+ }
public static void AddItemTargetingCheck(string name, RogueEventHandler check)
- => onItemTargeting.Subscribe(name, check);
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug($"Added \"{name}\" targeting inventory check.");
+ onItemTargeting.Subscribe(name, check);
+ }
+ public static void AddItemTargetingAnywhereCheck(string name, RogueEventHandler check)
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug($"Added \"{name}\" targeting anywhere inventory check.");
+ onItemTargetingAnywhere.Subscribe(name, check);
+ }
public static bool IsCheckAllowed(InvItem item, string checkName) => IsCheckAllowed(item?.GetHook(), checkName);
public static bool IsCheckAllowed(CustomItem customItem, string checkName)
@@ -60,6 +80,19 @@ public OnItemTargetingArgs(InvItem item, PlayfieldObject targetObject, Agent use
public PlayfieldObject Target { get; set; }
public Agent User { get; set; }
}
+ public class OnItemTargetingAnywhereArgs : RogueEventArgs
+ {
+ public OnItemTargetingAnywhereArgs(InvItem item, Vector2 position, Agent user)
+ {
+ Item = item;
+ Target = position;
+ User = user;
+ }
+ public InvDatabase Inventory => Item.database;
+ public InvItem Item { get; }
+ public Vector2 Target { get; set; }
+ public Agent User { get; set; }
+ }
public class RogueEvent where TArgs : RogueEventArgs
{
private readonly List> list = new List>(0);
diff --git a/RogueLibsCore/Hooks/Traits/CustomTrait.cs b/RogueLibsCore/Hooks/Traits/CustomTrait.cs
index a3ad32845..e62883f70 100644
--- a/RogueLibsCore/Hooks/Traits/CustomTrait.cs
+++ b/RogueLibsCore/Hooks/Traits/CustomTrait.cs
@@ -46,6 +46,8 @@ public override bool TryCreate(Trait instance, out IHook hook)
public TraitInfo AddTrait() where T : CustomTrait, new()
{
TraitInfo info = TraitInfo.Get();
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Traits))
+ RogueFramework.LogDebug($"Created custom trait {typeof(T)} ({info.Name}).");
traitsDict.Add(info.Name, new TraitEntry { Initializer = () => new T(), TraitInfo = info });
return info;
}
diff --git a/RogueLibsCore/Patches/Patches_Abilities.cs b/RogueLibsCore/Patches/Patches_Abilities.cs
index 5576b6a1c..6c53e44c3 100644
--- a/RogueLibsCore/Patches/Patches_Abilities.cs
+++ b/RogueLibsCore/Patches/Patches_Abilities.cs
@@ -30,12 +30,12 @@ public static void StatusEffects_GiveSpecialAbility(StatusEffects __instance)
CustomAbility custom = __instance.agent.GetAbility();
if (custom is null) return;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Abilities))
+ RogueFramework.LogDebug($"Giving ability {custom} ({__instance.agent.specialAbility}, {__instance.agent.agentName}).");
+
try { custom.OnAdded(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error in CustomAbility.OnAdded() - {custom} ({__instance.agent.specialAbility})");
- RogueFramework.Logger.LogError(e);
- }
+ catch (Exception e) { RogueFramework.LogError(e, "CustomAbility.OnAdded", custom, __instance.agent); }
+
__instance.SpecialAbilityInterfaceCheck();
__instance.RechargeSpecialAbility(custom.ItemInfo.Name);
}
@@ -45,12 +45,11 @@ public static void StatusEffects_PressedSpecialAbility(StatusEffects __instance)
CustomAbility custom = __instance.agent.GetAbility();
if (custom is null) return;
- try { custom?.OnPressed(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error in CustomAbility.OnPressed() - {custom} ({__instance.agent.specialAbility})");
- RogueFramework.Logger.LogError(e);
- }
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Abilities))
+ RogueFramework.LogDebug($"Pressing ability ability {custom} ({__instance.agent.specialAbility}, {__instance.agent.agentName}).");
+
+ try { custom.OnPressed(); }
+ catch (Exception e) { RogueFramework.LogError(e, "CustomAbility.OnPressed", custom, __instance.agent); }
}
public static void StatusEffects_HeldSpecialAbility(StatusEffects __instance)
{
@@ -60,18 +59,16 @@ public static void StatusEffects_HeldSpecialAbility(StatusEffects __instance)
ref float held = ref GameController.gameController.playerControl.pressedSpecialAbilityTime[__instance.agent.isPlayer - 1];
float prevHeld = held;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Abilities))
+ RogueFramework.LogDebug($"Holding ability {custom} for {prevHeld}s ({__instance.agent.specialAbility}, {__instance.agent.agentName}).");
+
OnAbilityHeldArgs args = new OnAbilityHeldArgs { HeldTime = prevHeld };
try { custom.OnHeld(args); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error in CustomAbility.OnHeld() - {custom} ({__instance.agent.specialAbility})");
- RogueFramework.Logger.LogError(e);
- }
+ catch (Exception e) { RogueFramework.LogError(e, "CustomAbility.OnHeld", custom, __instance.agent); }
held = args.HeldTime;
- custom.lastHeld = args.HeldTime;
-
- if (held is 0f) custom.OnReleased(new OnAbilityReleasedArgs(prevHeld));
+ custom.lastHeld = prevHeld;
+ __instance.ReleasedSpecialAbility();
}
public static void StatusEffects_ReleasedSpecialAbility(StatusEffects __instance)
{
@@ -81,13 +78,12 @@ public static void StatusEffects_ReleasedSpecialAbility(StatusEffects __instance
float prevHeld = custom.lastHeld;
if (prevHeld is 0f) return;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Abilities))
+ RogueFramework.LogDebug($"Releasing ability {custom} - {prevHeld}s ({__instance.agent.specialAbility}, {__instance.agent.agentName}).");
+
custom.lastHeld = 0f;
try { custom.OnReleased(new OnAbilityReleasedArgs(prevHeld)); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error in CustomAbility.OnReleased() - {custom} ({__instance.agent.specialAbility})");
- RogueFramework.Logger.LogError(e);
- }
+ catch (Exception e) { RogueFramework.LogError(e, "CustomAbility.OnReleased", custom, __instance.agent); }
}
}
}
diff --git a/RogueLibsCore/Patches/Patches_CharacterCreation.cs b/RogueLibsCore/Patches/Patches_CharacterCreation.cs
index 884168ce2..d562e3dd8 100644
--- a/RogueLibsCore/Patches/Patches_CharacterCreation.cs
+++ b/RogueLibsCore/Patches/Patches_CharacterCreation.cs
@@ -8,6 +8,8 @@
using UnityEngine.UI;
using BepInEx;
using HarmonyLib;
+using static UnityEngine.Random;
+using System.Diagnostics;
namespace RogueLibsCore
{
@@ -41,6 +43,8 @@ public static bool CharacterCreation_SortUnlocks(CharacterCreation __instance, L
displayedList.Sort();
CustomCharacterCreation menu = new CustomCharacterCreation(__instance, displayedList);
+ if (RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus))
+ RogueFramework.LogDebug($"Setting up \"{menu.Type}\" menu.");
List listUnlocks = unlockType == "Item" ? __instance.listUnlocksItems
: unlockType == "Trait" ? __instance.listUnlocksTraits
@@ -72,7 +76,14 @@ public static bool CharacterCreation_SortUnlocks(CharacterCreation __instance, L
public static bool CharacterCreation_PushedButton(CharacterCreation __instance, ButtonHelper myButton)
{
- if (__instance.selectedSpace == "Load") return true;
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus);
+ if (__instance.selectedSpace == "Load")
+ {
+ if (debug) RogueFramework.LogDebug("Redirecting the button push to the original method.");
+ return true;
+ }
+
+ if (debug) RogueFramework.LogDebug($"Pressing \"{myButton.myText.text}\" ({myButton.scrollingButtonNum}, {myButton.scrollingButtonType}) button.");
string type = myButton.scrollingButtonUnlock.unlockType;
List buttonsData = type == "Item" ? __instance.buttonsDataItems
@@ -83,7 +94,8 @@ public static bool CharacterCreation_PushedButton(CharacterCreation __instance,
ButtonData buttonData = buttonsData[myButton.scrollingButtonNum];
DisplayedUnlock du = (DisplayedUnlock)buttonData.__RogueLibsCustom;
- du.OnPushedButton();
+ try { du.OnPushedButton(); }
+ catch (Exception e) { RogueFramework.LogError(e, "DisplayedUnlock.OnPushedButton", du, du.Menu); }
__instance.curSelectedButton = myButton;
__instance.curSelectedButtonNum = myButton.scrollingButtonNum;
return false;
diff --git a/RogueLibsCore/Patches/Patches_Items.cs b/RogueLibsCore/Patches/Patches_Items.cs
index a824bcfaf..199136529 100644
--- a/RogueLibsCore/Patches/Patches_Items.cs
+++ b/RogueLibsCore/Patches/Patches_Items.cs
@@ -8,6 +8,7 @@
using UnityEngine.UI;
using BepInEx;
using HarmonyLib;
+using System.Diagnostics;
namespace RogueLibsCore
{
@@ -44,9 +45,18 @@ public void PatchItems()
public static void InvItem_SetupDetails(InvItem __instance)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Items);
+ bool debug2 = RogueFramework.IsDebugEnabled(DebugFlags.Abilities);
foreach (IHookFactory factory in RogueFramework.ItemFactories)
if (factory.TryCreate(__instance, out IHook hook))
{
+ if (debug2 && hook is CustomAbility)
+ RogueFramework.LogDebug($"Initializing custom ability {hook} ({__instance.invItemName}).");
+ else if (debug)
+ {
+ if (hook is CustomItem) RogueFramework.LogDebug($"Initializing custom item {hook} ({__instance.invItemName}).");
+ else RogueFramework.LogDebug($"Initializing item hook {hook} for \"{__instance.invItemName}\".");
+ }
__instance.AddHook(hook);
hook.Initialize();
}
@@ -54,13 +64,17 @@ public static void InvItem_SetupDetails(InvItem __instance)
public static bool ItemFunctions_UseItem(InvItem item, Agent agent)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Items);
CustomItem custom = item.GetHook();
if (custom is IItemTargetable || custom is IItemTargetableAnywhere)
{
+ if (debug) RogueFramework.LogDebug($"Showing target for {custom} ({item.invItemName}).");
item.invInterface.ShowOrHideTarget(item);
return false;
}
+ if (debug) RogueFramework.LogDebug($"Using {custom} ({item.invItemName}):");
+
Agent originalAgent = agent;
OnItemUsingArgs args = new OnItemUsingArgs(item, agent);
if (InventoryChecks.onItemUsing.Raise(args, custom?.ItemInfo.IgnoredChecks))
@@ -82,19 +96,31 @@ public static bool ItemFunctions_UseItem(InvItem item, Agent agent)
}
// if it's not a custom item, run the original method
if (!(custom is IItemUsable usable))
+ {
+ if (debug) RogueFramework.LogDebug("---- Running the original method.");
return true;
+ }
bool success = usable.UseItem();
+ if (debug) RogueFramework.LogDebug($"---- Usage {(success ? "was successful" : "failed")}.");
if (success) new ItemFunctions().UseItemAnim(item, agent);
}
}
+ else
+ {
+ if (debug) RogueFramework.LogDebug("---- Usage was prevented by an inventory check.");
+ }
return false;
}
public static bool InvItem_CombineItems(InvItem __instance, InvItem otherItem, int slotNum, Agent myAgent, string combineType, ref bool __result)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Items);
+ bool actualCombining = combineType == "Combine";
CustomItem custom = __instance.GetHook();
+ if (debug && actualCombining) RogueFramework.LogDebug($"Combining {custom} ({__instance.invItemName}) with {otherItem.invItemName}:");
+
if (__instance.stackable && __instance.invItemName == otherItem.invItemName
&& InventoryChecks.IsCheckAllowed(custom, "AutoStacking"))
{
@@ -103,8 +129,13 @@ public static bool InvItem_CombineItems(InvItem __instance, InvItem otherItem, i
__result = false;
return false;
}
- if (combineType == "Combine")
+ if (actualCombining)
{
+ if (debug)
+ {
+ RogueFramework.LogDebug("---- Triggered \"AutoStacking\" inventory check.");
+ RogueFramework.LogDebug("---- Combining was prevented by an inventory check.");
+ }
if (myAgent.controllerType != "Keyboard")
myAgent.gc.audioHandler.Play(myAgent, "BeginCombine");
otherItem.agent.mainGUI.invInterface.PutDraggedItemBack();
@@ -113,83 +144,127 @@ public static bool InvItem_CombineItems(InvItem __instance, InvItem otherItem, i
return false;
}
- bool filterResult;
if (custom is IItemCombinable combinable)
{
using (AgentSwapper swapper = new AgentSwapper(__instance, myAgent))
- filterResult = combinable.CombineFilter(otherItem);
+ __result = combinable.CombineFilter(otherItem);
}
- else filterResult = new ItemFunctions().CombineItems(__instance, myAgent, otherItem, slotNum, string.Empty);
-
- OnItemsCombiningArgs args = new OnItemsCombiningArgs(__instance, otherItem, myAgent);
- __result = filterResult && InventoryChecks.onItemsCombining.Raise(args, custom?.ItemInfo.IgnoredChecks);
+ else __result = new ItemFunctions().CombineItems(__instance, myAgent, otherItem, slotNum, string.Empty);
- if (__result && combineType == "Combine")
+ if (actualCombining)
{
- myAgent = args.Combiner;
- otherItem = args.OtherItem;
- if (custom is IItemCombinable combinable2)
+ OnItemsCombiningArgs args = new OnItemsCombiningArgs(__instance, otherItem, myAgent);
+ if (InventoryChecks.onItemsCombining.Raise(args, custom?.ItemInfo.IgnoredChecks))
{
- using (AgentSwapper swapper = new AgentSwapper(__instance, myAgent))
+ myAgent = args.Combiner;
+ otherItem = args.OtherItem;
+ if (custom is IItemCombinable combinable2)
{
- bool success = combinable2.CombineItems(otherItem);
- if (success) new ItemFunctions().UseItemAnim(__instance, myAgent);
+ using (AgentSwapper swapper = new AgentSwapper(__instance, myAgent))
+ {
+ bool success = combinable2.CombineItems(otherItem);
+ if (debug) RogueFramework.LogDebug($"---- Combining {(success ? "was successful" : "failed")}.");
+ if (success) new ItemFunctions().UseItemAnim(__instance, myAgent);
+ }
+ }
+ else
+ {
+ if (debug) RogueFramework.LogDebug("---- Running the original method.");
+ new ItemFunctions().CombineItems(__instance, myAgent, otherItem, slotNum, "Combine");
}
- }
- else new ItemFunctions().CombineItems(__instance, myAgent, otherItem, slotNum, "Combine");
- if (__instance.invItemCount < 1 || !__instance.database.InvItemList.Contains(__instance)
- && InventoryChecks.IsCheckAllowed(custom, "StopOnZero"))
+ if (__instance.invItemCount < 1 || !__instance.database.InvItemList.Contains(__instance)
+ && InventoryChecks.IsCheckAllowed(custom, "StopOnZero"))
+ {
+ if (debug) RogueFramework.LogDebug("---- Triggered \"StopOnZero\" inventory check.");
+ myAgent.mainGUI.invInterface.HideDraggedItem();
+ myAgent.mainGUI.invInterface.HideTarget();
+ }
+ }
+ else
{
- myAgent.mainGUI.invInterface.HideDraggedItem();
- myAgent.mainGUI.invInterface.HideTarget();
+ if (debug) RogueFramework.LogDebug("---- Combining was prevented by an inventory check.");
}
}
return false;
}
public static bool InvItem_TargetObject(InvItem __instance, PlayfieldObject otherObject, string combineType, ref bool __result)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Items);
+ bool actualCombining = combineType == "Combine";
CustomItem custom = __instance.GetHook();
+ if (debug && actualCombining) RogueFramework.LogDebug($"Targeting {custom} ({__instance.invItemName}) on {otherObject.objectName}:");
+
if (Vector2.Distance(__instance.agent.curPosition, otherObject.curPosition) > 15f
&& InventoryChecks.IsCheckAllowed(custom, "Distance"))
{
+ if (debug && actualCombining)
+ {
+ RogueFramework.LogDebug("---- Triggered \"Distance\" inventory check.");
+ RogueFramework.LogDebug("---- Targeting was prevented by an inventory check.");
+ }
__result = false;
return false;
}
if ((otherObject as Agent)?.butlerBot == true && InventoryChecks.IsCheckAllowed(custom, "ButlerBot"))
{
+ if (debug && actualCombining)
+ {
+ RogueFramework.LogDebug("---- Triggered \"ButlerBot\" inventory check.");
+ RogueFramework.LogDebug("---- Targeting was prevented by an inventory check.");
+ }
__result = false;
return false;
}
if ((otherObject as Agent)?.mechEmpty == true && InventoryChecks.IsCheckAllowed(custom, "EmptyMech"))
{
+ if (debug && actualCombining)
+ {
+ RogueFramework.LogDebug("---- Triggered \"EmptyMech\" inventory check.");
+ RogueFramework.LogDebug("---- Targeting was prevented by an inventory check.");
+ }
__result = false;
return false;
}
- bool firstCheck = custom is IItemTargetable targetable
+ __result = custom is IItemTargetable targetable
? targetable.TargetFilter(otherObject)
: new ItemFunctions().TargetObject(__instance, __instance.agent, otherObject, string.Empty);
- OnItemTargetingArgs args = new OnItemTargetingArgs(__instance, otherObject, __instance.agent);
- __result = firstCheck && InventoryChecks.onItemTargeting.Raise(args, custom?.ItemInfo.IgnoredChecks);
-
- if (__result && combineType == "Combine")
+ if (actualCombining)
{
- otherObject = args.Target;
- using (AgentSwapper swapper = new AgentSwapper(__instance, args.User))
+ OnItemTargetingArgs args = new OnItemTargetingArgs(__instance, otherObject, __instance.agent);
+ if (InventoryChecks.onItemTargeting.Raise(args, custom?.ItemInfo.IgnoredChecks))
{
- if (custom is IItemTargetable targetable2) targetable2.TargetObject(otherObject);
- else new ItemFunctions().TargetObject(__instance, __instance.agent, otherObject, "Combine");
-
- if (__instance.invItemCount < 1 || !__instance.database.InvItemList.Contains(__instance)
- && InventoryChecks.IsCheckAllowed(custom, "StopOnZero"))
+ otherObject = args.Target;
+ using (AgentSwapper swapper = new AgentSwapper(__instance, args.User))
{
- __instance.agent.mainGUI.invInterface.HideDraggedItem();
- __instance.agent.mainGUI.invInterface.HideTarget();
+ if (custom is IItemTargetable targetable2)
+ {
+ bool success = targetable2.TargetObject(otherObject);
+ if (debug) RogueFramework.LogDebug($"---- Targeting {(success ? "was successful" : "failed")}.");
+ if (success) new ItemFunctions().UseItemAnim(__instance, __instance.agent);
+ }
+ else
+ {
+ if (debug) RogueFramework.LogDebug("---- Running the original method.");
+ new ItemFunctions().TargetObject(__instance, __instance.agent, otherObject, "Combine");
+ }
+
+ if (__instance.invItemCount < 1 || !__instance.database.InvItemList.Contains(__instance)
+ && InventoryChecks.IsCheckAllowed(custom, "StopOnZero"))
+ {
+ if (debug) RogueFramework.LogDebug("---- Triggered \"StopOnZero\" inventory check.");
+ __instance.agent.mainGUI.invInterface.HideDraggedItem();
+ __instance.agent.mainGUI.invInterface.HideTarget();
+ }
}
}
+ else
+ {
+ if (debug) RogueFramework.LogDebug("---- Targeting was prevented by an inventory check.");
+ }
}
return false;
}
@@ -311,12 +386,16 @@ public static void InvSlot_UpdateInvSlot(InvSlot __instance, Text ___itemText)
public static void InvInterface_TargetAnywhere(InvInterface __instance, Vector2 myPos, bool pressedButton)
{
- if (__instance.mainGUI.targetItem != null)
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Items);
+ InvItem invItem = __instance.mainGUI.targetItem;
+ if (invItem != null)
{
- CustomItem custom = __instance.mainGUI.targetItem.GetHook();
+ CustomItem custom = invItem.GetHook();
__instance.cursorHighlightTargetObjects = custom is IItemTargetable;
if (custom is IItemTargetableAnywhere targetable)
{
+ if (debug && pressedButton)
+ RogueFramework.LogDebug($"Targeting {custom} ({invItem.invItemName}) anywhere:");
if (targetTextColor is null) targetTextColor = __instance.cursorTextString3.color;
bool filter = targetable.TargetFilter(myPos);
@@ -330,13 +409,29 @@ public static void InvInterface_TargetAnywhere(InvInterface __instance, Vector2
if (pressedButton)
{
- targetable.TargetPosition(myPos);
- if (custom.Count < 1 || !custom.Inventory.InvItemList.Contains(custom.Item))
+ OnItemTargetingAnywhereArgs args = new OnItemTargetingAnywhereArgs(invItem, myPos, invItem.agent);
+ if (InventoryChecks.onItemTargetingAnywhere.Raise(args, custom?.ItemInfo.IgnoredChecks))
+ {
+ myPos = args.Target;
+ using (AgentSwapper swapper = new AgentSwapper(invItem, args.User))
+ {
+ bool success = targetable.TargetPosition(myPos);
+ if (debug) RogueFramework.LogDebug($"---- Targeting {(success ? "was successful" : "failed")}.");
+ if (success) new ItemFunctions().UseItemAnim(invItem, invItem.agent);
+
+ if (custom.Count < 1 || !custom.Inventory.InvItemList.Contains(custom.Item)
+ && InventoryChecks.IsCheckAllowed(custom, "StopOnZero"))
+ {
+ if (debug) RogueFramework.LogDebug("---- Triggered \"StopOnZero\" inventory check.");
+ __instance.HideDraggedItem();
+ __instance.HideTarget();
+ }
+ }
+ }
+ else
{
- __instance.HideDraggedItem();
- __instance.HideTarget();
+ if (debug) RogueFramework.LogDebug("---- Targeting was prevented by an inventory check.");
}
- __instance.HideTarget();
}
}
}
@@ -375,6 +470,8 @@ public static void GhostCheck(OnItemUsingArgs e)
{
if (e.User.ghost)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"Ghost\" inventory check.");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
}
@@ -383,6 +480,8 @@ public static void PeaBrainedCheck(OnItemUsingArgs e)
{
if (e.Item.itemType != ItemTypes.Food && e.User.HasTrait("CantInteract"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"PeaBrained\" inventory check.");
e.User.SayDialogue("CantInteract");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -393,6 +492,8 @@ public static void OnlyOilCheck(OnItemUsingArgs e)
if (e.Item.itemType == ItemTypes.Food && (e.Item.Categories.Contains("Food") || e.Item.Categories.Contains("Alcohol"))
&& e.User.HasTrait("OilRestoresHealth"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyOil\" inventory check.");
e.User.SayDialogue("OnlyOilGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -403,6 +504,8 @@ public static void OnlyOilMedicineCheck(OnItemUsingArgs e)
if (e.Item.itemType == ItemTypes.Consumable && e.Item.Categories.Contains("Health")
&& e.User.HasTrait("OilRestoresHealth"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyOilMedicine\" inventory check.");
e.User.SayDialogue("OnlyOilGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -413,6 +516,8 @@ public static void OnlyBloodCheck(OnItemUsingArgs e)
if (e.Item.itemType == ItemTypes.Food && (e.Item.Categories.Contains("Food") || e.Item.Categories.Contains("Alcohol"))
&& e.User.HasTrait("BloodRestoresHealth"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyBlood\" inventory check.");
e.User.SayDialogue("OnlyBloodGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -423,6 +528,8 @@ public static void OnlyBloodMedicineCheck(OnItemUsingArgs e)
if (e.Item.itemType == ItemTypes.Consumable && e.Item.Categories.Contains("Health")
&& e.User.HasTrait("BloodRestoresHealth"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyBloodMedicine\" inventory check.");
e.User.SayDialogue("OnlyBloodGivesHealth2");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -432,6 +539,8 @@ public static void OnlyChargeCheck(OnItemUsingArgs e)
{
if (e.User.electronic && e.Item.itemType == ItemTypes.Food && e.Item.Categories.Contains("Food"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyCharge\" inventory check.");
e.User.SayDialogue("OnlyChargeGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -441,6 +550,8 @@ public static void OnlyChargeMedicineCheck(OnItemUsingArgs e)
{
if (e.User.electronic && e.Item.itemType == ItemTypes.Consumable && e.Item.Categories.Contains("Health"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyChargeMedicine\" inventory check.");
e.User.SayDialogue("OnlyChargeGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -451,6 +562,8 @@ public static void OnlyHumanFleshCheck(OnItemUsingArgs e)
if (e.Item.itemType == ItemTypes.Food && e.Item.Categories.Contains("Food")
&& e.User.HasTrait("CannibalizeRestoresHealth"))
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"OnlyHumanFlesh\" inventory check.");
e.User.SayDialogue("OnlyCannibalizeGivesHealth");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
@@ -460,6 +573,8 @@ public static void FullHealthCheck(OnItemUsingArgs e)
{
if (e.Item.healthChange > 0 && e.User.health == e.User.healthMax)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Items))
+ RogueFramework.LogDebug("---- Triggered \"FullHealth\" inventory check.");
e.User.SayDialogue("HealthFullCantUseItem");
e.User.gc.audioHandler.Play(e.User, "CantDo");
e.Cancel = e.Handled = true;
diff --git a/RogueLibsCore/Patches/Patches_Misc.cs b/RogueLibsCore/Patches/Patches_Misc.cs
index be0f072b7..ccc5daff7 100644
--- a/RogueLibsCore/Patches/Patches_Misc.cs
+++ b/RogueLibsCore/Patches/Patches_Misc.cs
@@ -15,14 +15,14 @@ public partial class RogueLibsPlugin
{
public void PatchMisc()
{
- // get and set the current game language as a LanguageCode
+ // initialize LanguageService
Patcher.Postfix(typeof(NameDB), nameof(NameDB.RealAwake));
// CustomNames
Patcher.Postfix(typeof(NameDB), nameof(NameDB.GetName));
- // IDoUpdate.Update()
+ // IDoUpdate.Update
Patcher.Postfix(typeof(Updater), "Update");
- // IDoFixedUpdate.FixedUpdate()
+ // IDoFixedUpdate.FixedUpdate
Patcher.Postfix(typeof(Updater), nameof(Updater.FixedUpdate));
}
@@ -30,6 +30,8 @@ public static void NameDB_RealAwake(NameDB __instance)
{
if (!LanguageService.Languages.TryGetValue(__instance.language, out LanguageCode code))
code = LanguageCode.English;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Names))
+ RogueFramework.LogDebug($"Current language: {LanguageService.GetLanguageName(code)} ({(int)code})");
LanguageService.NameDB = __instance;
LanguageService.Current = code;
@@ -47,153 +49,101 @@ public static void NameDB_GetName(string myName, string type, ref string __resul
public static void Updater_Update()
{
- List agents = GameController.gameController.agentList;
- for (int i = 0; i < agents.Count; i++)
+ foreach (Agent agent in GameController.gameController.agentList.ToList())
{
- Agent agent = agents[i];
- foreach (IDoUpdate obj in agents[i].GetHooks())
+ foreach (IDoUpdate obj in agent.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {agent.agentName}");
- RogueFramework.Logger.LogError(e);
- }
-
- for (int j = 0; j < agent.inventory.InvItemList.Count; j++)
- {
- InvItem item = agent.inventory.InvItemList[j];
- foreach (IDoUpdate obj in item.GetHooks())
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj); }
+
+ InvItem specialAbility = agent.inventory.equippedSpecialAbility;
+ if (specialAbility != null)
+ foreach (IDoUpdate obj in specialAbility.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {item.invItemName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
-
- for (int j = 0; j < agent.statusEffects.StatusEffectList.Count; j++)
- {
- StatusEffect effect = agent.statusEffects.StatusEffectList[j];
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, agent); }
+
+ foreach (InvItem item in agent.inventory.InvItemList.ToList())
+ if (item != specialAbility)
+ foreach (IDoUpdate obj in item.GetHooks())
+ try { obj.Update(); }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, agent); }
+
+ foreach (StatusEffect effect in agent.statusEffects.StatusEffectList.ToList())
foreach (IDoUpdate obj in effect.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {effect.statusEffectName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
-
- for (int j = 0; j < agent.statusEffects.TraitList.Count; j++)
- {
- Trait trait = agent.statusEffects.TraitList[j];
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, agent); }
+
+ foreach (Trait trait in agent.statusEffects.TraitList.ToList())
foreach (IDoUpdate obj in trait.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {trait.traitName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, agent); }
}
- List- items = GameController.gameController.itemList;
- for (int i = 0; i < items.Count; i++)
+ foreach (ObjectReal objectReal in GameController.gameController.objectRealListUpdate.ToList())
{
- foreach (IDoUpdate obj in items[i].invItem.GetHooks())
+ foreach (IDoUpdate obj in objectReal.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {items[i]}");
- RogueFramework.Logger.LogError(e);
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj); }
+
+ if (objectReal.objectInvDatabase != null)
+ foreach (InvItem item in objectReal.objectInvDatabase.InvItemList)
+ foreach (IDoUpdate obj in item.GetHooks())
+ try { obj.Update(); }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, objectReal); }
}
- List objects = GameController.gameController.objectRealListUpdate;
- for (int i = 0; i < objects.Count; i++)
- {
- foreach (IDoUpdate obj in objects[i].GetHooks())
+ foreach (Item item in GameController.gameController.itemList.ToList())
+ foreach (IDoUpdate obj in item.invItem.GetHooks())
try { obj.Update(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {objects[i].objectName}");
- RogueFramework.Logger.LogError(e);
- }
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoUpdate.Update", obj, item); }
}
public static void Updater_FixedUpdate()
{
- List agents = GameController.gameController.agentList;
- for (int i = 0; i < agents.Count; i++)
+ foreach (Agent agent in GameController.gameController.agentList.ToList())
{
- Agent agent = agents[i];
- foreach (IDoFixedUpdate obj in agents[i].GetHooks())
+ foreach (IDoFixedUpdate obj in agent.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {agent.agentName}");
- RogueFramework.Logger.LogError(e);
- }
-
- for (int j = 0; j < agent.inventory.InvItemList.Count; j++)
- {
- InvItem item = agent.inventory.InvItemList[j];
- foreach (IDoFixedUpdate obj in item.GetHooks())
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj); }
+
+ InvItem specialAbility = agent.inventory.equippedSpecialAbility;
+ if (specialAbility != null)
+ foreach (IDoFixedUpdate obj in specialAbility.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {item.invItemName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
-
- for (int j = 0; j < agent.statusEffects.StatusEffectList.Count; j++)
- {
- StatusEffect effect = agent.statusEffects.StatusEffectList[j];
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, agent); }
+
+ foreach (InvItem item in agent.inventory.InvItemList.ToList())
+ if (item != specialAbility)
+ foreach (IDoFixedUpdate obj in item.GetHooks())
+ try { obj.FixedUpdate(); }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, agent); }
+
+ foreach (StatusEffect effect in agent.statusEffects.StatusEffectList.ToList())
foreach (IDoFixedUpdate obj in effect.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {effect.statusEffectName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
-
- for (int j = 0; j < agent.statusEffects.TraitList.Count; j++)
- {
- Trait trait = agent.statusEffects.TraitList[j];
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, agent); }
+
+ foreach (Trait trait in agent.statusEffects.TraitList.ToList())
foreach (IDoFixedUpdate obj in trait.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {trait.traitName} ({agent.agentName})");
- RogueFramework.Logger.LogError(e);
- }
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, agent); }
}
- List
- items = GameController.gameController.itemList;
- for (int i = 0; i < items.Count; i++)
+ foreach (ObjectReal objectReal in GameController.gameController.objectRealListUpdate.ToList())
{
- foreach (IDoFixedUpdate obj in items[i].invItem.GetHooks())
+ foreach (IDoFixedUpdate obj in objectReal.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {items[i]}");
- RogueFramework.Logger.LogError(e);
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj); }
+
+ if (objectReal.objectInvDatabase != null)
+ foreach (InvItem item in objectReal.objectInvDatabase.InvItemList)
+ foreach (IDoFixedUpdate obj in item.GetHooks())
+ try { obj.FixedUpdate(); }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, objectReal); }
}
- List objects = GameController.gameController.objectRealListUpdate;
- for (int i = 0; i < objects.Count; i++)
- {
- foreach (IDoFixedUpdate obj in objects[i].GetHooks())
+ foreach (Item item in GameController.gameController.itemList.ToList())
+ foreach (IDoFixedUpdate obj in item.invItem.GetHooks())
try { obj.FixedUpdate(); }
- catch (Exception e)
- {
- RogueFramework.Logger.LogError($"Error updating {obj} in {objects[i].objectName}");
- RogueFramework.Logger.LogError(e);
- }
- }
+ catch (Exception e) { RogueFramework.LogError(e, "IDoFixedUpdate.FixedUpdate", obj, item); }
}
}
}
diff --git a/RogueLibsCore/Patches/Patches_ScrollingMenu.cs b/RogueLibsCore/Patches/Patches_ScrollingMenu.cs
index 1b3a2cb11..93ed592ed 100644
--- a/RogueLibsCore/Patches/Patches_ScrollingMenu.cs
+++ b/RogueLibsCore/Patches/Patches_ScrollingMenu.cs
@@ -40,18 +40,22 @@ public void PatchScrollingMenu()
Patcher.Postfix(typeof(ScrollingMenu), nameof(ScrollingMenu.CanHaveTrait));
RogueLibs.CreateCustomName("GiveNuggetsDebug", "Unlock", new CustomNameInfo("[DEBUG] +10 Nuggets"));
- RogueLibs.CreateCustomName("D_GiveNuggetsDebug", "Unlock", new CustomNameInfo("A debug-build feature that gives you 10 nuggets."));
+ RogueLibs.CreateCustomName("D_GiveNuggetsDebug", "Unlock", new CustomNameInfo("A debug tool that gives you 10 nuggets."));
}
public static void ScrollingMenu_OpenScrollingMenu_Prefix(ScrollingMenu __instance, out float __state)
{
float x = 1f - __instance.scrollBar.value;
__state = x * (__instance.numButtons - __instance.numButtonsOnScreen + 1f);
+ if (RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus))
+ RogueFramework.LogDebug($"Stored menu's scrolling value of {__state} units.");
}
public static void ScrollingMenu_OpenScrollingMenu(ScrollingMenu __instance, ref float __state, List ___listUnlocks)
{
__instance.numButtons = ___listUnlocks.Count;
float x = __state / (__instance.numButtons - __instance.numButtonsOnScreen + 1f);
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus);
+ if (debug) RogueFramework.LogDebug($"Restoring menu's scrolling value of {__state} units.");
__instance.StartCoroutine(EnsureScrollbarValue(__instance, Mathf.Clamp01(1f - x)));
if (__instance.menuType == "Challenges" || __instance.menuType == "FreeItems")
@@ -60,6 +64,7 @@ public static void ScrollingMenu_OpenScrollingMenu(ScrollingMenu __instance, ref
}
else if (__instance.menuType == "Floors")
{
+ if (debug) RogueFramework.LogDebug("Setting up \"Floors\" menu.");
List displayedUnlocks = GameController.gameController.sessionDataBig.floorUnlocks.Select(u => (DisplayedUnlock)u.__RogueLibsCustom).OrderBy(d => d).ToList();
CustomScrollingMenu menu = new CustomScrollingMenu(__instance, displayedUnlocks);
@@ -77,6 +82,7 @@ public static void ScrollingMenu_OpenScrollingMenu(ScrollingMenu __instance, ref
}
else if (__instance.menuType == "Traits")
{
+ if (debug) RogueFramework.LogDebug("Setting up \"Traits\" menu.");
__instance.numButtons = __instance.smallTraitList.Count;
List displayedUnlocks = __instance.smallTraitList.Select(u => (DisplayedUnlock)u.__RogueLibsCustom).OrderBy(d => d).ToList();
CustomScrollingMenu menu = new CustomScrollingMenu(__instance, displayedUnlocks);
@@ -89,6 +95,7 @@ public static void ScrollingMenu_OpenScrollingMenu(ScrollingMenu __instance, ref
}
else if (__instance.menuType == "RemoveTrait" || __instance.menuType == "ChangeTraitRandom" || __instance.menuType == "UpgradeTrait")
{
+ if (debug) RogueFramework.LogDebug($"Setting up \"{__instance.menuType}\" menu.");
__instance.numButtons = __instance.customTraitList.Count;
List displayedUnlocks = __instance.customTraitList.Select(u => (DisplayedUnlock)u.__RogueLibsCustom).OrderBy(d => d).ToList();
CustomScrollingMenu menu = new CustomScrollingMenu(__instance, displayedUnlocks);
@@ -167,6 +174,8 @@ public static bool ScrollingMenu_SortUnlocks(ScrollingMenu __instance, List du.Unlock));
@@ -180,6 +189,7 @@ public static bool ScrollingMenu_SortUnlocks(ScrollingMenu __instance, List ___loadoutList)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus);
+ if (debug) RogueFramework.LogDebug("Refreshing the loadouts.");
___loadoutList.RemoveAt(0);
for (int i = 0; i < ___loadoutList.Count; i++)
{
Unlock unlock = ___loadoutList[i];
if (unlock.__RogueLibsCustom is null)
{
+ if (debug) RogueFramework.LogDebug("Hooking up an unhooked unlock.");
Unlock normalized = GameController.gameController.sessionDataBig.unlocks
.Find(u => u.unlockName == unlock.unlockName && u.unlockType == unlock.unlockType);
unlock.__RogueLibsCustom = normalized.__RogueLibsCustom;
@@ -284,9 +296,10 @@ public GiveNuggetsButton() : base("GiveNuggetsDebug", true) { }
public override string GetFancyName() => $"{GetName()}";
public override void OnPushedButton()
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.UnlockMenus))
+ RogueFramework.LogDebug("Added 10 nuggets with the debug tool.");
gc.unlocks.AddNuggets(10);
PlaySound("BuyItem");
- gc.unlocks.SaveUnlockData(true);
UpdateMenu();
}
}
diff --git a/RogueLibsCore/Patches/Patches_Sprites.cs b/RogueLibsCore/Patches/Patches_Sprites.cs
index a28a12506..81c4f6c0b 100644
--- a/RogueLibsCore/Patches/Patches_Sprites.cs
+++ b/RogueLibsCore/Patches/Patches_Sprites.cs
@@ -15,7 +15,7 @@ public partial class RogueLibsPlugin
{
public void PatchSprites()
{
- // define RogueSprites in the RogueSprite.addOnGCAwakeList
+ // define non-initialized RogueSprites
Patcher.Postfix(typeof(GameController), "Awake");
// set the shared material of all renderers to the one selected in the tk2dSpriteDefinition
diff --git a/RogueLibsCore/Patches/Patches_TraitsStatusEffects.cs b/RogueLibsCore/Patches/Patches_TraitsStatusEffects.cs
index dec681304..f453decb8 100644
--- a/RogueLibsCore/Patches/Patches_TraitsStatusEffects.cs
+++ b/RogueLibsCore/Patches/Patches_TraitsStatusEffects.cs
@@ -8,6 +8,8 @@
using HarmonyLib;
using UnityEngine.Networking;
using UnityEngine;
+using System.Diagnostics;
+using static UnityEngine.Random;
namespace RogueLibsCore
{
@@ -75,10 +77,17 @@ public static IEnumerable StatusEffects_AddStatusEffect(IEnumer
private static readonly FieldInfo StatusEffect_causingAgent = typeof(StatusEffect).GetField(nameof(StatusEffect.causingAgent));
public static void SetupEffectHook(StatusEffect effect, StatusEffects parent)
{
+ bool debug = RogueFramework.IsDebugEnabled(DebugFlags.Effects);
effect.__RogueLibsContainer = parent;
foreach (IHookFactory factory in RogueFramework.EffectFactories)
if (factory.TryCreate(effect, out IHook hook))
{
+ if (debug)
+ {
+ if (hook is CustomEffect)
+ RogueFramework.LogDebug($"Initializing custom effect {hook} ({effect.statusEffectName}, {parent.agent.agentName}).");
+ else RogueFramework.LogDebug($"Initializing effect hook {hook} ({effect.statusEffectName}, {parent.agent.agentName}).");
+ }
effect.AddHook(hook);
hook.Initialize();
}
@@ -86,8 +95,11 @@ public static void SetupEffectHook(StatusEffect effect, StatusEffects parent)
public static void RefreshEffect(StatusEffect effect, int newTime)
{
CustomEffect custom = effect.GetHook();
+ float oldTime = effect.curTime;
if (custom is null) effect.curTime = newTime;
else custom.OnRefreshed();
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Effects))
+ RogueFramework.LogDebug($"Refreshed {custom} ({effect.statusEffectName}, {effect.GetStatusEffects().agent.agentName}): {oldTime} > {effect.curTime}.");
}
public static IEnumerable StatusEffects_AddTrait(IEnumerable codeEnumerable)
@@ -107,11 +119,18 @@ public static IEnumerable StatusEffects_AddTrait(IEnumerable factory in RogueFramework.TraitFactories)
if (factory.TryCreate(trait, out IHook hook))
{
+ if (debug)
+ {
+ if (hook is CustomTrait)
+ RogueFramework.LogDebug($"Initializing custom trait {hook} ({trait.traitName}, {parent.agent.agentName}).");
+ else RogueFramework.LogDebug($"Initializing trait hook {hook} ({trait.traitName}, {parent.agent.agentName}).");
+ }
trait.AddHook(hook);
hook.Initialize();
any = true;
@@ -129,6 +148,8 @@ public static void StatusEffects_RemoveTrait_Prefix(StatusEffects __instance, st
public static void StatusEffects_RemoveTrait(Trait __state)
{
CustomTrait trait = __state?.GetHook();
+ if (__state != null && RogueFramework.IsDebugEnabled(DebugFlags.Traits))
+ RogueFramework.LogDebug($"Removing trait {trait} ({__state.traitName}, {__state.GetStatusEffects().agent.agentName}).");
trait?.OnRemoved();
}
@@ -137,6 +158,8 @@ public static void StatusEffects_RemoveStatusEffect_Prefix(StatusEffects __insta
public static void StatusEffects_RemoveStatusEffect(StatusEffect __state)
{
CustomEffect effect = __state?.GetHook();
+ if (__state != null && RogueFramework.IsDebugEnabled(DebugFlags.Effects))
+ RogueFramework.LogDebug($"Removing effect {effect} ({__state.statusEffectName}, {__state.GetStatusEffects().agent.agentName}).");
effect?.OnRemoved();
}
@@ -191,6 +214,8 @@ public static bool StatusEffects_UpdateStatusEffect(StatusEffects __instance, St
{
CustomEffect custom = myStatusEffect.GetHook();
if (custom is null) return true;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Effects))
+ RogueFramework.LogDebug($"Starting {custom} update coroutine ({myStatusEffect.statusEffectName}, {myStatusEffect.GetStatusEffects().agent.agentName}).");
__result = StatusEffectUpdateEnumerator(__instance, custom, showTextOnRemoval);
return false;
}
@@ -241,6 +266,8 @@ public static bool StatusEffects_UpdateTrait(StatusEffects __instance, Trait myT
{
CustomTrait custom = myTrait.GetHook();
if (custom is null) return true;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Effects))
+ RogueFramework.LogDebug($"Starting {custom} update coroutine ({myTrait.traitName}, {myTrait.GetStatusEffects().agent.agentName}).");
__result = TraitUpdateEnumerator(__instance, custom);
return false;
}
diff --git a/RogueLibsCore/Patches/Patches_Unlocks.cs b/RogueLibsCore/Patches/Patches_Unlocks.cs
index 5372a0651..2fb74fd5d 100644
--- a/RogueLibsCore/Patches/Patches_Unlocks.cs
+++ b/RogueLibsCore/Patches/Patches_Unlocks.cs
@@ -49,6 +49,8 @@ public static void Unlocks_AddUnlock(Unlock createdUnlock, Unlock __result)
private static void UnlocksClearHelper(bool dontClear)
{
if (dontClear) return;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Unlocks))
+ RogueFramework.LogDebug("Reloading unlocks.");
RogueFramework.Unlocks.Clear();
}
public static IEnumerable Unlocks_LoadInitialUnlocks(IEnumerable codeEnumerable)
@@ -81,56 +83,56 @@ public static void LoadUnlockWrappersAndCategorize()
foreach (Unlock unlock in sdb.unlocks.ToList())
{
// wrapping original unlocks
- if (gc.unlocks.GetSpecialUnlockInfo(unlock.unlockName, unlock) != "") unlock.cost = -2;
- UnlockWrapper wrapper = RogueFramework.CustomUnlocks.Find(u => u.Name == unlock.unlockName && u.Type == unlock.unlockType);
- if (wrapper != null)
- AddUnlockFull(wrapper);
+ if (gc.unlocks.GetSpecialUnlockInfo(unlock.unlockName, unlock) != "")
+ {
+ unlock.cost = -2;
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Unlocks))
+ RogueFramework.LogDebug($"\"{unlock.unlockName}\" ({unlock.unlockType}) has special unlock conditions.");
+ }
+
+ UnlockWrapper wrapper;
+ if (unlock.unlockType == "Challenge")
+ {
+ unlock.unavailable = false;
+ wrapper = new MutatorUnlock(unlock);
+ }
+ else if (unlock.unlockType == "Item")
+ {
+ if (!unlock.unavailable && !unlock.onlyInCharacterCreation && !unlock.freeItem)
+ unlock.onlyInCharacterCreation = unlock.freeItem = true;
+ wrapper = new ItemUnlock(unlock);
+ }
+ else if (unlock.unlockType == "Trait")
+ {
+ unlock.onlyInCharacterCreation = !unlock.unavailable;
+ wrapper = new TraitUnlock(unlock);
+ }
+ else if (unlock.unlockType == "Ability")
+ {
+ unlock.onlyInCharacterCreation = !unlock.unavailable;
+ wrapper = new AbilityUnlock(unlock);
+ }
+ else if (unlock.unlockType == "Achievement") wrapper = new AchievementUnlock(unlock);
+ else if (unlock.unlockType == "Floor") wrapper = new FloorUnlock(unlock);
+ else if (unlock.unlockType == "BigQuest") wrapper = new BigQuestUnlock(unlock);
+ else if (unlock.unlockType == "HomeBase") wrapper = new HomeBaseUnlock(unlock);
+ else if (unlock.unlockType == "Extra") wrapper = new ExtraUnlock(unlock);
+ else if (unlock.unlockType == "Agent") wrapper = new AgentUnlock(unlock);
+ else if (unlock.unlockType == "Loadout") wrapper = new LoadoutUnlock(unlock);
else
{
- if (unlock.unlockType == "Challenge")
- {
- unlock.unavailable = false;
- wrapper = new MutatorUnlock(unlock);
- }
- else if (unlock.unlockType == "Item")
- {
- if (!unlock.unavailable && !unlock.onlyInCharacterCreation && !unlock.freeItem)
- unlock.onlyInCharacterCreation = unlock.freeItem = true;
- wrapper = new ItemUnlock(unlock);
- }
- else if (unlock.unlockType == "Trait")
- {
- unlock.onlyInCharacterCreation = !unlock.unavailable;
- wrapper = new TraitUnlock(unlock);
- }
- else if (unlock.unlockType == "Ability")
- {
- unlock.onlyInCharacterCreation = !unlock.unavailable;
- wrapper = new AbilityUnlock(unlock);
- }
- else if (unlock.unlockType == "Achievement") wrapper = new AchievementUnlock(unlock);
- else if (unlock.unlockType == "Floor") wrapper = new FloorUnlock(unlock);
- else if (unlock.unlockType == "BigQuest") wrapper = new BigQuestUnlock(unlock);
- else if (unlock.unlockType == "HomeBase") wrapper = new HomeBaseUnlock(unlock);
- else if (unlock.unlockType == "Extra") wrapper = new ExtraUnlock(unlock);
- else if (unlock.unlockType == "Agent") wrapper = new AgentUnlock(unlock);
- else if (unlock.unlockType == "Loadout") wrapper = new LoadoutUnlock(unlock);
- else
- {
- RogueFramework.Logger.LogError("Unknown unlock type!\n" +
- $"unlockName: {unlock.unlockName}\n" +
- $"unlockType: {unlock.unlockType}\n" +
- $"unlocked: {unlock.unlocked}");
- sdb.unlocks.Remove(unlock);
- continue;
- }
- if (wrapper is IUnlockInCC inCC && !inCC.IsAvailableInCC) inCC.IsAvailableInCC = wrapper.IsAvailable;
- RogueFramework.Unlocks.Add(wrapper);
- AddUnlockFull(wrapper, true);
+ RogueFramework.LogError($"Unknown unlock type \"{unlock.unlockName}\" ({unlock.unlockType})");
+ sdb.unlocks.Remove(unlock);
+ continue;
}
+ if (wrapper is IUnlockInCC inCC && !inCC.IsAvailableInCC) inCC.IsAvailableInCC = wrapper.IsAvailable;
+ RogueFramework.Unlocks.Add(wrapper);
+ AddUnlockFull(wrapper, true);
}
foreach (UnlockWrapper wrapper in RogueFramework.CustomUnlocks)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Unlocks))
+ RogueFramework.LogDebug($"Initializing custom unlock \"{wrapper.Name}\" ({wrapper.Type}).");
RogueFramework.Unlocks.Add(wrapper);
AddUnlockFull(wrapper);
}
@@ -143,9 +145,13 @@ public static void AddUnlockFull(UnlockWrapper wrapper, bool alreadyLoaded = fal
Unlock result = alreadyLoaded ? wrapper.Unlock : GameController.gameController.unlocks.AddUnlock(wrapper.Unlock);
if (wrapper.Unlock != result)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Unlocks))
+ RogueFramework.LogDebug($"Loaded state for \"{wrapper.Name}\" ({wrapper.Type}): unlocked - {result.unlocked}, enabled - {!result.notActive}");
+
List list = GameController.gameController.sessionDataBig.unlocks;
list.Remove(result);
list.Add(wrapper.Unlock);
+
wrapper.IsUnlocked = result.unlocked;
if (!(wrapper is MutatorUnlock))
wrapper.IsEnabled = !result.notActive;
@@ -158,7 +164,7 @@ public static void AddUnlockFull(UnlockWrapper wrapper, bool alreadyLoaded = fal
}
catch (Exception e)
{
- RogueFramework.Logger.LogError($"An error setting up {wrapper.Unlock?.unlockName} ({wrapper.Unlock?.unlockType}) unlock.");
+ RogueFramework.Logger.LogError($"Error setting up {wrapper.Unlock?.unlockName} ({wrapper.Unlock?.unlockType}) unlock.");
RogueFramework.Logger.LogError(e);
}
}
@@ -614,6 +620,9 @@ public static class UnlocksExtensions
public static bool AllowUnlocksAnyway { get; set; }
public static void DoUnlockForced(this Unlocks unlocks, string unlockName, string unlockType)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Unlocks))
+ RogueFramework.LogDebug($"Force-unlocking \"{unlockName}\" ({unlockType})");
+
bool prev = AllowUnlocksAnyway;
AllowUnlocksAnyway = true;
unlocks.DoUnlock(unlockName, unlockType);
diff --git a/RogueLibsCore/Properties/AssemblyInfo.cs b/RogueLibsCore/Properties/AssemblyInfo.cs
index 659bce143..950198b4f 100644
--- a/RogueLibsCore/Properties/AssemblyInfo.cs
+++ b/RogueLibsCore/Properties/AssemblyInfo.cs
@@ -5,21 +5,26 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("RogueLibs")]
+[assembly: AssemblyTitle("RogueLibsCore")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("RogueLibs")]
-[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyCompany("Abbysssal")]
+[assembly: AssemblyProduct("RogueLibsCore")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#elif RELEASE
+[assembly: AssemblyConfiguration("Release")]
+#else
+[assembly: AssemblyConfiguration("")]
+#endif
+
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: InternalsVisibleTo("RogueLibsCore.Test")]
+
[assembly: Guid("43a221f2-a56c-4f59-8c3c-828de75259c4")]
// Version information for an assembly consists of the following four values:
@@ -32,5 +37,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion(RogueLibsCore.RogueLibs.AssemblyVersion)]
+[assembly: AssemblyFileVersion(RogueLibsCore.RogueLibs.AssemblyVersion)]
diff --git a/RogueLibsCore/RogueFramework.cs b/RogueLibsCore/RogueFramework.cs
index 70ed9393c..8bad5295e 100644
--- a/RogueLibsCore/RogueFramework.cs
+++ b/RogueLibsCore/RogueFramework.cs
@@ -10,13 +10,42 @@ public static class RogueFramework
public static RogueLibsPlugin Plugin { get; internal set; }
internal static ManualLogSource Logger { get; set; }
- public static DebugFlags Debug { get; set; }
+ public static bool Debug { get; set; }
+ public static DebugFlags DebugFlags { get; set; }
#if DEBUG
- = DebugFlags.All;
+ = DebugFlags.EnableTools | DebugFlags.Abilities | DebugFlags.Unlocks;
#endif
- public static bool IsDebugEnabled(DebugFlags flags) => (Debug & flags) == flags;
- public static void LogDebug(string message) => Logger.LogDebug(message);
+ public static bool IsDebugEnabled(DebugFlags flags) => (DebugFlags & flags) == flags;
+
+ internal static void LogDebug(string message) => Logger.LogDebug(message);
+ internal static void LogWarning(string message) => Logger.LogWarning(message);
+ internal static void LogError(string message) => Logger.LogError(message);
+ internal static void LogError(Exception e, string methodName, object hookObj, object container = null)
+ {
+ IHook hook = (IHook)hookObj;
+ object instance = hook.Instance;
+
+ string instanceName = instance is InvItem item ? item.invItemName
+ : instance is StatusEffect effect ? effect.statusEffectName
+ : instance is Trait trait ? trait.traitName
+ : instance is Agent agent ? agent.agentName
+ : instance is ObjectReal objectReal ? objectReal.objectName
+ : instance is UnlockWrapper wrapper ? $"{wrapper.Name} ({wrapper.Type})"
+ : instance.ToString();
+
+ string containerName = container is null ? string.Empty
+ : ", " + (
+ container is Item ? "on the ground"
+ : container is Agent a ? a.agentName
+ : container is ObjectReal o ? o.objectName
+ : container is UnlocksMenu m ? m.Type.ToString()
+ : container.ToString()
+ );
+
+ Logger.LogError($"{methodName} error in {hookObj} ({instanceName}{containerName})");
+ Logger.LogError(e);
+ }
public static readonly List> ItemFactories = new List>();
public static readonly List> TraitFactories = new List>();
diff --git a/RogueLibsCore/RogueLibs.cs b/RogueLibsCore/RogueLibs.cs
index 6966e3846..a6caedca2 100644
--- a/RogueLibsCore/RogueLibs.cs
+++ b/RogueLibsCore/RogueLibs.cs
@@ -20,8 +20,13 @@ static RogueLibs()
public const string GUID = "abbysssal.streetsofrogue.roguelibscore";
public const string Name = "RogueLibsCore";
- public static string Version { [MethodImpl(MethodImplOptions.NoInlining)] get => CompiledVersion; }
+
public const string CompiledVersion = "3.0";
+ public const string CompiledSemanticVersion = "3.0.0-beta.8";
+ internal const string AssemblyVersion = "3.0.0.0";
+
+ public static string Version { [MethodImpl(MethodImplOptions.NoInlining)] get => CompiledVersion; }
+ public static string SemanticVersion { [MethodImpl(MethodImplOptions.NoInlining)] get => CompiledSemanticVersion; }
private static readonly CustomItemFactory ItemFactory = new CustomItemFactory();
private static readonly CustomTraitFactory TraitFactory = new CustomTraitFactory();
@@ -34,6 +39,12 @@ public static ItemBuilder CreateCustomItem()
ItemInfo info = ItemFactory.AddItem();
return new ItemBuilder(info);
}
+ public static AbilityBuilder CreateCustomAbility()
+ where TAbility : CustomAbility, new()
+ {
+ ItemInfo info = ItemFactory.AddItem();
+ return new AbilityBuilder(info);
+ }
public static TraitBuilder CreateCustomTrait()
where TTrait : CustomTrait, new()
{
@@ -129,6 +140,45 @@ public ItemBuilder WithUnlock(ItemUnlock unlock)
return this;
}
}
+ public class AbilityBuilder
+ {
+ public AbilityBuilder(ItemInfo info) => Info = info;
+ public ItemInfo Info { get; }
+
+ public CustomName Name { get; private set; }
+ public CustomName Description { get; private set; }
+ public RogueSprite Sprite { get; private set; }
+ public AbilityUnlock Unlock { get; private set; }
+
+ public AbilityBuilder WithName(CustomNameInfo name)
+ {
+ Name = RogueLibs.CreateCustomName(Info.Name, "Item", name);
+ return this;
+ }
+ public AbilityBuilder WithDescription(CustomNameInfo description)
+ {
+ Description = RogueLibs.CreateCustomName(Info.Name, "Description", description);
+ return this;
+ }
+ public AbilityBuilder WithSprite(byte[] rawData, float ppu = 64f)
+ {
+ Sprite = RogueLibs.CreateCustomSprite(Info.Name, SpriteScope.Items, rawData, ppu);
+ return this;
+ }
+ public AbilityBuilder WithSprite(byte[] rawData, Rect region, float ppu = 64f)
+ {
+ Sprite = RogueLibs.CreateCustomSprite(Info.Name, SpriteScope.Items, rawData, region, ppu);
+ return this;
+ }
+ public AbilityBuilder WithUnlock() => WithUnlock(new AbilityUnlock(Info.Name, true));
+ public AbilityBuilder WithUnlock(AbilityUnlock unlock)
+ {
+ unlock.Name = Info.Name;
+ RogueLibs.CreateCustomUnlock(unlock);
+ Unlock = unlock;
+ return this;
+ }
+ }
public class TraitBuilder
{
public TraitBuilder(TraitInfo info) => Info = info;
diff --git a/RogueLibsCore/RogueLibsPlugin.cs b/RogueLibsCore/RogueLibsPlugin.cs
index e0fbd1f61..09e04e88f 100644
--- a/RogueLibsCore/RogueLibsPlugin.cs
+++ b/RogueLibsCore/RogueLibsPlugin.cs
@@ -16,6 +16,7 @@ public sealed partial class RogueLibsPlugin : BaseUnityPlugin
public RoguePatcher Patcher;
public void Awake()
{
+ Logger.LogInfo($"Running RogueLibs v{RogueLibs.CompiledSemanticVersion}.");
Stopwatch sw = new Stopwatch();
sw.Start();
diff --git a/RogueLibsCore/RogueSprite.cs b/RogueLibsCore/RogueSprite.cs
index 5ef344dfd..b11c0097c 100644
--- a/RogueLibsCore/RogueSprite.cs
+++ b/RogueLibsCore/RogueSprite.cs
@@ -115,11 +115,16 @@ private Sprite CreateSprite()
internal static void DefinePrepared(tk2dSpriteCollectionData collection, SpriteScope scope)
{
if (prepared.TryGetValue(scope, out List sprites))
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Sprites))
+ RogueFramework.LogDebug($"Initializing ${sprites.Count} prepared sprites in scope {scope}:");
+
foreach (RogueSprite sprite in sprites)
{
sprite.isPrepared = false;
- sprite.Define(collection, scope);
+ sprite.DefineInternal(collection, scope);
}
+ }
}
internal RogueSprite(string spriteName, SpriteScope spriteScope, byte[] rawData, Rect? spriteRegion, float ppu = 64f)
@@ -154,34 +159,44 @@ public void Define()
DefineScope(Scope & SpriteScope.Items);
DefineScope(Scope & SpriteScope.Objects);
DefineScope(Scope & SpriteScope.Floors);
+ DefineScope(Scope & SpriteScope.Extra);
}
private void DefineScope(SpriteScope scope)
{
if (scope == SpriteScope.None) return;
tk2dSpriteCollectionData coll = GetCollection(scope);
- if (coll is null)
+ if (coll is null && scope != SpriteScope.Extra)
{
+ isPrepared = true;
if (prepared.TryGetValue(scope, out List sprites))
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Sprites))
+ RogueFramework.LogDebug($"Prepared sprite \"{Name}\" for initialization.");
sprites.Add(this);
- isPrepared = true;
+ }
+ else RogueFramework.LogError($"Pseudo-prepared sprite \"{Name}\" for initialization.");
}
- else Define(coll, scope);
+ else DefineInternal(coll, scope);
}
internal Material Material { get; private set; }
internal Material LightUpMaterial { get; private set; }
- internal void Define(tk2dSpriteCollectionData coll, SpriteScope scope)
+ internal void DefineInternal(tk2dSpriteCollectionData coll, SpriteScope scope)
{
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Sprites))
+ RogueFramework.LogDebug($"Defining \"{Name}\" sprite in scope {scope}.");
+
if (coll != null)
{
tk2dSpriteDefinition def = AddDefinition(coll, texture, region);
def.__RogueLibsCustom = this;
- definitions.Add(new CustomTk2dDefinition(coll, def));
+ definitions.Add(new CustomTk2dDefinition(coll, def, scope));
if (Material is null) Material = def.material;
if (LightUpMaterial is null) LightUpMaterial = UnityEngine.Object.Instantiate(Material);
LightUpMaterial.shader = GameController.gameController.lightUpShader;
}
+ else definitions.Add(new CustomTk2dDefinition(null, null, scope));
GameResources gr = GameResources.gameResources;
@@ -194,23 +209,31 @@ public void Undefine()
{
if (isPrepared)
{
+ isPrepared = false;
if (prepared.TryGetValue(Scope, out List list))
list.Remove(this);
- isPrepared = false;
+ else RogueFramework.LogWarning($"Undefined a pseudo-prepared sprite \"{Name}\".");
return;
}
if (!IsDefined) return;
foreach (CustomTk2dDefinition def in definitions)
- RemoveDefinition(def.Collection, def.Definition);
+ UndefineInternal(def);
definitions = null;
+ }
+ private void UndefineInternal(CustomTk2dDefinition def)
+ {
+ if (RogueFramework.IsDebugEnabled(DebugFlags.Sprites))
+ RogueFramework.LogDebug($"Undefining sprite \"{Name}\" from scope {def.Scope}.");
- GameResources gr = GameResources.gameResources;
+ if (def.Collection != null)
+ RemoveDefinition(def.Collection, def.Definition);
+ GameResources gr = GameResources.gameResources;
if (Scope == SpriteScope.Items) { gr.itemDic.Remove(Name); gr.itemList.Remove(Sprite); }
- else if (Scope == SpriteScope.Objects) { gr.objectDic.Remove(Name); gr.objectList.Remove(Sprite); }
- else if (Scope == SpriteScope.Floors) { gr.floorDic.Remove(Name); gr.floorList.Remove(Sprite); }
- else if (Scope == SpriteScope.Extra) RogueFramework.ExtraSprites.Remove(Name);
+ if (Scope == SpriteScope.Objects) { gr.objectDic.Remove(Name); gr.objectList.Remove(Sprite); }
+ if (Scope == SpriteScope.Floors) { gr.floorDic.Remove(Name); gr.floorList.Remove(Sprite); }
+ if (Scope == SpriteScope.Extra) RogueFramework.ExtraSprites.Remove(Name);
}
public static tk2dSpriteDefinition CreateDefinition(Texture2D texture, Rect? region, float scale)
@@ -317,13 +340,15 @@ private static void RemoveDefinition(tk2dSpriteCollectionData coll, tk2dSpriteDe
public class CustomTk2dDefinition
{
- internal CustomTk2dDefinition(tk2dSpriteCollectionData collection, tk2dSpriteDefinition definition)
+ internal CustomTk2dDefinition(tk2dSpriteCollectionData collection, tk2dSpriteDefinition definition, SpriteScope scope)
{
Collection = collection;
Definition = definition;
+ Scope = scope;
}
public tk2dSpriteCollectionData Collection { get; }
public tk2dSpriteDefinition Definition { get; }
+ public SpriteScope Scope { get; }
}
}
[Flags]
@@ -335,6 +360,6 @@ public enum SpriteScope
Items = 1 << 0,
Objects = 1 << 1,
- Floors = 1 << 2
+ Floors = 1 << 2,
}
}
diff --git a/RogueLibsCore/Utilities/RoguePatcher.cs b/RogueLibsCore/Utilities/RoguePatcher.cs
index 5a97c90af..7168758e5 100644
--- a/RogueLibsCore/Utilities/RoguePatcher.cs
+++ b/RogueLibsCore/Utilities/RoguePatcher.cs
@@ -52,10 +52,12 @@ public void LogResults()
$" | {time.Elapsed.TotalMilliseconds,4:####}ms |");
total += time.Elapsed;
}
- log.LogDebug($"Total: {total,5:#####}ms");
+ log.LogDebug($"Total: {total.TotalMilliseconds,5:#####}ms");
}
- private static readonly BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
+ private const BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
+ private static MethodInfo GetMethod(Type type, string methodName, Type[] parameterTypes)
+ => parameterTypes is null ? type.GetMethod(methodName, All) : type.GetMethod(methodName, All, null, parameterTypes, null);
public bool Prefix(Type targetType, string targetMethod, Type[] targetParameterTypes = null)
{
@@ -75,9 +77,9 @@ public bool Prefix(Type targetType, string targetMethod, string patchMethod, Typ
{
sw = new Stopwatch();
sw.Start();
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, new HarmonyMethod(patch));
sw.Stop();
@@ -86,9 +88,9 @@ public bool Prefix(Type targetType, string targetMethod, string patchMethod, Typ
}
else
{
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, new HarmonyMethod(patch));
}
@@ -120,9 +122,9 @@ public bool Postfix(Type targetType, string targetMethod, string patchMethod, Ty
{
sw = new Stopwatch();
sw.Start();
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, new HarmonyMethod(patch));
sw.Stop();
@@ -131,9 +133,9 @@ public bool Postfix(Type targetType, string targetMethod, string patchMethod, Ty
}
else
{
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, new HarmonyMethod(patch));
}
@@ -165,9 +167,9 @@ public bool Transpiler(Type targetType, string targetMethod, string patchMethod,
{
sw = new Stopwatch();
sw.Start();
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, null, new HarmonyMethod(patch));
sw.Stop();
@@ -176,9 +178,9 @@ public bool Transpiler(Type targetType, string targetMethod, string patchMethod,
}
else
{
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, null, new HarmonyMethod(patch));
}
@@ -210,9 +212,9 @@ public bool Finalizer(Type targetType, string targetMethod, string patchMethod,
{
sw = new Stopwatch();
sw.Start();
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, null, null, new HarmonyMethod(patch));
sw.Stop();
@@ -221,9 +223,9 @@ public bool Finalizer(Type targetType, string targetMethod, string patchMethod,
}
else
{
- MethodInfo target = targetType.GetMethod(targetMethod, All, null, targetParameterTypes, null)
+ MethodInfo target = GetMethod(targetType, targetMethod, targetParameterTypes)
?? throw new MemberNotFoundException($"Target method {targetType.FullName}.{targetMethod} could not be found.");
- MethodInfo patch = TypeWithPatches.GetMethod(patchMethod, All)
+ MethodInfo patch = GetMethod(TypeWithPatches, patchMethod, null)
?? throw new MemberNotFoundException($"Patch method {TypeWithPatches.FullName}.{patchMethod} could not be found.");
harmony.Patch(target, null, null, null, new HarmonyMethod(patch));
}