using HarmonyLib; using SRMultiplayer.Networking; using SRMultiplayer.Packets; using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace SRMultiplayer.Patches { [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("Reset")] class PlayerState_Reset { static void Postfix(PlayerState __instance) { Dictionary dictionary = new Dictionary(PlayerState.AmmoModeComparer.Instance); dictionary.Add(PlayerState.AmmoMode.DEFAULT, new NetworkPlayerAmmo(0, __instance.GetPotentialAmmo(), 5, 4, PlayerState.PLAYER_AMMO_PREDS, new Func(__instance.GetMaxAmmo_Default))); HashSet hashSet = new HashSet(Identifiable.idComparer); hashSet.Add(Identifiable.Id.QUICKSILVER_PLORT); hashSet.Add(Identifiable.Id.VALLEY_AMMO_1); hashSet.Add(Identifiable.Id.VALLEY_AMMO_2); hashSet.Add(Identifiable.Id.VALLEY_AMMO_3); hashSet.Add(Identifiable.Id.VALLEY_AMMO_4); Predicate[] array = new Predicate[3]; array[0] = ((Identifiable.Id id) => id == Identifiable.Id.QUICKSILVER_PLORT); array[1] = ((Identifiable.Id id) => id == Identifiable.Id.VALLEY_AMMO_1); array[2] = ((Identifiable.Id id) => id == Identifiable.Id.VALLEY_AMMO_2 || id == Identifiable.Id.VALLEY_AMMO_3 || id == Identifiable.Id.VALLEY_AMMO_4); dictionary.Add(PlayerState.AmmoMode.NIMBLE_VALLEY, new NetworkPlayerAmmo(1, hashSet, 3, 3, array, new Func(__instance.GetMaxAmmo_NimbleValley))); __instance.ammoDict = dictionary; } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("SpendKey")] class PlayerModel_SpendKey { static void Postfix(ref bool __result) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; if (__result) { new PacketWorldKey() { Added = false }.Send(); } } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("UnlockMap")] class PlayerModel_UnlockMap { static void Postfix(ZoneDirector.Zone zone) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketWorldMapUnlock() { Zone = (byte)zone }.Send(); } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("SpendCurrency")] class PlayerModel_SpendCurrency { static void Postfix(PlayerState __instance, int adjust) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketPlayerCurrency() { Total = Math.Max(0, __instance.GetCurrency()), Adjust = -adjust }.Send(); } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("AddCurrency")] class PlayerModel_AddCurrency { static void Postfix(PlayerState __instance, int adjust, PlayerState.CoinsType coinsType) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketPlayerCurrency() { Total = Math.Max(0, __instance.GetCurrency()), Adjust = adjust, Type = (byte)coinsType }.Send(); } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("SetCurrencyDisplay")] class PlayerModel_SetCurrencyDisplay { static void Postfix(PlayerState __instance, int? currencyDisplay) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketPlayerCurrencyDisplay() { IsNull = currencyDisplay == null, Currency = currencyDisplay != null ? currencyDisplay.Value : DroneFastForwarder.coinsPopup }.Send(); } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("AddUpgrade")] class PlayerModel_AddUpgrade { static void Postfix(PlayerState.Upgrade upgrade) { if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketPlayerUpgrade() { Upgrade = (byte)upgrade }.Send(); } } [HarmonyPatch(typeof(PlayerState))] [HarmonyPatch("Update")] class PlayerState_Update { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); int foundAt = -1; for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Brtrue_S) { for (int j = 0; j < 10; j++) { if (codes[i + j].opcode == OpCodes.Callvirt && codes[i + j].operand?.ToString() == "Void Add(Upgrade)") { foundAt = i + j; break; } } } if (foundAt >= 0) break; } if (foundAt >= 0) { codes[foundAt] = new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PlayerState_Update), "Transpiler_Execute")); } return codes.AsEnumerable(); } static void Transpiler_Execute(PlayerState.Upgrade upgrade) { SRSingleton.Instance.PlayerState.model.availUpgrades.Add(upgrade); if (!Globals.IsMultiplayer || Globals.HandlePacket) return; new PacketPlayerUpgradeUnlock() { Upgrade = (byte)upgrade }.Send(); } } }