using System;
using System.Collections;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;
[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("YourName")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("R.E.P.O. Hard Mode - Modular difficulty mod")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("REPOHardMode")]
[assembly: AssemblyTitle("REPOHardMode")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.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 REPOHardMode
{
[BepInPlugin("com.gosufrutita.repohardmode", "R.E.P.O. Hard Mode", "1.2.1")]
public class HardModePlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.yourname.repohardmode";
public const string PluginName = "R.E.P.O. Hard Mode";
public const string PluginVersion = "1.2.1";
internal static ManualLogSource Log;
internal static HardModePlugin Instance;
private Harmony _harmony;
public static ConfigEntry<float> PriceMultiplier;
public static ConfigEntry<float> EnemySpeedMultiplier;
public static ConfigEntry<float> ItemWeightMultiplier;
public static ConfigEntry<float> ItemSpawnMultiplier;
public static ConfigEntry<int> PlayerMaxHealth;
public static ConfigEntry<float> ItemFragilityMultiplier;
public static ConfigEntry<float> ItemDurabilityMultiplier;
private void Awake()
{
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
PriceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "PriceMultiplier", 2.5f, "Multiplier for all shop item prices (2.5 = x2.5 prices)");
EnemySpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "EnemySpeedMultiplier", 2f, "Multiplier for enemy movement speed (2.0 = 2x faster)");
ItemWeightMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "ItemWeightMultiplier", 2f, "Multiplier for item weight/mass (2.0 = 2x heavier)");
ItemSpawnMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "ItemSpawnMultiplier", 1.15f, "Multiplier for item spawn count (1.15 = 15% more items)");
PlayerMaxHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Difficulty", "PlayerMaxHealth", 50, "Maximum health for players (default game value is 100, set to 50 for harder difficulty)");
ItemFragilityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "ItemFragilityMultiplier", 2f, "Multiplier for item fragility (2.0 = items break 2x easier from impacts)");
ItemDurabilityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "ItemDurabilityMultiplier", 0.5f, "Multiplier for item durability (0.5 = items have half durability, break 2x faster)");
_harmony = new Harmony("com.yourname.repohardmode");
_harmony.PatchAll();
Log.LogInfo((object)"R.E.P.O. Hard Mode v1.2.1 loaded!");
Log.LogInfo((object)$"Settings: Prices x{PriceMultiplier.Value}, Enemy Speed x{EnemySpeedMultiplier.Value}, Weight x{ItemWeightMultiplier.Value}, Max HP: {PlayerMaxHealth.Value}");
Log.LogInfo((object)$"Fragility x{ItemFragilityMultiplier.Value}, Durability x{ItemDurabilityMultiplier.Value}");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
public static class PatchUtils
{
public static bool ShouldApplyPatch()
{
if (!PhotonNetwork.IsConnected)
{
return true;
}
return PhotonNetwork.IsMasterClient;
}
public static bool ShouldApplyToSelf()
{
return true;
}
}
[HarmonyPatch(typeof(ItemAttributes), "GetValue")]
public class ItemPricePatch
{
private static readonly FieldRef<ShopManager, float> _getItemValueMultiplier;
private static readonly FieldRef<ShopManager, float> _getUpgradeValueIncrease;
private static readonly FieldRef<ShopManager, float> _getHealthPackValueIncrease;
private static readonly FieldRef<ShopManager, float> _getCrystalValueIncrease;
static ItemPricePatch()
{
try
{
_getItemValueMultiplier = AccessTools.FieldRefAccess<ShopManager, float>(typeof(ShopManager).GetField("itemValueMultiplier", BindingFlags.Instance | BindingFlags.NonPublic));
_getUpgradeValueIncrease = AccessTools.FieldRefAccess<ShopManager, float>(typeof(ShopManager).GetField("upgradeValueIncrease", BindingFlags.Instance | BindingFlags.NonPublic));
_getHealthPackValueIncrease = AccessTools.FieldRefAccess<ShopManager, float>(typeof(ShopManager).GetField("healthPackValueIncrease", BindingFlags.Instance | BindingFlags.NonPublic));
_getCrystalValueIncrease = AccessTools.FieldRefAccess<ShopManager, float>(typeof(ShopManager).GetField("crystalValueIncrease", BindingFlags.Instance | BindingFlags.NonPublic));
HardModePlugin.Log.LogInfo((object)"Item price patch initialized successfully");
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Failed to initialize item price patch: {arg}");
}
}
public static bool Prefix(ref int ___value, float ___itemValueMin, float ___itemValueMax, itemType ___itemType, string ___itemAssetName, PhotonView ___photonView)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Invalid comparison between Unknown and I4
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Invalid comparison between Unknown and I4
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Invalid comparison between Unknown and I4
if (GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient)
{
return true;
}
if (!SemiFunc.RunIsShop())
{
return true;
}
if (!PatchUtils.ShouldApplyPatch())
{
return true;
}
try
{
float num = Random.Range(___itemValueMin, ___itemValueMax) * _getItemValueMultiplier.Invoke(ShopManager.instance);
if (num < 1000f)
{
num = 1000f;
}
if (num >= 1000f)
{
num = Mathf.Ceil(num / 1000f);
}
if ((int)___itemType == 3)
{
num += num * _getUpgradeValueIncrease.Invoke(ShopManager.instance) * (float)StatsManager.instance.GetItemsUpgradesPurchased(___itemAssetName);
}
else if ((int)___itemType == 8)
{
num += num * _getHealthPackValueIncrease.Invoke(ShopManager.instance) * (float)RunManager.instance.levelsCompleted;
}
else if ((int)___itemType == 5)
{
num += num * _getCrystalValueIncrease.Invoke(ShopManager.instance) * (float)RunManager.instance.levelsCompleted;
}
float num2 = num * HardModePlugin.PriceMultiplier.Value;
___value = Mathf.Max(1, Mathf.RoundToInt(num2));
if (GameManager.Multiplayer() && PhotonNetwork.IsMasterClient && (Object)(object)___photonView != (Object)null)
{
___photonView.RPC("RpcValueChange", (RpcTarget)4, new object[1] { ___value });
}
return false;
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Error in price patch: {arg}");
return true;
}
}
}
[HarmonyPatch(typeof(EnemyNavMeshAgent), "Awake")]
public class EnemySpeedPatch
{
private static HashSet<int> processedAgents = new HashSet<int>();
private static FieldInfo FI_Agent = AccessTools.Field(typeof(EnemyNavMeshAgent), "Agent");
private static FieldInfo FI_DefaultSpeed = AccessTools.Field(typeof(EnemyNavMeshAgent), "DefaultSpeed");
[HarmonyPostfix]
private static void Postfix(EnemyNavMeshAgent __instance)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
if (!PatchUtils.ShouldApplyPatch() || (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsArena()))
{
return;
}
int instanceID = ((Object)__instance).GetInstanceID();
if (processedAgents.Contains(instanceID))
{
return;
}
processedAgents.Add(instanceID);
try
{
NavMeshAgent val = (NavMeshAgent)FI_Agent.GetValue(__instance);
float num = (float)FI_DefaultSpeed.GetValue(__instance);
if ((Object)(object)val != (Object)null && num > 0f)
{
float num2 = num * HardModePlugin.EnemySpeedMultiplier.Value;
FI_DefaultSpeed.SetValue(__instance, num2);
val.speed = num2;
HardModePlugin.Log.LogInfo((object)$"Enemy speed: {num:F2} -> {num2:F2}");
}
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Error in enemy speed patch: {arg}");
}
}
}
[HarmonyPatch(typeof(PlayerHealth), "Awake")]
public class PlayerHealthPatch
{
private static FieldInfo FI_playerAvatar = AccessTools.Field(typeof(PlayerHealth), "playerAvatar");
private static FieldInfo FI_maxHealth = AccessTools.Field(typeof(PlayerHealth), "maxHealth");
private static FieldInfo FI_health = AccessTools.Field(typeof(PlayerHealth), "health");
[HarmonyPostfix]
private static void Postfix(PlayerHealth __instance)
{
((MonoBehaviour)__instance).StartCoroutine(ApplyHealthModifiersDelayed(__instance));
}
private static IEnumerator ApplyHealthModifiersDelayed(PlayerHealth healthInstance)
{
while ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
{
yield return (object)new WaitForSeconds(0.1f);
}
yield return (object)new WaitForSeconds(0.5f);
try
{
PlayerAvatar val = (PlayerAvatar)(FI_playerAvatar?.GetValue(healthInstance));
if ((Object)(object)val == (Object)null)
{
HardModePlugin.Log.LogWarning((object)"PlayerAvatar is null!");
yield break;
}
if (!SemiFunc.RunIsLevel())
{
HardModePlugin.Log.LogInfo((object)"Not on level, skipping");
yield break;
}
int num = (int)FI_health.GetValue(healthInstance);
int num2 = (int)FI_maxHealth.GetValue(healthInstance);
int value = HardModePlugin.PlayerMaxHealth.Value;
int num3 = Mathf.Min(num, value);
FI_maxHealth.SetValue(healthInstance, value);
FI_health.SetValue(healthInstance, num3);
string text = "Unknown";
try
{
text = ((!((Object)(object)val.photonView != (Object)null) || val.photonView.Owner == null) ? "SinglePlayer/Local" : $"{val.photonView.Owner.NickName} (ID: {val.photonView.Owner.ActorNumber})");
}
catch
{
}
HardModePlugin.Log.LogInfo((object)$"[MULTIPLAYER] Player {text} health set: {num}/{num2} -> {num3}/{value}");
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Error in health patch: {arg}");
}
}
}
[HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")]
public class PlayerRevivePatch
{
[HarmonyPostfix]
private static void Postfix(PlayerAvatar __instance, bool _revivedByTruck)
{
((MonoBehaviour)__instance).StartCoroutine(SetHealthAfterRevive(__instance));
}
private static IEnumerator SetHealthAfterRevive(PlayerAvatar avatar)
{
yield return (object)new WaitForSeconds(0.2f);
try
{
if (!((Object)(object)avatar != (Object)null) || !((Object)(object)avatar.playerHealth != (Object)null))
{
yield break;
}
FieldInfo field = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo field2 = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field != null) || !(field2 != null))
{
yield break;
}
int value = HardModePlugin.PlayerMaxHealth.Value;
int num = (int)field.GetValue(avatar.playerHealth);
field2.SetValue(avatar.playerHealth, value);
if (num > value)
{
field.SetValue(avatar.playerHealth, value);
}
string arg = "Unknown";
try
{
if ((Object)(object)avatar.photonView != (Object)null && avatar.photonView.Owner != null)
{
arg = $"{avatar.photonView.Owner.NickName} (ID: {avatar.photonView.Owner.ActorNumber})";
}
}
catch
{
}
HardModePlugin.Log.LogInfo((object)$"[MULTIPLAYER] Player {arg} revived with reduced health: {Mathf.Min(num, value)}/{value}");
}
catch (Exception arg2)
{
HardModePlugin.Log.LogError((object)$"Error in revive patch: {arg2}");
}
}
}
[HarmonyPatch(typeof(ValuableObject), "Awake")]
public class ValuableFragilityPatch
{
[HarmonyPostfix]
private static void Postfix(ValuableObject __instance)
{
if (!PatchUtils.ShouldApplyPatch())
{
return;
}
try
{
if ((Object)(object)__instance.durabilityPreset != (Object)null)
{
Durability durabilityPreset = __instance.durabilityPreset;
durabilityPreset.fragility *= HardModePlugin.ItemFragilityMultiplier.Value;
Durability durabilityPreset2 = __instance.durabilityPreset;
durabilityPreset2.durability *= HardModePlugin.ItemDurabilityMultiplier.Value;
}
PhysGrabObjectImpactDetector component = ((Component)__instance).GetComponent<PhysGrabObjectImpactDetector>();
if ((Object)(object)component != (Object)null && (Object)(object)__instance.durabilityPreset != (Object)null)
{
component.fragility = __instance.durabilityPreset.fragility;
component.durability = __instance.durabilityPreset.durability;
}
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Error in fragility patch: {arg}");
}
}
}
[HarmonyPatch(typeof(ValuableObject), "Awake")]
public class ValuableWeightPatch
{
[HarmonyPostfix]
private static void Postfix(ValuableObject __instance)
{
if (!PatchUtils.ShouldApplyPatch())
{
return;
}
try
{
Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
float mass = component.mass;
component.mass *= HardModePlugin.ItemWeightMultiplier.Value;
HardModePlugin.Log.LogDebug((object)$"Item weight: {mass:F2} -> {component.mass:F2}");
}
}
catch (Exception arg)
{
HardModePlugin.Log.LogError((object)$"Error in weight patch: {arg}");
}
}
}
[HarmonyPatch(typeof(ValuableDirector), "Start")]
public class ItemSpawnPatch
{
[HarmonyPostfix]
private static void Postfix(ValuableDirector __instance)
{
if (!PatchUtils.ShouldApplyPatch())
{
return;
}
try
{
FieldInfo[] fields = typeof(ValuableDirector).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (!(fieldInfo.FieldType == typeof(int)))
{
continue;
}
string text = fieldInfo.Name.ToLower();
if (text.Contains("count") || text.Contains("amount") || text.Contains("max") || text.Contains("spawn"))
{
int num = (int)fieldInfo.GetValue(__instance);
if (num > 0 && num < 500)
{
int num2 = Mathf.RoundToInt((float)num * HardModePlugin.ItemSpawnMultiplier.Value);
fieldInfo.SetValue(__instance, num2);
HardModePlugin.Log.LogInfo((object)$"Spawn '{fieldInfo.Name}': {num} -> {num2}");
}
}
}
}
catch (Exception ex)
{
HardModePlugin.Log.LogDebug((object)("Item spawn patch: " + ex.Message));
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.gosufrutita.repohardmode";
public const string PLUGIN_NAME = "R.E.P.O. Hard Mode";
public const string PLUGIN_VERSION = "1.2.1";
}
}