using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using EasyFall.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EasyFall")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EasyFall")]
[assembly: AssemblyTitle("EasyFall")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace EasyFall
{
public class ModMenu : MonoBehaviour
{
private bool _visible;
private Rect _windowRect = new Rect(10f, 10f, 340f, 580f);
private bool _isResizing;
private Vector2 _scrollPos;
public bool InstantWaveSpawn;
public bool AutoStartNextWave;
public float PlayerUnitHpMultiplier = 1f;
public float PlayerUnitDamageMultiplier = 1f;
public float PlayerUnitAttackSpeedMultiplier = 1f;
public float PlayerUnitMoveSpeedMultiplier = 1f;
public float PlayerMoveSpeedMultiplier = 1f;
public float PlayerHpMultiplier = 1f;
public float PlayerDamageMultiplier = 1f;
public float PlayerAttackSpeedMultiplier = 1f;
public bool PlayerRandomTarget;
public float TowerHpMultiplier = 1f;
public float TowerDamageMultiplier = 1f;
public float TowerAttackSpeedMultiplier = 1f;
public int CoinsToSpawn;
private string _playerHpText = "1";
private string _playerDmgText = "1";
private string _playerAtkSpdText = "1";
private string _playerMoveSpdText = "1";
private string _playerCharMoveSpdText = "1";
private string _playerCharHpText = "1";
private string _playerCharDmgText = "1";
private string _playerCharAtkSpdText = "1";
private string _towerHpText = "1";
private string _towerDmgText = "1";
private string _towerAtkSpdText = "1";
private string _coinsText = "0";
private float _prevPlayerHp = 1f;
private float _prevPlayerDmg = 1f;
private float _prevPlayerAtkSpd = 1f;
private float _prevPlayerMoveSpd = 1f;
private float _prevPlayerCharMoveSpd = 1f;
private float _prevPlayerCharHp = 1f;
private float _prevPlayerCharDmg = 1f;
private float _prevPlayerCharAtkSpd = 1f;
private static GUIStyle _richStyle;
public bool PlayerStatsChanged { get; private set; }
public bool PlayerCharStatsChanged { get; private set; }
public bool SpawnCoinsRequested { get; set; }
public static ModMenu Instance { get; private set; }
private static GUIStyle RichStyle
{
get
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
object obj = _richStyle;
if (obj == null)
{
GUIStyle val = new GUIStyle(GUI.skin.label)
{
richText = true
};
_richStyle = val;
obj = (object)val;
}
return (GUIStyle)obj;
}
}
private void Awake()
{
Instance = this;
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)286))
{
_visible = !_visible;
}
PlayerStatsChanged = false;
if (PlayerUnitHpMultiplier != _prevPlayerHp || PlayerUnitDamageMultiplier != _prevPlayerDmg || PlayerUnitAttackSpeedMultiplier != _prevPlayerAtkSpd || PlayerUnitMoveSpeedMultiplier != _prevPlayerMoveSpd)
{
PlayerStatsChanged = true;
_prevPlayerHp = PlayerUnitHpMultiplier;
_prevPlayerDmg = PlayerUnitDamageMultiplier;
_prevPlayerAtkSpd = PlayerUnitAttackSpeedMultiplier;
_prevPlayerMoveSpd = PlayerUnitMoveSpeedMultiplier;
}
PlayerCharStatsChanged = false;
if (PlayerMoveSpeedMultiplier != _prevPlayerCharMoveSpd || PlayerHpMultiplier != _prevPlayerCharHp || PlayerDamageMultiplier != _prevPlayerCharDmg || PlayerAttackSpeedMultiplier != _prevPlayerCharAtkSpd)
{
PlayerCharStatsChanged = true;
_prevPlayerCharMoveSpd = PlayerMoveSpeedMultiplier;
_prevPlayerCharHp = PlayerHpMultiplier;
_prevPlayerCharDmg = PlayerDamageMultiplier;
_prevPlayerCharAtkSpd = PlayerAttackSpeedMultiplier;
}
}
private void OnGUI()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (_visible)
{
_windowRect = GUILayout.Window(948201, _windowRect, new WindowFunction(DrawWindow), "EasyFall", Array.Empty<GUILayoutOption>());
}
}
private void DrawWindow(int id)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0415: Unknown result type (might be due to invalid IL or missing references)
if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 22f, 2f, 20f, 20f), "X"))
{
_visible = false;
}
_scrollPos = GUILayout.BeginScrollView(_scrollPos, Array.Empty<GUILayoutOption>());
GUILayout.Label("<b>Wave Spawning</b>", RichStyle, Array.Empty<GUILayoutOption>());
InstantWaveSpawn = GUILayout.Toggle(InstantWaveSpawn, " Spawn all enemies instantly", Array.Empty<GUILayoutOption>());
AutoStartNextWave = GUILayout.Toggle(AutoStartNextWave, " Auto start next wave", Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
GUILayout.Label("<b>Player Character</b>", RichStyle, Array.Empty<GUILayoutOption>());
DrawMultiplierField("HP:", ref _playerCharHpText, ref PlayerHpMultiplier);
DrawMultiplierField("Damage:", ref _playerCharDmgText, ref PlayerDamageMultiplier);
DrawMultiplierField("Attack Speed:", ref _playerCharAtkSpdText, ref PlayerAttackSpeedMultiplier);
DrawMultiplierField("Move Speed:", ref _playerCharMoveSpdText, ref PlayerMoveSpeedMultiplier);
PlayerRandomTarget = GUILayout.Toggle(PlayerRandomTarget, " Random target each attack", Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Reset Player Character Stats", Array.Empty<GUILayoutOption>()))
{
PlayerHpMultiplier = 1f;
_playerCharHpText = "1";
PlayerDamageMultiplier = 1f;
_playerCharDmgText = "1";
PlayerAttackSpeedMultiplier = 1f;
_playerCharAtkSpdText = "1";
PlayerMoveSpeedMultiplier = 1f;
_playerCharMoveSpdText = "1";
PlayerRandomTarget = false;
}
GUILayout.Space(10f);
GUILayout.Label("<b>Player Unit Stats</b>", RichStyle, Array.Empty<GUILayoutOption>());
DrawMultiplierField("HP:", ref _playerHpText, ref PlayerUnitHpMultiplier);
DrawMultiplierField("Damage:", ref _playerDmgText, ref PlayerUnitDamageMultiplier);
DrawMultiplierField("Attack Speed:", ref _playerAtkSpdText, ref PlayerUnitAttackSpeedMultiplier);
DrawMultiplierField("Move Speed:", ref _playerMoveSpdText, ref PlayerUnitMoveSpeedMultiplier);
if (GUILayout.Button("Reset Player Unit Stats", Array.Empty<GUILayoutOption>()))
{
PlayerUnitHpMultiplier = 1f;
_playerHpText = "1";
PlayerUnitDamageMultiplier = 1f;
_playerDmgText = "1";
PlayerUnitAttackSpeedMultiplier = 1f;
_playerAtkSpdText = "1";
PlayerUnitMoveSpeedMultiplier = 1f;
_playerMoveSpdText = "1";
}
GUILayout.Space(10f);
GUILayout.Label("<b>Tower Stats</b>", RichStyle, Array.Empty<GUILayoutOption>());
DrawMultiplierField("HP:", ref _towerHpText, ref TowerHpMultiplier);
DrawMultiplierField("Damage:", ref _towerDmgText, ref TowerDamageMultiplier);
DrawMultiplierField("Attack Speed:", ref _towerAtkSpdText, ref TowerAttackSpeedMultiplier);
if (GUILayout.Button("Reset Tower Stats", Array.Empty<GUILayoutOption>()))
{
TowerHpMultiplier = 1f;
_towerHpText = "1";
TowerDamageMultiplier = 1f;
_towerDmgText = "1";
TowerAttackSpeedMultiplier = 1f;
_towerAtkSpdText = "1";
}
GUILayout.Space(10f);
GUILayout.Label("<b>Coins</b>", RichStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Amount:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
_coinsText = GUILayout.TextField(_coinsText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
if (int.TryParse(_coinsText, out var result))
{
CoinsToSpawn = Mathf.Max(0, result);
}
if (GUILayout.Button("Spawn", Array.Empty<GUILayoutOption>()))
{
SpawnCoinsRequested = true;
}
GUILayout.EndHorizontal();
GUILayout.Space(10f);
GUILayout.Label("<i>Drag title to move · Drag corner to resize · F5 to toggle</i>", RichStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndScrollView();
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 20f));
HandleResize();
}
private void DrawMultiplierField(string label, ref string text, ref float value)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
text = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
GUILayout.Label("x", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(14f) });
if (float.TryParse(text, out var result) && result > 0f)
{
value = result;
}
GUILayout.EndHorizontal();
}
private void HandleResize()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Invalid comparison between Unknown and I4
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
Rect val = default(Rect);
((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).width - 16f, ((Rect)(ref _windowRect)).height - 16f, 16f, 16f);
GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(1f, 1f, 1f, 0.3f), 0f, 0f);
Event current = Event.current;
if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
{
_isResizing = true;
}
if (_isResizing)
{
((Rect)(ref _windowRect)).width = Mathf.Max(280f, current.mousePosition.x + 4f);
((Rect)(ref _windowRect)).height = Mathf.Max(300f, current.mousePosition.y + 4f);
}
if ((int)current.type == 1)
{
_isResizing = false;
}
}
}
[BepInPlugin("com.easyfall", "EasyFall", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGUID = "com.easyfall";
public const string PluginName = "EasyFall";
public const string PluginVersion = "0.1.0";
internal static ManualLogSource Logger;
private Harmony _harmony;
private void Awake()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
((Component)this).gameObject.AddComponent<ModMenu>();
Logger.LogInfo((object)"EasyFall v0.1.0 loaded!");
_harmony = new Harmony("com.easyfall");
_harmony.PatchAll();
Logger.LogInfo((object)"All patches applied.");
}
private void Update()
{
if (!((Object)(object)ModMenu.Instance == (Object)null))
{
if (ModMenu.Instance.PlayerStatsChanged)
{
PlayerUnitHpPatch.ReapplyAll();
PlayerUnitAutoAttackPatch.ReapplyAll();
PlayerUnitMoveSpeedPatch.ReapplyAll();
}
if (ModMenu.Instance.PlayerCharStatsChanged)
{
PlayerCharacterMoveSpeedPatch.ReapplyIfNeeded();
PlayerCharacterHpPatch.ReapplyIfNeeded();
PlayerCharacterAttackPatch.ReapplyIfNeeded();
PlayerCharacterDamagePatch.ReapplyIfNeeded();
}
TowerHpPatch.ApplyToAllTowers();
TowerAutoAttackPatch.ApplyToAllTowers();
if (ModMenu.Instance.SpawnCoinsRequested)
{
ModMenu.Instance.SpawnCoinsRequested = false;
SpawnCoins(ModMenu.Instance.CoinsToSpawn);
}
}
}
private void SpawnCoins(int amount)
{
if (amount > 0)
{
if ((Object)(object)PlayerInteraction.instance == (Object)null)
{
Logger.LogWarning((object)"Cannot spawn coins: no PlayerInteraction instance.");
return;
}
PlayerInteraction.instance.AddCoin(amount);
Logger.LogInfo((object)$"Spawned {amount} coins.");
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
}
namespace EasyFall.Patches
{
[HarmonyPatch(typeof(Spawn), "Update")]
public static class SpawnUpdatePatch
{
private static bool Prefix(Spawn __instance)
{
if ((Object)(object)ModMenu.Instance == (Object)null || !ModMenu.Instance.InstantWaveSpawn)
{
return true;
}
__instance.delay = 0f;
__instance.interval = 0f;
__instance.waitBeforeNextSpawn = 0f;
return true;
}
}
[HarmonyPatch(typeof(EnemySpawner), "Update")]
public static class EnemySpawnerUpdatePatch
{
private static readonly FieldRef<EnemySpawner, int> PauseSpawningRef = AccessTools.FieldRefAccess<EnemySpawner, int>("pauseSpawningAtEnemyCount");
private static readonly FieldRef<EnemySpawner, int> WavenumberRef = AccessTools.FieldRefAccess<EnemySpawner, int>("wavenumber");
private static void Prefix(EnemySpawner __instance)
{
if (!((Object)(object)ModMenu.Instance == (Object)null) && ModMenu.Instance.InstantWaveSpawn)
{
PauseSpawningRef.Invoke(__instance) = int.MaxValue;
}
}
private static void Postfix(EnemySpawner __instance)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)ModMenu.Instance == (Object)null) && ModMenu.Instance.AutoStartNextWave && !__instance.SpawningInProgress && !__instance.MatchOver)
{
DayNightCycle instance = DayNightCycle.Instance;
if (!((Object)(object)instance == (Object)null) && (int)instance.CurrentTimestate == 0 && __instance.NumberOfEnemiesOnTheMap <= 0 && WavenumberRef.Invoke(__instance) > 0)
{
instance.SwitchToNight();
}
}
}
}
[HarmonyPatch(typeof(ManualAttack), "FindAttackTarget")]
public static class PlayerRandomTargetPatch
{
private static readonly List<TaggedObject> InRange = new List<TaggedObject>();
private static void Postfix(ManualAttack __instance, ref TaggedObject __result)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)ModMenu.Instance == (Object)null || !ModMenu.Instance.PlayerRandomTarget || (Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> enemyUnits = TagManager.instance.EnemyUnits;
if (enemyUnits == null || enemyUnits.Count == 0)
{
return;
}
float num = (((Object)(object)__instance.weapon != (Object)null) ? __instance.weapon.maximumChaseRange : 0f);
if (num <= 0f)
{
return;
}
float num2 = num * num;
Vector3 position = ((Component)__instance).transform.position;
InRange.Clear();
for (int i = 0; i < enemyUnits.Count; i++)
{
TaggedObject val = enemyUnits[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
Hp hp = val.Hp;
if (!((Object)(object)hp == (Object)null) && hp.Alive)
{
Vector3 val2 = ((Component)val).transform.position - position;
if (((Vector3)(ref val2)).sqrMagnitude <= num2)
{
InRange.Add(val);
}
}
}
if (InRange.Count != 0)
{
__result = InRange[Random.Range(0, InRange.Count)];
}
}
}
internal static class HpFieldAccess
{
public static readonly FieldRef<Hp, float> HpValue = AccessTools.FieldRefAccess<Hp, float>("hp");
public static void SetMaxHpSilent(Hp hp, float newMax)
{
float maxHp = hp.maxHp;
float num = HpValue.Invoke(hp);
float num2 = ((maxHp > 0f) ? (num / maxHp) : 1f);
hp.maxHp = newMax;
HpValue.Invoke(hp) = newMax * num2;
}
public static void ScaleHpSilent(Hp hp, float mult, HashSet<Hp> scaled)
{
float num;
if (scaled.Contains(hp))
{
num = hp.HpOriginal;
}
else
{
num = (hp.HpOriginal = hp.HpOriginal);
scaled.Add(hp);
}
SetMaxHpSilent(hp, num * mult);
}
}
[HarmonyPatch(typeof(Hp), "Start")]
public static class HpStartPatch
{
private static void Postfix(Hp __instance)
{
if ((Object)(object)ModMenu.Instance == (Object)null)
{
return;
}
ModMenu instance = ModMenu.Instance;
if (instance.PlayerUnitHpMultiplier == 1f && instance.PlayerHpMultiplier == 1f && instance.PlayerDamageMultiplier == 1f && instance.TowerHpMultiplier == 1f)
{
return;
}
TaggedObject taggedObj = __instance.TaggedObj;
if ((Object)(object)taggedObj == (Object)null)
{
return;
}
List<ETag> tags = taggedObj.Tags;
if (instance.PlayerUnitHpMultiplier != 1f && tags.Contains((ETag)7))
{
PlayerUnitHpPatch.TryApply(__instance);
}
if (tags.Contains((ETag)2))
{
if (instance.PlayerHpMultiplier != 1f)
{
PlayerCharacterHpPatch.TryApply(__instance);
}
if (instance.PlayerDamageMultiplier != 1f)
{
PlayerCharacterDamagePatch.Apply(__instance);
}
}
if (instance.TowerHpMultiplier != 1f && tags.Contains((ETag)24))
{
TowerHpPatch.TryApply(__instance);
}
}
}
[HarmonyPatch(typeof(AutoAttack), "Start")]
public static class AutoAttackStartPatch
{
private static void Postfix(AutoAttack __instance)
{
if ((Object)(object)ModMenu.Instance == (Object)null)
{
return;
}
ModMenu instance = ModMenu.Instance;
if (instance.PlayerUnitAttackSpeedMultiplier == 1f && instance.PlayerUnitDamageMultiplier == 1f && instance.TowerAttackSpeedMultiplier == 1f && instance.TowerDamageMultiplier == 1f)
{
return;
}
TaggedObject component = ((Component)__instance).GetComponent<TaggedObject>();
if (!((Object)(object)component == (Object)null))
{
List<ETag> tags = component.Tags;
if ((instance.PlayerUnitAttackSpeedMultiplier != 1f || instance.PlayerUnitDamageMultiplier != 1f) && tags.Contains((ETag)7))
{
PlayerUnitAutoAttackPatch.TryApply(__instance);
}
if ((instance.TowerAttackSpeedMultiplier != 1f || instance.TowerDamageMultiplier != 1f) && tags.Contains((ETag)24))
{
TowerAutoAttackPatch.TryApply(__instance);
}
}
}
}
public static class PlayerUnitHpPatch
{
private static readonly HashSet<Hp> Scaled = new HashSet<Hp>();
public static void TryApply(Hp hp)
{
float playerUnitHpMultiplier = ModMenu.Instance.PlayerUnitHpMultiplier;
if (playerUnitHpMultiplier != 1f || Scaled.Contains(hp))
{
HpFieldAccess.ScaleHpSilent(hp, playerUnitHpMultiplier, Scaled);
}
}
public static void ReapplyAll()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> playerUnits = TagManager.instance.PlayerUnits;
for (int i = 0; i < playerUnits.Count; i++)
{
Hp component = ((Component)playerUnits[i]).GetComponent<Hp>();
if ((Object)(object)component != (Object)null)
{
TryApply(component);
}
}
}
}
public static class PlayerUnitAutoAttackPatch
{
private static readonly Dictionary<AutoAttack, float> OriginalCooldowns = new Dictionary<AutoAttack, float>();
public static void TryApply(AutoAttack atk)
{
if (!OriginalCooldowns.ContainsKey(atk))
{
OriginalCooldowns[atk] = atk.cooldownDuration;
}
float num = OriginalCooldowns[atk];
atk.cooldownDuration = num / ModMenu.Instance.PlayerUnitAttackSpeedMultiplier;
atk.DamageMultiplyer = ModMenu.Instance.PlayerUnitDamageMultiplier;
}
public static void ReapplyAll()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> playerUnits = TagManager.instance.PlayerUnits;
for (int i = 0; i < playerUnits.Count; i++)
{
AutoAttack[] components = ((Component)playerUnits[i]).GetComponents<AutoAttack>();
for (int j = 0; j < components.Length; j++)
{
TryApply(components[j]);
}
}
}
}
[HarmonyPatch(typeof(PathfindMovementPlayerunit), "Start")]
public static class PlayerUnitMoveSpeedPatch
{
private static readonly Dictionary<PathfindMovementPlayerunit, float> OriginalSpeeds = new Dictionary<PathfindMovementPlayerunit, float>();
private static void Postfix(PathfindMovementPlayerunit __instance)
{
if (!((Object)(object)ModMenu.Instance == (Object)null) && ModMenu.Instance.PlayerUnitMoveSpeedMultiplier != 1f)
{
TryApply(__instance);
}
}
public static void TryApply(PathfindMovementPlayerunit mov)
{
if (!OriginalSpeeds.ContainsKey(mov))
{
OriginalSpeeds[mov] = mov.movementSpeed;
}
mov.movementSpeed = OriginalSpeeds[mov] * ModMenu.Instance.PlayerUnitMoveSpeedMultiplier;
}
public static void ReapplyAll()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> playerUnits = TagManager.instance.PlayerUnits;
for (int i = 0; i < playerUnits.Count; i++)
{
PathfindMovementPlayerunit component = ((Component)playerUnits[i]).GetComponent<PathfindMovementPlayerunit>();
if ((Object)(object)component != (Object)null)
{
TryApply(component);
}
}
}
}
[HarmonyPatch(typeof(PlayerMovement), "Start")]
public static class PlayerCharacterMoveSpeedPatch
{
private static readonly Dictionary<PlayerMovement, float[]> OriginalSpeeds = new Dictionary<PlayerMovement, float[]>();
private static void Postfix(PlayerMovement __instance)
{
if (!((Object)(object)ModMenu.Instance == (Object)null) && ModMenu.Instance.PlayerMoveSpeedMultiplier != 1f)
{
StoreAndApply(__instance);
}
}
public static void StoreAndApply(PlayerMovement pm)
{
if (!OriginalSpeeds.ContainsKey(pm))
{
OriginalSpeeds[pm] = new float[4] { pm.speed, pm.sprintSpeed, pm.speedDuringDay, pm.sprintSpeedDuringDay };
}
float[] array = OriginalSpeeds[pm];
float playerMoveSpeedMultiplier = ModMenu.Instance.PlayerMoveSpeedMultiplier;
pm.speed = array[0] * playerMoveSpeedMultiplier;
pm.sprintSpeed = array[1] * playerMoveSpeedMultiplier;
pm.speedDuringDay = array[2] * playerMoveSpeedMultiplier;
pm.sprintSpeedDuringDay = array[3] * playerMoveSpeedMultiplier;
}
public static void ReapplyIfNeeded()
{
if (!((Object)(object)PlayerMovement.instance == (Object)null))
{
StoreAndApply(PlayerMovement.instance);
}
}
}
public static class PlayerCharacterHpPatch
{
private static readonly Dictionary<Hp, float> OriginalMaxHp = new Dictionary<Hp, float>();
public static void TryApply(Hp hp)
{
float playerHpMultiplier = ModMenu.Instance.PlayerHpMultiplier;
if (playerHpMultiplier != 1f || OriginalMaxHp.ContainsKey(hp))
{
if (!OriginalMaxHp.ContainsKey(hp))
{
OriginalMaxHp[hp] = hp.HpOriginal;
}
HpFieldAccess.SetMaxHpSilent(hp, OriginalMaxHp[hp] * playerHpMultiplier);
}
}
public static void ReapplyIfNeeded()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> players = TagManager.instance.Players;
for (int i = 0; i < players.Count; i++)
{
Hp component = ((Component)players[i]).GetComponent<Hp>();
if ((Object)(object)component != (Object)null)
{
TryApply(component);
}
}
}
}
[HarmonyPatch(typeof(ManualAttack), "Start")]
public static class PlayerCharacterAttackPatch
{
private static readonly Dictionary<ManualAttack, float> OriginalCooldowns = new Dictionary<ManualAttack, float>();
private static void Postfix(ManualAttack __instance)
{
if (!((Object)(object)ModMenu.Instance == (Object)null) && ModMenu.Instance.PlayerAttackSpeedMultiplier != 1f)
{
TryApply(__instance);
}
}
public static void TryApply(ManualAttack atk)
{
if (!OriginalCooldowns.ContainsKey(atk))
{
OriginalCooldowns[atk] = atk.cooldownTime;
}
float num = OriginalCooldowns[atk];
atk.cooldownTime = num / ModMenu.Instance.PlayerAttackSpeedMultiplier;
}
public static void ReapplyIfNeeded()
{
if (!((Object)(object)PlayerInteraction.instance == (Object)null))
{
ManualAttack manualAttack = PlayerInteraction.instance.ManualAttack;
if ((Object)(object)manualAttack != (Object)null)
{
TryApply(manualAttack);
}
ManualAttack autoAttack = PlayerInteraction.instance.AutoAttack;
if ((Object)(object)autoAttack != (Object)null)
{
TryApply(autoAttack);
}
}
}
}
public static class PlayerCharacterDamagePatch
{
public static void Apply(Hp hp)
{
if (ModMenu.Instance.PlayerDamageMultiplier != 1f)
{
hp.DamageMultiplyer = ModMenu.Instance.PlayerDamageMultiplier;
}
}
public static void ReapplyIfNeeded()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
IReadOnlyList<TaggedObject> players = TagManager.instance.Players;
for (int i = 0; i < players.Count; i++)
{
Hp component = ((Component)players[i]).GetComponent<Hp>();
if ((Object)(object)component != (Object)null)
{
component.DamageMultiplyer = ModMenu.Instance.PlayerDamageMultiplier;
}
}
}
}
public static class TowerHpPatch
{
private static readonly HashSet<Hp> Scaled = new HashSet<Hp>();
private static readonly HashSet<Hp> Applied = new HashSet<Hp>();
private static float _lastMult = 1f;
public static void TryApply(Hp hp)
{
float towerHpMultiplier = ModMenu.Instance.TowerHpMultiplier;
if (towerHpMultiplier != 1f || Scaled.Contains(hp))
{
HpFieldAccess.ScaleHpSilent(hp, towerHpMultiplier, Scaled);
Applied.Add(hp);
}
}
public static void ApplyToAllTowers()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
float towerHpMultiplier = ModMenu.Instance.TowerHpMultiplier;
bool flag = towerHpMultiplier != _lastMult;
if (towerHpMultiplier == 1f && !flag)
{
return;
}
_lastMult = towerHpMultiplier;
List<TaggedObject> list = TagManager.instance.FindAllTaggedObjectsWithTagDirect_UseWithCare((ETag)24);
if (list == null)
{
return;
}
for (int i = 0; i < list.Count; i++)
{
Hp component = ((Component)list[i]).GetComponent<Hp>();
if (!((Object)(object)component == (Object)null) && (flag || !Applied.Contains(component)))
{
TryApply(component);
}
}
}
}
public static class TowerAutoAttackPatch
{
private static readonly Dictionary<AutoAttack, float> OriginalCooldowns = new Dictionary<AutoAttack, float>();
private static readonly HashSet<AutoAttack> Applied = new HashSet<AutoAttack>();
private static float _lastDmgMult = 1f;
private static float _lastAtkSpdMult = 1f;
public static void TryApply(AutoAttack atk)
{
if (!OriginalCooldowns.ContainsKey(atk))
{
OriginalCooldowns[atk] = atk.cooldownDuration;
}
float num = OriginalCooldowns[atk];
atk.cooldownDuration = num / ModMenu.Instance.TowerAttackSpeedMultiplier;
atk.DamageMultiplyer = ModMenu.Instance.TowerDamageMultiplier;
Applied.Add(atk);
}
public static void ApplyToAllTowers()
{
if ((Object)(object)TagManager.instance == (Object)null)
{
return;
}
float towerDamageMultiplier = ModMenu.Instance.TowerDamageMultiplier;
float towerAttackSpeedMultiplier = ModMenu.Instance.TowerAttackSpeedMultiplier;
bool flag = towerDamageMultiplier != _lastDmgMult || towerAttackSpeedMultiplier != _lastAtkSpdMult;
if (towerDamageMultiplier == 1f && towerAttackSpeedMultiplier == 1f && !flag)
{
return;
}
_lastDmgMult = towerDamageMultiplier;
_lastAtkSpdMult = towerAttackSpeedMultiplier;
List<TaggedObject> list = TagManager.instance.FindAllTaggedObjectsWithTagDirect_UseWithCare((ETag)24);
if (list == null)
{
return;
}
for (int i = 0; i < list.Count; i++)
{
AutoAttack[] components = ((Component)list[i]).GetComponents<AutoAttack>();
foreach (AutoAttack val in components)
{
if (flag || !Applied.Contains(val))
{
TryApply(val);
}
}
}
}
}
}