using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.InputSystem;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("JardsAdditions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JardsAdditions")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("2.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
namespace JardsAdditions
{
internal enum PvpProtection
{
Yes,
OnlyInWard,
No
}
internal enum BloodstoneEffect
{
Damage,
Vampirism,
DamageAndVampirism
}
internal class Configuration
{
public ConfigEntry<PvpProtection> PreventSkillLoss;
public ConfigEntry<PvpProtection> ProtectPlayerGraves;
public ConfigEntry<float> PavedRoadSpeedMultiplier;
public ConfigEntry<float> PavedRoadStaminaMultiplier;
public ConfigEntry<float> GreatswordStaggerMultiplier;
public ConfigEntry<float> GreatswordKnockbackMultiplier;
public ConfigEntry<float> GreatswordAdrenalineMultiplier;
public ConfigEntry<bool> ApplyRunBuffsToStoneFloors;
public ConfigEntry<bool> ApplyRunBuffsToCageFloors;
public ConfigEntry<BloodstoneEffect> ChangeBloodstoneEffect;
public ConfigEntry<float> BloodstoneDamagePercent;
public ConfigEntry<float> BloodstoneVampirismPercent;
public ConfigEntry<float> FoodLossPenalty;
public ConfigEntry<float> FoodLossPenaltyOnSoftDeath;
public ConfigEntry<bool> WindRunWithModer;
public ConfigEntry<bool> MapTableRestrictToBases;
public ConfigEntry<uint> MapTableBasePieceRequirement;
public ConfigEntry<uint> MapTableComfortLevelRequirement;
public void Load(BaseUnityPlugin plugin)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Expected O, but got Unknown
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Expected O, but got Unknown
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Expected O, but got Unknown
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Expected O, but got Unknown
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Expected O, but got Unknown
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Expected O, but got Unknown
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_026f: Expected O, but got Unknown
//IL_029f: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Expected O, but got Unknown
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Expected O, but got Unknown
//IL_0301: Unknown result type (might be due to invalid IL or missing references)
//IL_030b: Expected O, but got Unknown
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_0333: Expected O, but got Unknown
//IL_0358: Unknown result type (might be due to invalid IL or missing references)
//IL_0362: Expected O, but got Unknown
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_0391: Expected O, but got Unknown
object[] array = new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true
} };
PreventSkillLoss = plugin.Config.Bind<PvpProtection>("PvP Protection", "PreventPvPSkillLoss", PvpProtection.OnlyInWard, new ConfigDescription("Whether to prevent skill loss when killed by another player (enforced by server)", (AcceptableValueBase)null, array));
ProtectPlayerGraves = plugin.Config.Bind<PvpProtection>("PvP Protection", "ProtectPlayerGraves", PvpProtection.OnlyInWard, new ConfigDescription("Whether to prevent grave access by other players (enforced by server)", (AcceptableValueBase)null, array));
PavedRoadStaminaMultiplier = plugin.Config.Bind<float>("Vanilla tweaks", "PavedRoadStaminaMultiplier", 0.4f, new ConfigDescription("Stamina multiplier when running on a paved road (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), array));
PavedRoadSpeedMultiplier = plugin.Config.Bind<float>("Vanilla tweaks", "PavedRoadSpeedMultiplier", 0.4f, new ConfigDescription("Speed multiplier when running on a paved road (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), array));
GreatswordStaggerMultiplier = plugin.Config.Bind<float>("Vanilla tweaks", "GreatswordStaggerMultiplier", 1.5f, new ConfigDescription("Multiplier applied to staggering from greatsword attacks (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), array));
GreatswordKnockbackMultiplier = plugin.Config.Bind<float>("Vanilla tweaks", "GreatswordKnockbackMultiplier", 1.5f, new ConfigDescription("Multiplier applied to knockback from greatsword attacks (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), array));
GreatswordAdrenalineMultiplier = plugin.Config.Bind<float>("Vanilla tweaks", "GreatswordAdrenalineMultiplier", 1.333f, new ConfigDescription("Multiplier applied to gained adrenaline from greatsword attacks (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), array));
ApplyRunBuffsToStoneFloors = plugin.Config.Bind<bool>("Vanilla tweaks", "ApplyRunBuffsToStoneFloors", true, new ConfigDescription("Whether to apply speed and stamina multipliers when the player is running on a stone piece (stone floor, grausten floor, etc) (enforced by server)", (AcceptableValueBase)null, array));
ApplyRunBuffsToCageFloors = plugin.Config.Bind<bool>("Vanilla tweaks", "ApplyRunBuffsToCageFloors", true, new ConfigDescription("Whether to apply speed and stamina multipliers when the player is running on a cage floor piece (enforced by server)", (AcceptableValueBase)null, array));
ChangeBloodstoneEffect = plugin.Config.Bind<BloodstoneEffect>("Vanilla tweaks", "ChangeBloodstoneEffect", BloodstoneEffect.Damage, new ConfigDescription("Modify the effect of the bloodstone enchantment on Ashlands weapons (enforced by server)", (AcceptableValueBase)null, array));
BloodstoneDamagePercent = plugin.Config.Bind<float>("Vanilla tweaks", "BloodstoneDamagePercent", 0.004f, new ConfigDescription("Base percentage increase of damage per missing health point for bloodstone damage effect (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.002f, 0.01f), array));
BloodstoneVampirismPercent = plugin.Config.Bind<float>("Vanilla tweaks", "BloodstoneVampirismPercent", 0.0225f, new ConfigDescription("Base percentage of health returned per missing health point for bloodstone vampirism effect (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), array));
FoodLossPenalty = plugin.Config.Bind<float>("Vanilla tweaks", "FoodLossPenalty", 1f, new ConfigDescription("The percentage penalty to apply to consumed food duration after dying. 0 is no food loss, 1 is standard vanilla behavior (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), array));
FoodLossPenaltyOnSoftDeath = plugin.Config.Bind<float>("Vanilla tweaks", "FoodLossPenaltyOnSoftDeath", 1f, new ConfigDescription("The percentage penalty to apply to consumed food duration after dying with the 'No skill drain' status. 0 is no food loss, 1 is standard vanilla behavior (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), array));
WindRunWithModer = plugin.Config.Bind<bool>("Vanilla tweaks", "WindRunWithModer", true, new ConfigDescription("Whether Moder's power synergizes with the asksvin cape by controlling wind direction while wearing the cape (enforced by server)", (AcceptableValueBase)null, array));
MapTableRestrictToBases = plugin.Config.Bind<bool>("Vanilla tweaks", "MapTableRestrictToBases", false, new ConfigDescription("Whether to restrict writing and reading from the cartography table to player bases only. Emulates NoMapPrinter's map restrictions, but for interaction with the cartography table (enforced by server)", (AcceptableValueBase)null, array));
MapTableBasePieceRequirement = plugin.Config.Bind<uint>("Vanilla tweaks", "MapTableBasePieceRequirement", 0u, new ConfigDescription("Assuming `MapTableRestrictToBase = true`; the number of surrounding base pieces required to read from and write to the cartography table (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<uint>(0u, 100u), array));
MapTableComfortLevelRequirement = plugin.Config.Bind<uint>("Vanilla tweaks", "MapTableComfortLevelRequirement", 0u, new ConfigDescription("Assuming `MapTableRestrictToBase = true`; the player comfort level required to read from and write to the cartography table (enforced by server)", (AcceptableValueBase)(object)new AcceptableValueRange<uint>(0u, 100u), array));
}
}
[BepInPlugin("hu.jard.JardsAdditions", "Jard's Additions", "2.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInIncompatibility("Basil_NoStamCosts")]
[BepInIncompatibility("Basil_NoFoodLoss")]
internal class JardsAdditions : BaseUnityPlugin
{
public const string PluginGUID = "hu.jard.JardsAdditions";
public const string PluginName = "Jard's Additions";
public const string PluginVersion = "2.1.0";
public static Configuration PluginConfig = new Configuration();
public static LocaleManager PluginLocale = new LocaleManager();
private AssetBundle CustomBundle;
private AssetBundle OldVanityBundle;
private AssetBundle NewVanityBundle;
private void Awake()
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
LoadBundles();
PluginConfig.Load((BaseUnityPlugin)(object)this);
PluginLocale.Load(CustomBundle, "custom");
PrefabManager.OnVanillaPrefabsAvailable += AddVanityItems;
PrefabManager.OnVanillaPrefabsAvailable += AddStatusEffects;
new Harmony("hu.jard.JardsAdditions").PatchAll();
new Harmony("Basil_NoStamCosts").UnpatchSelf();
}
private void LoadBundles()
{
CustomBundle = AssetUtils.LoadAssetBundleFromResources("custom", Assembly.GetExecutingAssembly());
OldVanityBundle = AssetUtils.LoadAssetBundleFromResources("vanity1", Assembly.GetExecutingAssembly());
NewVanityBundle = AssetUtils.LoadAssetBundleFromResources("vanity2", Assembly.GetExecutingAssembly());
}
private void AddStatusEffects()
{
AddSEFrom(CustomBundle, "Enigma_block");
AddSEFrom(CustomBundle, "Enigma_heavyarmor_carry");
AddSEFrom(CustomBundle, "Enigma_towershield_haste");
PrefabManager.OnVanillaPrefabsAvailable -= AddStatusEffects;
}
private void AddVanityItems()
{
AddItemFrom(OldVanityBundle, "CapeJard");
AddItemFrom(OldVanityBundle, "HelmetDriver");
AddItemFrom(OldVanityBundle, "CapeDriver");
AddItemFrom(NewVanityBundle, "CrossbowJard");
PrefabManager.OnVanillaPrefabsAvailable -= AddVanityItems;
}
private void AddItemFrom(AssetBundle bundle, string prefabName)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
GameObject val = bundle.LoadAsset<GameObject>(prefabName);
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load prefab '" + prefabName + "' from asset bundle '" + ((Object)bundle).name + "'"));
}
else
{
ItemManager.Instance.AddItem(new CustomItem(val, true));
}
}
private void AddSEFrom(AssetBundle bundle, string seName)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
StatusEffect val = bundle.LoadAsset<StatusEffect>(seName);
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load status effect '" + seName + "' from asset bundle '" + ((Object)bundle).name + "'"));
}
else
{
ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(val, true));
}
}
}
internal class LocaleManager
{
private CustomLocalization Manager = LocalizationManager.Instance.GetLocalization();
public void Load(AssetBundle bundle, string locale_key)
{
TextAsset[] array = bundle.LoadAllAssets<TextAsset>();
foreach (TextAsset val in array)
{
Manager.AddJsonFile(((Object)val).name.Replace(".json", null).Replace(locale_key + "_", null), ((object)val).ToString());
}
}
}
internal class BloodstoneHelpers
{
public static float CalculateVampMultiplier(ItemData item)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if (item.m_shared.m_attack.m_damageMultiplierPerMissingHP <= 0f)
{
return 0f;
}
float num = JardsAdditions.PluginConfig.BloodstoneVampirismPercent.Value * (JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value / item.m_shared.m_attack.m_damageMultiplierPerMissingHP);
DamageTypes damages = item.m_shared.m_damages;
if (item.m_quality > 1)
{
((DamageTypes)(ref damages)).Add(item.m_shared.m_damagesPerLevel, Mathf.Min(item.m_quality - 1, 3));
}
float num2 = ((DamageTypes)(ref damages)).GetTotalPhysicalDamage();
if (item.m_quality > 4)
{
((DamageTypes)(ref damages)).Add(item.m_shared.m_damagesPerLevel, item.m_quality - 4);
float num3 = ((DamageTypes)(ref damages)).GetTotalPhysicalDamage() - num2;
num2 += num3 / (1f + Mathf.Log((float)(item.m_quality - 4)));
}
float num4 = Mathf.Pow(num2 / 140f, 2.5f);
if (num4 < 1f)
{
num4 = 1f;
}
float num5 = 0f;
ZoneSystem.instance.GetGlobalKey((GlobalKeys)1, ref num5);
if (num5 == 0f)
{
num5 = 100f;
}
num5 /= 100f;
return num * num4 * num5;
}
}
[HarmonyPatch(typeof(Attack))]
internal class BloodstoneModifiers_DamageOverride
{
private static bool ShouldModifyDamage()
{
if (JardsAdditions.PluginConfig.ChangeBloodstoneEffect.Value == BloodstoneEffect.Vampirism)
{
return true;
}
if (JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value != 0.02f)
{
return true;
}
return false;
}
[HarmonyPatch("ModifyDamage")]
[HarmonyPrefix]
private static bool OverrideBloodDamage(ref Attack __instance, HitData hitData, float damageFactor)
{
if (ShouldModifyDamage())
{
if (__instance.m_damageMultiplier != 1f)
{
((DamageTypes)(ref hitData.m_damage)).Modify(__instance.m_damageMultiplier);
}
if (damageFactor != 1f)
{
((DamageTypes)(ref hitData.m_damage)).Modify(damageFactor);
}
((DamageTypes)(ref hitData.m_damage)).Modify(__instance.GetLevelDamageFactor());
float num = 0f;
switch (JardsAdditions.PluginConfig.ChangeBloodstoneEffect.Value)
{
case BloodstoneEffect.Damage:
case BloodstoneEffect.DamageAndVampirism:
num = ((JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value != 0.002f) ? JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value : __instance.m_damageMultiplierPerMissingHP);
break;
}
if (__instance.m_damageMultiplierByTotalHealthMissing > 0f)
{
((DamageTypes)(ref hitData.m_damage)).Modify(1f + (1f - ((Character)__instance.m_character).GetHealthPercentage()) * __instance.m_damageMultiplierByTotalHealthMissing);
}
if (num > 0f)
{
((DamageTypes)(ref hitData.m_damage)).Modify(1f + (1f - ((Character)__instance.m_character).GetHealthPercentage()) * num);
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Attack))]
internal class BloodstoneModifiers_VampirismOverride
{
[HarmonyPatch("OnAttackTrigger")]
[HarmonyPrefix]
private static void OnAttackTrigger(ref Attack __instance)
{
if (JardsAdditions.PluginConfig.ChangeBloodstoneEffect.Value != 0 && __instance.m_damageMultiplierPerMissingHP > 0f)
{
float num = BloodstoneHelpers.CalculateVampMultiplier(__instance.m_weapon);
float attackHealthReturnHit = (((Character)__instance.m_character).GetMaxHealth() - ((Character)__instance.m_character).GetHealth()) * num;
__instance.m_attackHealthReturnHit = attackHealthReturnHit;
}
}
}
[HarmonyPatch(typeof(ItemData))]
internal class BloodstoneModifiers_TooltipPatches
{
[HarmonyPatch("GetTooltip", new Type[]
{
typeof(ItemData),
typeof(int),
typeof(bool),
typeof(float),
typeof(int)
})]
[HarmonyPostfix]
private static void OverrideTooltipValues(ref string __result, ItemData item, int qualityLevel, bool crafting, float worldLevel, int stackOverride = -1)
{
LinkedList<string> linkedList = new LinkedList<string>(__result.Split(new char[1] { '\n' }));
bool flag = false;
for (LinkedListNode<string> linkedListNode = linkedList.First; linkedListNode != null; linkedListNode = linkedListNode.Next)
{
if (linkedListNode.Value.Contains("$item_damagemultiplierhp"))
{
if (JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value != item.m_shared.m_attack.m_damageMultiplierPerMissingHP)
{
linkedListNode.Value = $"$item_damagemultiplierhp: <color=orange>{JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value * 100f}%</color>";
flag = true;
}
if (JardsAdditions.PluginConfig.ChangeBloodstoneEffect.Value != 0)
{
float num = BloodstoneHelpers.CalculateVampMultiplier(item);
string value = $"$item_vampirismhp: <color=orange>{num * 100f}%</color>";
if (JardsAdditions.PluginConfig.ChangeBloodstoneEffect.Value == BloodstoneEffect.Vampirism)
{
linkedListNode.Value = value;
}
else
{
linkedList.AddAfter(linkedListNode, value);
}
flag = true;
}
break;
}
}
if (!flag)
{
return;
}
__result = "";
foreach (string item2 in linkedList)
{
__result = __result + "\n" + item2;
}
}
}
internal class FoodHelpers
{
public static bool customFoodPenalty()
{
if (!(JardsAdditions.PluginConfig.FoodLossPenalty.Value < 1f))
{
return JardsAdditions.PluginConfig.FoodLossPenaltyOnSoftDeath.Value < 1f;
}
return true;
}
public static float getFoodMultiplier(bool softDeath)
{
return 1f - (softDeath ? JardsAdditions.PluginConfig.FoodLossPenaltyOnSoftDeath.Value : JardsAdditions.PluginConfig.FoodLossPenalty.Value);
}
}
internal class FoodModifiers
{
[HarmonyPatch(typeof(Player))]
internal class PunishFoods_Prefix
{
public static List<Food> foodsOnDeath = new List<Food>();
[HarmonyPatch("OnDeath")]
[HarmonyPrefix]
private static void SaveFoods(ref Player __instance)
{
if (!((Character)__instance).m_nview.IsOwner() || !FoodHelpers.customFoodPenalty())
{
return;
}
float foodMultiplier = FoodHelpers.getFoodMultiplier(!__instance.HardDeath());
if (foodMultiplier == 0f)
{
return;
}
foreach (Food food in __instance.m_foods)
{
food.m_time *= foodMultiplier;
foodsOnDeath.Add(food);
}
}
[HarmonyPatch("OnDeath")]
[HarmonyPostfix]
private static void LoadFoods(ref Player __instance)
{
if (!((Character)__instance).m_nview.IsOwner() || !FoodHelpers.customFoodPenalty() || foodsOnDeath.Capacity <= 0)
{
return;
}
foreach (Food item in foodsOnDeath)
{
__instance.m_foods.Add(item);
}
foodsOnDeath.Clear();
}
}
}
internal class MapTableHelpers
{
public static bool basePieceRestriction(Player player)
{
if (!JardsAdditions.PluginConfig.MapTableRestrictToBases.Value)
{
return true;
}
if (JardsAdditions.PluginConfig.MapTableBasePieceRequirement.Value != 0 && player.GetBaseValue() < JardsAdditions.PluginConfig.MapTableBasePieceRequirement.Value)
{
return false;
}
return true;
}
public static bool comfortLevelRestriction(Player player)
{
if (!JardsAdditions.PluginConfig.MapTableRestrictToBases.Value)
{
return true;
}
if (JardsAdditions.PluginConfig.MapTableComfortLevelRequirement.Value != 0 && player.GetComfortLevel() < JardsAdditions.PluginConfig.MapTableComfortLevelRequirement.Value)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(MapTable))]
internal class MapTableModifiers
{
[HarmonyPatch("OnRead", new Type[]
{
typeof(Switch),
typeof(Humanoid),
typeof(ItemData),
typeof(bool)
})]
[HarmonyPrefix]
private static bool DoBaseChecks_OnRead(ref MapTable __instance, bool __result, Switch caller, Humanoid user, ItemData item, bool showMessage)
{
if (!MapTableHelpers.basePieceRestriction(Player.m_localPlayer))
{
MessageHud.instance.ShowMessage((MessageType)2, $"Not enough base pieces nearby ({Player.m_localPlayer.GetBaseValue()} / {JardsAdditions.PluginConfig.MapTableBasePieceRequirement.Value})", 1, (Sprite)null, false);
return false;
}
if (!MapTableHelpers.comfortLevelRestriction(Player.m_localPlayer))
{
MessageHud.instance.ShowMessage((MessageType)2, $"Not enough comfort level ({Player.m_localPlayer.GetComfortLevel()} / {JardsAdditions.PluginConfig.MapTableComfortLevelRequirement.Value})", 1, (Sprite)null, false);
return false;
}
return true;
}
[HarmonyPatch("OnWrite")]
[HarmonyPrefix]
private static bool DoBaseChecks_OnWrite(ref MapTable __instance, ref bool __result)
{
if (!MapTableHelpers.basePieceRestriction(Player.m_localPlayer))
{
MessageHud.instance.ShowMessage((MessageType)2, $"Not enough base pieces nearby ({Player.m_localPlayer.GetBaseValue()} / {JardsAdditions.PluginConfig.MapTableBasePieceRequirement.Value})", 1, (Sprite)null, false);
return false;
}
if (!MapTableHelpers.comfortLevelRestriction(Player.m_localPlayer))
{
MessageHud.instance.ShowMessage((MessageType)2, $"Not enough comfort level ({Player.m_localPlayer.GetComfortLevel()} / {JardsAdditions.PluginConfig.MapTableComfortLevelRequirement.Value})", 1, (Sprite)null, false);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(EnvMan))]
internal class ModerPowerModifiers
{
[HarmonyPatch("UpdateWind")]
[HarmonyPrefix]
private static bool AskCapeWind(ref EnvMan __instance, long timeSec, float dt)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
if (__instance.GetCurrentEnvironment() != null && (Object)(object)Player.m_localPlayer != (Object)null)
{
bool num = (Object)(object)Ship.GetLocalShip() == (Object)null;
bool flag = ((Character)Player.m_localPlayer).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Moder"));
bool flag2 = ((Character)Player.m_localPlayer).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("WindRun"));
if (num && flag && flag2 && JardsAdditions.PluginConfig.WindRunWithModer.Value)
{
State state = Random.state;
float num2 = 0f;
float num3 = 0.5f;
__instance.AddWindOctave(timeSec, 1, ref num2, ref num3);
__instance.AddWindOctave(timeSec, 2, ref num2, ref num3);
__instance.AddWindOctave(timeSec, 4, ref num2, ref num3);
__instance.AddWindOctave(timeSec, 8, ref num2, ref num3);
Random.state = state;
num3 = Mathf.Lerp(__instance.GetCurrentEnvironment().m_windMin, __instance.GetCurrentEnvironment().m_windMax, num3);
__instance.SetTargetWind(((Component)Player.m_localPlayer).transform.forward, num3);
__instance.UpdateWindTransition(dt);
return false;
}
}
return true;
}
}
internal class PavedRoadHelpers
{
public static bool IsPaved(Heightmap h, Vector3 worldPos)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
int num2 = 0;
h.WorldToVertexMask(worldPos, ref num, ref num2);
return h.m_paintMask.GetPixel(num, num2).b > 0.5f;
}
private static WearNTear GetSuitableWearNTear(GameObject gameObject, int levels = 1)
{
if ((Object)(object)gameObject == (Object)null)
{
return null;
}
WearNTear component = gameObject.GetComponent<WearNTear>();
if ((Object)(object)component != (Object)null)
{
return component;
}
if (levels > 0)
{
return GetSuitableWearNTear(((Component)gameObject.transform.parent).gameObject, levels - 1);
}
return null;
}
public static bool TestCreatureIsOnPavedRoad(Character character)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Invalid comparison between Unknown and I4
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Invalid comparison between Unknown and I4
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Invalid comparison between Unknown and I4
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Invalid comparison between Unknown and I4
if (character.IsOnGround() && (Object)(object)character.m_lastGroundCollider != (Object)null)
{
Heightmap component = ((Component)character.m_lastGroundCollider).GetComponent<Heightmap>();
if ((Object)(object)component != (Object)null)
{
return IsPaved(component, ((Component)character).transform.position);
}
if (JardsAdditions.PluginConfig.ApplyRunBuffsToStoneFloors.Value || JardsAdditions.PluginConfig.ApplyRunBuffsToCageFloors.Value)
{
WearNTear suitableWearNTear = GetSuitableWearNTear(((Component)character.m_lastGroundCollider).gameObject);
if ((Object)(object)suitableWearNTear != (Object)null)
{
bool flag = (int)suitableWearNTear.m_materialType == 1 || (int)suitableWearNTear.m_materialType == 4 || (int)suitableWearNTear.m_materialType == 5;
bool flag2 = (int)suitableWearNTear.m_materialType == 2;
if (!(JardsAdditions.PluginConfig.ApplyRunBuffsToStoneFloors.Value && flag))
{
return JardsAdditions.PluginConfig.ApplyRunBuffsToCageFloors.Value && flag2;
}
return true;
}
}
}
return false;
}
public static void ScaleCreatureStat(Character character, float multiplier, ref float result)
{
if (TestCreatureIsOnPavedRoad(character))
{
result *= multiplier;
}
}
}
[HarmonyPatch(typeof(Character))]
internal class PavedRoadModifiers_CharacterSpeed
{
[HarmonyPatch("GetRunSpeedFactor")]
[HarmonyPostfix]
private static void ScaleCharacterRunSpeed(ref Character __instance, ref float __result)
{
PavedRoadHelpers.ScaleCreatureStat(__instance, JardsAdditions.PluginConfig.PavedRoadSpeedMultiplier.Value, ref __result);
}
}
[HarmonyPatch(typeof(Player))]
internal class PavedRoadModifiers_PlayerSpeed
{
[HarmonyPatch("GetRunSpeedFactor")]
[HarmonyPostfix]
private static void ScalePlayerRunSpeed(ref Character __instance, ref float __result)
{
PavedRoadHelpers.ScaleCreatureStat(__instance, JardsAdditions.PluginConfig.PavedRoadSpeedMultiplier.Value, ref __result);
}
}
[HarmonyPatch(typeof(SEMan))]
internal class PavedRoadModifiers_PlayerStamina
{
[HarmonyPatch("ModifyRunStaminaDrain")]
[HarmonyPostfix]
private static void ScalePlayerRunStamina(ref SEMan __instance, float baseDrain, ref float drain, bool minZero = true)
{
PavedRoadHelpers.ScaleCreatureStat(__instance.m_character, JardsAdditions.PluginConfig.PavedRoadStaminaMultiplier.Value, ref drain);
}
}
internal class PvpWardHelpers
{
public static bool checkIfLocationIsSafe(Vector3 position)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
foreach (PrivateArea allArea in PrivateArea.m_allAreas)
{
if (allArea.IsEnabled() && allArea.IsInside(position, 0f))
{
return true;
}
}
return false;
}
public static bool getSafeAreas(Vector3 position, ref List<PrivateArea> areas)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
bool result = false;
foreach (PrivateArea allArea in PrivateArea.m_allAreas)
{
if (allArea.IsEnabled() && allArea.IsInside(position, 0f))
{
areas.Add(allArea);
result = true;
}
}
return result;
}
}
[HarmonyPatch(typeof(Skills))]
internal class PvpWardModifiers_ProtectSkills
{
[HarmonyPatch("OnDeath")]
private static bool Prefix(ref Skills __instance)
{
//IL_0038: 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_004f: Invalid comparison between Unknown and I4
Player player = __instance.m_player;
bool flag = false;
switch (JardsAdditions.PluginConfig.PreventSkillLoss.Value)
{
case PvpProtection.Yes:
flag = true;
break;
case PvpProtection.OnlyInWard:
flag = PvpWardHelpers.checkIfLocationIsSafe(((Component)player).transform.position);
break;
}
bool flag2 = (int)((Character)player).m_lastHit.m_hitType == 2;
return !(flag && flag2);
}
}
[HarmonyPatch(typeof(TombStone))]
internal class PvpWardModifiers_ProtectTombstone
{
[HarmonyPatch("GetHoverText")]
[HarmonyPrefix]
private static bool NoAccessHoverText(ref TombStone __instance, ref string __result)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if (__instance.m_nview.IsValid())
{
bool flag = false;
switch (JardsAdditions.PluginConfig.ProtectPlayerGraves.Value)
{
case PvpProtection.Yes:
flag = true;
break;
case PvpProtection.OnlyInWard:
flag = PvpWardHelpers.checkIfLocationIsSafe(((Component)__instance).transform.position);
break;
}
if (flag && !__instance.IsOwner())
{
string text = __instance.m_text + " " + __instance.GetOwnerName() + "\n$piece_noaccess";
__result = Localization.instance.Localize(text);
return false;
}
}
return true;
}
[HarmonyPatch("Interact")]
[HarmonyPrefix]
private static bool BlockInteract(ref TombStone __instance)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
List<PrivateArea> areas = new List<PrivateArea>();
bool flag = false;
switch (JardsAdditions.PluginConfig.ProtectPlayerGraves.Value)
{
case PvpProtection.Yes:
flag = true;
break;
case PvpProtection.OnlyInWard:
flag = PvpWardHelpers.getSafeAreas(((Component)__instance).transform.position, ref areas);
break;
}
if (flag && !__instance.IsOwner())
{
foreach (PrivateArea item in areas)
{
item.FlashShield(false);
}
return false;
}
return true;
}
}
internal class Q3ABoomerHelpers
{
public static bool AreYouABoomer()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
ButtonDef buttonDef = ZInput.m_instance.GetButtonDef("Jump");
if (buttonDef == null || (int)buttonDef.Source != 170)
{
return false;
}
InputBinding val = ((IEnumerable<InputBinding>)(object)buttonDef.ButtonAction.bindings).FirstOrDefault();
return ZInput.instance.MapKeyFromPath(((InputBinding)(ref val)).effectivePath).Equals("rightButton");
}
}
[HarmonyPatch(typeof(Humanoid))]
internal class Q3ABoomerModifiers_FlagJumpInInventory
{
public static bool ItemFlag;
[HarmonyPatch("UseItem")]
[HarmonyPostfix]
private static void PlayerUsesItem(bool fromInventoryGui)
{
if (fromInventoryGui && Q3ABoomerHelpers.AreYouABoomer())
{
ItemFlag = true;
}
}
}
[HarmonyPatch(typeof(Character))]
internal class Q3ABoomerModifiers_StopJumpInInventory
{
[HarmonyPatch("Jump")]
[HarmonyPrefix]
private static bool StopJump(ref Character __instance)
{
if (Q3ABoomerModifiers_FlagJumpInInventory.ItemFlag && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
{
Q3ABoomerModifiers_FlagJumpInInventory.ItemFlag = false;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ItemDrop))]
internal class WeaponModifiers
{
[HarmonyPatch("SetQuality")]
[HarmonyPostfix]
private static void ModifyWeapon(ref ItemDrop __instance, int quality)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Invalid comparison between Unknown and I4
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance != (Object)null && (int)__instance.m_itemData.m_shared.m_animationState == 0 && __instance.m_itemData.m_shared.m_name.Equals("$item_fistweapon_bjorn_undead") && quality > 4)
{
__instance.m_itemData.m_shared.m_attack.m_damageMultiplierPerMissingHP = JardsAdditions.PluginConfig.BloodstoneDamagePercent.Value * 2.5f;
}
else if ((int)__instance.m_itemData.m_shared.m_animationState == 13)
{
__instance.m_itemData.m_shared.m_attack.m_staggerMultiplier = JardsAdditions.PluginConfig.GreatswordStaggerMultiplier.Value;
__instance.m_itemData.m_shared.m_attack.m_forceMultiplier = JardsAdditions.PluginConfig.GreatswordKnockbackMultiplier.Value;
__instance.m_itemData.m_shared.m_attack.m_attackAdrenaline = 2f * JardsAdditions.PluginConfig.GreatswordAdrenalineMultiplier.Value;
__instance.m_itemData.m_shared.m_secondaryAttack.m_staggerMultiplier = JardsAdditions.PluginConfig.GreatswordStaggerMultiplier.Value;
__instance.m_itemData.m_shared.m_secondaryAttack.m_forceMultiplier = JardsAdditions.PluginConfig.GreatswordKnockbackMultiplier.Value;
__instance.m_itemData.m_shared.m_secondaryAttack.m_attackAdrenaline = JardsAdditions.PluginConfig.GreatswordAdrenalineMultiplier.Value;
}
}
}
[HarmonyPatch(typeof(ItemData))]
internal class BlockForceModifiers
{
[HarmonyPatch("GetDeflectionForce", new Type[] { typeof(int) })]
[HarmonyPrefix]
private static bool NerfEmpower(ref ItemData __instance, ref float __result, int quality)
{
if (quality > 4)
{
float deflectionForce = __instance.GetDeflectionForce(4);
float num = (float)Mathf.Max(0, quality - 4) * __instance.m_shared.m_deflectionForcePerLevel;
__result = deflectionForce + num / (1f + Mathf.Log((float)(quality - 4)));
return false;
}
return true;
}
}
}
namespace JardsAdditions.CustomPatches
{
[HarmonyPatch(typeof(Humanoid))]
public class CapeColliderPatches
{
private static void AttemptAdjustRadius(Transform parent, string colliderToTry, float radius)
{
if ((Object)(object)parent != (Object)null && (Object)(object)TransformExtensions.FindDeepChild(parent, colliderToTry, (IterativeSearchType)1) != (Object)null)
{
((Component)TransformExtensions.FindDeepChild(parent, colliderToTry, (IterativeSearchType)1)).GetComponent<CapsuleCollider>().radius = radius;
}
}
private static void AttemptAdjustDisplace(Transform parent, string colliderToTry, float x, float y, float z)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)parent != (Object)null && (Object)(object)TransformExtensions.FindDeepChild(parent, colliderToTry, (IterativeSearchType)1) != (Object)null)
{
((Component)TransformExtensions.FindDeepChild(parent, colliderToTry, (IterativeSearchType)1)).GetComponent<CapsuleCollider>().center = new Vector3(x, y, z);
}
}
[HarmonyPatch("SetupVisEquipment")]
[HarmonyPostfix]
private static void ModifyColliderSize(ref Humanoid __instance)
{
if (__instance is Player)
{
Transform val = TransformExtensions.FindDeepChild(((Component)__instance).transform, "Hips", (IterativeSearchType)1);
Transform val2 = TransformExtensions.FindDeepChild(((Component)__instance).transform, "Spine1", (IterativeSearchType)1);
Transform val3 = TransformExtensions.FindDeepChild(((Component)__instance).transform, "Head", (IterativeSearchType)1);
if (__instance.m_visEquipment.m_shoulderItem.Equals("CapeJard"))
{
AttemptAdjustRadius(((Component)val).transform, "ClothCollider", 0.575f);
AttemptAdjustRadius(((Component)val).transform, "ClothColliderHips", 0.375f);
AttemptAdjustRadius(((Component)val).transform, "ClothColliderHipsCape", 0.375f);
AttemptAdjustRadius(((Component)val2).transform, "ClothCollider (3)", 0.55f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderMid", 0.25f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderMidCape", 0.25f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderRightUpArmCape", 0.8f);
AttemptAdjustDisplace(((Component)val2).transform, "ClothColliderRightUpArmCape", -0.2f, -0.15f, -0.15f);
AttemptAdjustRadius(((Component)val3).transform, "ClothColliderHead", 0f);
AttemptAdjustRadius(((Component)val3).transform, "ClothColliderHeadCape", 0f);
}
else
{
AttemptAdjustRadius(((Component)val).transform, "ClothCollider", 1.8f);
AttemptAdjustRadius(((Component)val).transform, "ClothColliderHips", 0.45f);
AttemptAdjustRadius(((Component)val).transform, "ClothColliderHipsCape", 0.5f);
AttemptAdjustRadius(((Component)val2).transform, "ClothCollider (3)", 0.8f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderMid", 0.45f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderMidCape", 0.45f);
AttemptAdjustRadius(((Component)val2).transform, "ClothColliderRightUpArmCape", 0.4f);
AttemptAdjustDisplace(((Component)val2).transform, "ClothColliderRightUpArmCape", 0f, 0f, 0f);
AttemptAdjustRadius(((Component)val3).transform, "ClothColliderHead", 0.38f);
AttemptAdjustRadius(((Component)val3).transform, "ClothColliderHeadCape", 0.5f);
}
}
}
}
}