using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ButteRyBalance.Components;
using ButteRyBalance.NetcodePatcher;
using ButteRyBalance.Network;
using ButteRyBalance.Overrides;
using ButteRyBalance.Overrides.Moons;
using ButteRyBalance.Patches;
using ButteRyBalance.Utilities;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering.HighDefinition;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("ButteRyBalance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Buttery's rebalances")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a2d55ac06ef6acf298b57dcfc257e3d5f0a993ab")]
[assembly: AssemblyProduct("ButteRyBalance")]
[assembly: AssemblyTitle("ButteRyBalance")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 ButteRyBalance
{
internal class Common
{
internal enum DamageID
{
Unknown = -1,
Shovel = 1,
Knife = 5,
Cruiser = 331
}
internal const int NUM_LEVELS = 13;
internal static bool INSTALLED_ARTIFICE_BLIZZARD;
internal static bool INSTALLED_BARBER_FIXES;
internal static bool INSTALLED_SPAWN_CYCLE_FIXES;
internal static GameObject artificeBlizzard;
internal static Dictionary<string, EnemyType> enemies = new Dictionary<string, EnemyType>();
private static Terminal terminal;
internal static List<Bounds> caveTiles = new List<Bounds>();
internal static VehicleController vehicleController;
internal static Terminal Terminal
{
get
{
if ((Object)(object)terminal == (Object)null)
{
terminal = Object.FindAnyObjectByType<Terminal>();
}
return terminal;
}
}
internal static void Disconnect()
{
enemies.Clear();
caveTiles.Clear();
}
internal static bool IsSnowLevel()
{
if (StartOfRound.Instance.currentLevel.levelIncludesSnowFootprints)
{
if (!((Object)(object)artificeBlizzard == (Object)null))
{
return artificeBlizzard.activeSelf;
}
return true;
}
return false;
}
internal static void CacheCaveTiles()
{
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
caveTiles.Clear();
if (RoundManager.Instance.currentDungeonType != 4)
{
return;
}
GameObject val = RoundManager.Instance.dungeonGenerator?.Root ?? GameObject.Find("/Systems/LevelGeneration/LevelGenerationRoot");
if ((Object)(object)val == (Object)null)
{
if (((Object)StartOfRound.Instance.currentLevel).name != "CompanyBuildingLevel")
{
Plugin.Logger.LogWarning((object)"Landed on a moon with no dungeon generated. This shouldn't happen");
}
return;
}
Tile[] componentsInChildren = val.GetComponentsInChildren<Tile>();
foreach (Tile val2 in componentsInChildren)
{
if (((Object)val2).name.StartsWith("Cave"))
{
caveTiles.Add(val2.OverrideAutomaticTileBounds ? UnityUtil.TransformBounds(((Component)val2).transform, val2.TileBoundsOverride) : val2.Bounds);
}
}
}
}
internal class Configuration
{
internal enum DineScrap
{
DontChange,
Consolidate,
Rollback
}
internal enum SnowmanFrequency
{
None,
Rare,
Lots
}
internal enum JetpackControls
{
Vanilla,
V49,
Dynamic
}
internal const int MIN_PRICE = 10;
internal const int MAX_PRICE = 250000;
private static ConfigFile configFile;
internal static ConfigEntry<bool> coilheadStunReset;
internal static ConfigEntry<bool> jesterWalkThrough;
internal static ConfigEntry<bool> butlerManorChance;
internal static ConfigEntry<bool> butlerStealthStab;
internal static ConfigEntry<bool> butlerLongCooldown;
internal static ConfigEntry<bool> jesterLongCooldown;
internal static ConfigEntry<bool> butlerKnifePrice;
internal static ConfigEntry<bool> knifeShortCooldown;
internal static ConfigEntry<bool> knifeAutoSwing;
internal static ConfigEntry<bool> maneaterLimitGrowth;
internal static ConfigEntry<bool> maneaterWideTurns;
internal static ConfigEntry<bool> maneaterScrapGrowth;
internal static ConfigEntry<bool> moonsKillSwitch;
internal static ConfigEntry<bool> dineReduceButlers;
internal static ConfigEntry<bool> barberDynamicSpawns;
internal static ConfigEntry<bool> foggyLimit;
internal static ConfigEntry<bool> experimentationNoEvents;
internal static ConfigEntry<bool> experimentationNoGiants;
internal static ConfigEntry<bool> experimentationNoEggs;
internal static ConfigEntry<bool> experimentationBuffScrap;
internal static ConfigEntry<bool> randomIndoorFog;
internal static ConfigEntry<bool> assuranceNerfScrap;
internal static ConfigEntry<bool> assuranceMasked;
internal static ConfigEntry<bool> vowNoCoils;
internal static ConfigEntry<bool> vowMineshafts;
internal static ConfigEntry<bool> offenseBuffScrap;
internal static ConfigEntry<bool> offenseMasked;
internal static ConfigEntry<bool> offenseNerfEclipse;
internal static ConfigEntry<bool> vowNoTraps;
internal static ConfigEntry<bool> marchBuffScrap;
internal static ConfigEntry<bool> butlerSquishy;
internal static ConfigEntry<bool> adamanceBuffScrap;
internal static ConfigEntry<bool> coilheadCurves;
internal static ConfigEntry<bool> rendShrink;
internal static ConfigEntry<bool> rendWorms;
internal static ConfigEntry<bool> metalSheetPrice;
internal static ConfigEntry<bool> coilheadPower;
internal static ConfigEntry<bool> dineAdjustOutdoor;
internal static ConfigEntry<bool> titanBuffScrap;
internal static ConfigEntry<bool> titanAddGold;
internal static ConfigEntry<bool> titanAdjustEnemies;
internal static ConfigEntry<bool> titanWeeds;
internal static ConfigEntry<bool> giantSnowSight;
internal static ConfigEntry<bool> dineFloods;
internal static ConfigEntry<bool> robotFog;
internal static ConfigEntry<bool> nutcrackerGunPrice;
internal static ConfigEntry<bool> nutcrackerKevlar;
internal static ConfigEntry<bool> jetpackBattery;
internal static ConfigEntry<bool> jetpackReduceDiscount;
internal static ConfigEntry<bool> artificeBuffScrap;
internal static ConfigEntry<bool> artificeInteriors;
internal static ConfigEntry<bool> artificeTurrets;
internal static ConfigEntry<bool> zapGunPrice;
internal static ConfigEntry<bool> radarBoosterPrice;
internal static ConfigEntry<bool> stunGrenadePrice;
internal static ConfigEntry<bool> scrapAdjustWeights;
internal static ConfigEntry<bool> maneaterPower;
internal static ConfigEntry<bool> embrionWeeds;
internal static ConfigEntry<bool> embrionAdjustEnemies;
internal static ConfigEntry<bool> embrionMega;
internal static ConfigEntry<bool> infestationRework;
internal static ConfigEntry<bool> infestationButlers;
internal static ConfigEntry<bool> infestationMasked;
internal static ConfigEntry<bool> infestationBarbers;
internal static ConfigEntry<bool> zapGunBattery;
internal static ConfigEntry<bool> offenseBees;
internal static ConfigEntry<bool> apparatusPrice;
internal static ConfigEntry<bool> spikeTrapDistance;
internal static ConfigEntry<bool> infestationThumpers;
internal static ConfigEntry<bool> coilheadPersistence;
internal static ConfigEntry<bool> giantSquishy;
internal static ConfigEntry<bool> hoarderAngerManagement;
internal static ConfigEntry<bool> infestationSnareFlea;
internal static ConfigEntry<bool> infestationCoilhead;
internal static ConfigEntry<bool> foxSlender;
internal static ConfigEntry<bool> adamanceNerfEclipse;
internal static ConfigEntry<bool> adamanceReduceCadavers;
internal static ConfigEntry<bool> cadaversPower;
internal static ConfigEntry<bool> pufferPower;
internal static ConfigEntry<bool> spikeTrapMineshaft;
internal static ConfigEntry<bool> jetpackUtility;
internal static ConfigEntry<bool> infestationGunkfish;
internal static ConfigEntry<bool> adamanceInteriors;
internal static ConfigEntry<bool> adamanceNoMasks;
internal static ConfigEntry<bool> offenseNerfTraps;
internal static ConfigEntry<bool> assuranceGiants;
internal static ConfigEntry<bool> dineMineshafts;
internal static ConfigEntry<bool> proFlashlightPrice;
internal static ConfigEntry<bool> vowMisty;
internal static ConfigEntry<bool> nerfNightVision;
internal static ConfigEntry<bool> marchAdjustEnemies;
internal static ConfigEntry<bool> gunkfishSquishy;
internal static ConfigEntry<bool> shovelBuffer;
internal static ConfigEntry<bool> stunLonger;
internal static ConfigEntry<bool> maneaterTarget;
internal static ConfigEntry<bool> cadaverTarget;
internal static ConfigEntry<bool> cavernsNoKeys;
internal static ConfigEntry<bool> jetpackWarmUp;
internal static ConfigEntry<bool> cruiserItemSafety;
internal static ConfigEntry<bool> cruiserExhaust;
internal static ConfigEntry<bool> cruiserRegen;
internal static ConfigEntry<bool> cruiserTrees;
internal static ConfigEntry<bool> cruiserEnemyDamage;
internal static ConfigEntry<bool> cruiserCrashDamage;
internal static ConfigEntry<DineScrap> dineScrapPool;
internal static ConfigEntry<SnowmanFrequency> rendSnowmen;
internal static ConfigEntry<SnowmanFrequency> dineSnowmen;
internal static ConfigEntry<SnowmanFrequency> titanSnowmen;
internal static ConfigEntry<int> cruiserPrice;
internal static ConfigEntry<int> jetpackPrice;
internal static ConfigEntry<JetpackControls> jetpackControls;
internal static void Init(ConfigFile cfg)
{
configFile = cfg;
MiscConfig();
InfestationConfig();
EnemyConfig();
ItemConfig();
VehicleConfig();
MoonConfig();
MigrateLegacyConfig();
}
private static void ItemConfig()
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
scrapAdjustWeights = configFile.Bind<bool>("Items", "Adjust Scrap Weights", false, "Makes some minor alterations to the weight of several scrap items.");
apparatusPrice = configFile.Bind<bool>("Item.Apparatus", "Randomize Price", false, "Randomizes the price of the apparatus once it has been unplugged.");
jetpackBattery = configFile.Bind<bool>("Item.Jetpack", "Reduce Battery", true, "Reduces jetpack battery back to 40s (from 50s), like the v50 beta.");
jetpackPrice = configFile.Bind<int>("Item.Jetpack", "Price", 900, new ConfigDescription("Alters the price of the Jetpack. $700 is the original price from launch. $900 is the current vanilla price.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 250000), Array.Empty<object>()));
jetpackReduceDiscount = configFile.Bind<bool>("Item.Jetpack", "Reduce Max Discount", true, "Jetpack price will never go beyond 60% off ($180 -> $360)");
jetpackControls = configFile.Bind<JetpackControls>("Item.Jetpack", "Control Scheme", JetpackControls.Dynamic, "Controls how the jetpacks' speed and handling are set.\n\"Vanilla\" makes no changes.\n\"V49\" restores the classic control scheme, with much stronger inertia, meaning you must pre-emptively adjust your momentum.\n\"Dynamic\" adjusts speed and handling based on your carried weight (light weight = high speed, poor handling; heavy weight = low speed, smooth handling)");
jetpackWarmUp = configFile.Bind<bool>("Item.Jetpack", "Warmup Period", true, "When first activated, jetpacks take a brief period of time to warm up to maximum thrust power, leaving you more vulnerable to enemies.");
jetpackUtility = configFile.Bind<bool>("Item.Jetpack", "No Utility Belt", true, "Blacklists the jetpack from the utility belt, like shovels. This means you can only fly 3 scraps at a time like before.");
knifeShortCooldown = configFile.Bind<bool>("Item.KitchenKnife", "Short Cooldown", true, "The knife will deal damage faster.");
knifeAutoSwing = configFile.Bind<bool>("Item.KitchenKnife", "Auto-Swing", true, "(Client-side) Holding the attack button will automatically swing the knife. When damage is dealt, your swing speed will decrease to avoid wasting hits.");
proFlashlightPrice = configFile.Bind<bool>("Item.ProFlashlight", "Nerf Price", true, "Increases the cost of pro-flashlights from $28 to $32, like the first v80 beta.");
radarBoosterPrice = configFile.Bind<bool>("Item.RadarBooster", "Buff Price", true, "Reduces the cost of the radar booster from $60 to $50, like in v40.");
shovelBuffer = configFile.Bind<bool>("Item.Shovel", "Input Buffer", true, "(Client-side) Clicking the attack button shortly before the shovel is readied will \"buffer\" your input, winding up as soon as the shovel finishes its swing.");
stunGrenadePrice = configFile.Bind<bool>("Item.StunGrenade", "Nerf Price", true, "Increases the cost of stun grenades from $30 to $40, like in v40.");
stunLonger = configFile.Bind<bool>("Item.StunGrenade", "Stun Longer", true, "Increases the effectiveness of stun grenades against certain enemies. (Like hoarding bugs and thumpers)");
metalSheetPrice = configFile.Bind<bool>("Item.MetalSheet", "Increase Value", false, "Increases the average sell value of metal sheets.");
zapGunPrice = configFile.Bind<bool>("Item.ZapGun", "Buff Price", true, "Reduces the cost of the zap gun from $400 to $200, like in v9.");
zapGunBattery = configFile.Bind<bool>("Item.ZapGun", "Increase Battery", true, "Increases zap gun battery back to 120s (from 22s), like v9.");
}
private static void VehicleConfig()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
cruiserPrice = configFile.Bind<int>("Vehicle.Cruiser", "Price", 700, new ConfigDescription("Alters the price of the Cruiser. $400 is the original price from v55 launch. $370 is the current vanilla price.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 250000), Array.Empty<object>()));
cruiserRegen = configFile.Bind<bool>("Vehicle.Cruiser", "Reduced Regeneration", true, "Sharply decreases HP regen for the Cruiser, which makes weed killer more valuable as the only source of mid-round maintenance.");
cruiserTrees = configFile.Bind<bool>("Vehicle.Cruiser", "Nature Prevails", true, "The cruiser takes damage from destroying trees again. Does *not* affect snowmen.");
cruiserEnemyDamage = configFile.Bind<bool>("Vehicle.Cruiser", "Increase Enemy Damage", true, "The cruiser takes increased damage from collision with enemies. *Does not apply* when the Cruiser is left unattended, parked and with the engine off.");
cruiserCrashDamage = configFile.Bind<bool>("Vehicle.Cruiser", "Increase Crash Damage", true, "The cruiser takes increased damage from collision with terrain or walls.");
cruiserItemSafety = configFile.Bind<bool>("Vehicle.Cruiser", "No Space Insurance", true, "When returning to orbit, items on top of the Cruiser, or in the back while the door is open, are lost.");
cruiserExhaust = configFile.Bind<bool>("Vehicle.Cruiser", "Rocking Costs Stamina", true, "When \"rocking\" the car (with the jump button), stamina will be deducted, and you are unable to rock the car when out of stamina. The stamina cost gets steeper the more the car is facing upward.");
}
private static void EnemyConfig()
{
gunkfishSquishy = configFile.Bind<bool>("Enemy.BackwaterGunkfish", "Squishy", false, "Reduce the Backwater Gunkfish's HP from 4 to 3.");
barberDynamicSpawns = configFile.Bind<bool>("Enemy.Barber", "Dynamic Spawn Settings", true, "Barbers will spawn in pairs, up to 8 total, in factories and manors. In mineshafts, they are limited to 1 total.");
butlerManorChance = configFile.Bind<bool>("Enemy.Butler", "Manor Increased Chance", true, "Butlers have an increased chance to spawn in manor interiors.");
butlerStealthStab = configFile.Bind<bool>("Enemy.Butler", "Stealth Stab", true, "When triggering a Butler to attack by bumping into it (rare chance), it will no longer \"berserk\", unless the offending player is alone.");
butlerLongCooldown = configFile.Bind<bool>("Enemy.Butler", "Slow Attacks", false, "Butlers will deal damage slower, as long as they haven't been attacked before. In singleplayer, this setting will also increase their HP from 2 to 3.");
butlerSquishy = configFile.Bind<bool>("Enemy.Butler", "Squishy", true, "Butlers take bonus damage from shotgun shots and explosions, allowing those to kill in one hit.");
butlerKnifePrice = configFile.Bind<bool>("Enemy.Butler", "Randomize Knife Price", false, "Restores the kitchen knife's price randomization. On average, it will be significantly more valuable than $35, the vanilla price.");
cadaverTarget = configFile.Bind<bool>("Enemy.CadaverBloom", "Infighting", true, "Allows Cadaver Blooms to be targeted by other enemies after bursting outside the building. (Baboon hawks, Old Birds, giant sapsucker)");
cadaversPower = configFile.Bind<bool>("Enemy.CadaverGrowths", "Increase Power Level", true, "Increase Cadaver Growths' power level from 2 to 4, to keep the day's threats more solitarily focused.");
coilheadStunReset = configFile.Bind<bool>("Enemy.Coilhead", "Stuns Reset", true, "Coil-heads will begin \"recharging\" when they are stunned by stun grenades, radar boosters, or homemade flashbangs.");
coilheadCurves = configFile.Bind<bool>("Enemy.Coilhead", "Adjust Spawn Curves", false, "Adds two multipliers to Coil-head spawn rates; one reduces their chances earlier in the day, and the other reduces the chance of multiple spawning in one day.");
coilheadPower = configFile.Bind<bool>("Enemy.Coilhead", "Increase Power Level", true, "Increase Coil-heads' power level from 1 to 2, to reduce the potential for forming bad enemy combos.");
coilheadPersistence = configFile.Bind<bool>("Enemy.Coilhead", "Persistence", false, "Coil-heads no longer recharge from just chasing players, behaving akin to their pre-v60 iteration.");
giantSnowSight = configFile.Bind<bool>("Enemy.ForestKeeper", "Treat Blizzard Like Fog", true, "On snowy moons, Forest Keepers will have their line-of-sight range reduced, the same way as in foggy weather.");
giantSquishy = configFile.Bind<bool>("Enemy.ForestKeeper", "Squishy", true, "Forest Keepers are instantly killed if the Cruiser is rammed into them at high speeds, just like before v70.");
hoarderAngerManagement = configFile.Bind<bool>("Enemy.HoardingBug", "Anger Management", true, "Hoarding bug \"annoyance\" (from player proximity) will reset when they enter chase, which makes them less likely to get stuck in an aggro loop on players who don't steal from them.");
jesterWalkThrough = configFile.Bind<bool>("Enemy.Jester", "Walk-Through", true, "Lets you walk through Jesters once they begin winding up.");
jesterLongCooldown = configFile.Bind<bool>("Enemy.Jester", "Long Cooldown", true, "Slightly increase the average time before a Jester winds, in multiplayer. Only works in games with 4 players or less.");
foxSlender = configFile.Bind<bool>("Enemy.KidnapperFox", "No Roadkill", true, "Make the kidnapper fox immune to the Company Cruiser. This is already the case in vanilla, but CruiserImproved fixes the bug causing it, which pseudo-nerfs the fox");
maneaterPower = configFile.Bind<bool>("Enemy.Maneater", "Increase Power Level", true, "Increase the Maneater's power level from 2 to 3, to reduce the potential for forming bad enemy combos.");
maneaterLimitGrowth = configFile.Bind<bool>("Enemy.Maneater", "Limit Growth", true, "Sharply limits (or completely prevents) the Maneater's ability to transform before it has been encountered by a player.");
maneaterScrapGrowth = configFile.Bind<bool>("Enemy.Maneater", "Metabolism", false, "Eating scrap will permanently reduce the speed at which a Maneater transforms from crying.");
maneaterWideTurns = configFile.Bind<bool>("Enemy.Maneater", "Limit Turn Speed", true, "Adult Maneaters will have far worse turning speed when lunging, as long as they are inside the building.");
maneaterTarget = configFile.Bind<bool>("Enemy.Maneater", "Infighting", true, "Allows Maneaters to be targeted by other enemies after transforming into an adult outside the building. (Baboon hawks, Old Birds, giant sapsucker)");
nutcrackerGunPrice = configFile.Bind<bool>("Enemy.Nutcracker", "Randomize Shotgun Price", false, "Restores randomization for the shotgun's price.");
nutcrackerKevlar = configFile.Bind<bool>("Enemy.Nutcracker", "Last Stand", false, "Nutcrackers will resist instant death from a shotgun blast if they are at full health, immediately entering \"berserk\" state.");
robotFog = configFile.Bind<bool>("Enemy.OldBird", "See Through Fog", true, "Old Birds can see through fog with their powerful searchlights.");
pufferPower = configFile.Bind<bool>("Enemy.SporeLizard", "Decrease Power Level", true, "Decrease spore lizard's power level from 1 to 0.5, as like the Backwater Gunkfish, it is mostly passive to players and only incidentally dangerous.");
}
private static void MoonConfig()
{
moonsKillSwitch = configFile.Bind<bool>("Moons", "Kill Switch", false, "If this setting is enabled, all other settings in the \"Moon\" category will be disabled. This is helpful if you want to use an external mod to configure them.");
experimentationBuffScrap = configFile.Bind<bool>("Moon.Experimentation", "Buff Scrap", true, "Increases the amount of scrap that spawns on Experimentation, like in v9. (8-11 -> 11-15)");
experimentationNoEvents = configFile.Bind<bool>("Moon.Experimentation", "No Random Events", true, "Disables all random events on Experimentation. (Meteor showers, infestations, spooky fog)");
experimentationNoGiants = configFile.Bind<bool>("Moon.Experimentation", "No Forest Keepers", true, "Forest Keepers no longer have a random chance to spawn on Experimentation.");
experimentationNoEggs = configFile.Bind<bool>("Moon.Experimentation", "No Easter Eggs", true, "Easter eggs no longer appear in Experimentation's loot pool.");
assuranceNerfScrap = configFile.Bind<bool>("Moon.Assurance", "Nerf Scrap", true, "Swaps several items' rarities with the corresponding values from Offense's loot pool.");
assuranceMasked = configFile.Bind<bool>("Moon.Assurance", "Spawn Masked", true, "Allow \"Masked\" enemies to spawn very rarely on Assurance, since Comedy and Tragedy spawn there.");
assuranceGiants = configFile.Bind<bool>("Moon.Assurance", "More Forest Giants", true, "Swaps Assurance's forest giant spawn chance with Offense's chances. This will also reduce forest giants on Offense.");
vowMineshafts = configFile.Bind<bool>("Moon.Vow", "Mostly Mineshafts", true, "Significantly reduce the likelihood of factory interiors on Vow. Fewer \"mineshaft bonus items\" will spawn, and outside spawns will be slightly increased, to compensate for increased profits.");
vowNoCoils = configFile.Bind<bool>("Moon.Vow", "No Coil-heads", true, "Coil-heads no longer have a random chance to spawn on Vow.");
vowNoTraps = configFile.Bind<bool>("Moon.Vow", "No Traps", false, "Removes landmines and turrets from Vow, like in v9.");
vowMisty = configFile.Bind<bool>("Moon.Vow", "Misty", true, "Makes Vow's natural fog much denser, like it was before v72.");
offenseBuffScrap = configFile.Bind<bool>("Moon.Offense", "Buff Scrap", true, "Swaps several items' rarities with the corresponding values from Assurance's loot pool. Also adds gold bars as a very rare spawn.");
offenseBees = configFile.Bind<bool>("Moon.Offense", "Circuit Bees", false, "Allow circuit bees to spawn on Offense, like Assurance.");
offenseMasked = configFile.Bind<bool>("Moon.Offense", "Spawn Masked", true, "Allow \"Masked\" enemies to spawn rarely on Offense, since Comedy spawns there - these rare spawns will completely replace brackens.");
offenseNerfEclipse = configFile.Bind<bool>("Moon.Offense", "Nerf Eclipse", false, "Reduces enemy spawns per \"wave\" during eclipses on Offense from 4 to 3.");
offenseNerfTraps = configFile.Bind<bool>("Moon.Offense", "Reduce Traps", true, "Reduces trap spawns (landmines and turrets) to pre-v80 spawn rates.");
marchBuffScrap = configFile.Bind<bool>("Moon.March", "Buff Scrap", false, "Slightly increase the amount and quality of scrap that spawns on March, to bring it a little closer with Adamance.");
marchAdjustEnemies = configFile.Bind<bool>("Moon.March", "Adjust Outdoor Enemies", false, "Decreases dogs and increases giants.");
adamanceReduceCadavers = configFile.Bind<bool>("Moon.Adamance", "Reduce Cadavers", true, "Cadavers are no longer guaranteed to appear when the ship lands. This greatly increases the spawn rate of other enemies to compensate.");
adamanceBuffScrap = configFile.Bind<bool>("Moon.Adamance", "Buff Scrap", true, "Increases the amount of scrap that spawns on Adamance, like before v80. (14-16 -> 16-18)");
adamanceNerfEclipse = configFile.Bind<bool>("Moon.Adamance", "Nerf Eclipse", false, "Reduces enemy spawns per \"wave\" during eclipses on Adamance from 3 to 2.");
adamanceInteriors = configFile.Bind<bool>("Moon.Adamance", "Adjust Interiors", false, "Increases mineshaft chance (like before v80) and also slightly increases manor chance (like v50 beta). Also adds butlers back to the spawn pool, as a bonus.");
adamanceNoMasks = configFile.Bind<bool>("Moon.Adamance", "No Masked", true, "\"Masked\" no longer have a random chance to spawn on Adamance.");
rendShrink = configFile.Bind<bool>("Moon.Rend", "Shrink Interior", false, "Reduces Rend's interior size multiplier from 1.8x to 1.6x.");
rendWorms = configFile.Bind<bool>("Moon.Rend", "Restore Earth Leviathans", false, "Allow Earth Leviathans, which were removed from Rend in v56, to spawn again.");
rendSnowmen = configFile.Bind<SnowmanFrequency>("Moon.Rend", "Snowmen", SnowmanFrequency.Rare, "Allow snowmen, which were removed in v70, to spawn again.");
dineScrapPool = configFile.Bind<DineScrap>("Moon.Dine", "Scrap Pool", DineScrap.Consolidate, "What sort of scrap should spawn on Dine?\n\"DontChange\" will avoid making any changes, letting vanilla or other mods take priority.\n\"Consolidate\" will use V73+'s spawn pool, but 40% as many items will spawn with 1.75x value each.\n\"Rollback\" will revert the scrap pool to what it was in ButteRyBalance before v73.");
dineMineshafts = configFile.Bind<bool>("Moon.Dine", "Dineshaft", true, "Increase the chance of mineshafts again, much like it was before v80.");
dineReduceButlers = configFile.Bind<bool>("Moon.Dine", "Reduce Butler Chance", true, "Reduces the spawn weight of Butlers on Dine. Intended to be combined with the \"Manor Increased Chance\" setting for Butlers.");
dineAdjustOutdoor = configFile.Bind<bool>("Moon.Dine", "Adjust Outdoor Enemies", true, "Decreases spawn chance for giants and increases spawn chance for Old Birds, leading to more varied outdoor gameplay.");
dineFloods = configFile.Bind<bool>("Moon.Dine", "Fix Floods", true, "Reduces the water level at the start of flooded weather days on Dine, so that the main entrance no longer starts out underwater.");
dineSnowmen = configFile.Bind<SnowmanFrequency>("Moon.Dine", "Snowmen", SnowmanFrequency.Rare, "Allow snowmen, which were removed in v70, to spawn again.");
titanBuffScrap = configFile.Bind<bool>("Moon.Titan", "Buff Scrap", true, "Increases scrap counts on Titan from 28-31 to 28-35, like in v50 betas.");
titanAddGold = configFile.Bind<bool>("Moon.Titan", "Gold Rush", false, "Adds gold bars to Titan's loot pool as a rare find.");
titanAdjustEnemies = configFile.Bind<bool>("Moon.Titan", "Adjust Enemies", true, "Slightly adjusts interior spawns to reduce the frequency of the Jester, and also increases Old Birds.");
titanWeeds = configFile.Bind<bool>("Moon.Titan", "No Vain Shrouds", true, "Disable vain shroud growth on Titan, to prevent the kidnapper fox from camping the ship.");
titanSnowmen = configFile.Bind<SnowmanFrequency>("Moon.Titan", "Snowmen", SnowmanFrequency.Rare, "Allow snowmen, which were removed in v70, to spawn again.");
artificeBuffScrap = configFile.Bind<bool>("Moon.Artifice", "Buff Scrap", true, "Restores Artifice's scrap counts from v56 (26-30 to 31-37), and also restores original gold bar spawn chance.");
artificeInteriors = configFile.Bind<bool>("Moon.Artifice", "Adjust Interiors", false, "Adjusts interior chances to make manor dominant again. (15%/35%/50% -> 15%/50%/35%) Also increases the size of manors and factories from 1.8x to 2.0x, but mineshafts are not affected.");
artificeTurrets = configFile.Bind<bool>("Moon.Artifice", "Increase Turrets", true, "Drastically increase the spawn rate of turrets, like in the v50 betas.");
embrionMega = configFile.Bind<bool>("Moon.Embrion", "Bigger on the Inside", false, "Double the interior size, dramatically increase the chance of mineshafts, and greatly increase the number of scrap items.");
embrionAdjustEnemies = configFile.Bind<bool>("Moon.Embrion", "Adjust Indoor Enemies", false, "Increase the spawn rates of non-biological enemies in the interior.");
embrionWeeds = configFile.Bind<bool>("Moon.Embrion", "No Vain Shrouds", false, "Disable vain shroud growth on Embrion, since there is limited biological life on the surface.");
}
private static void MiscConfig()
{
nerfNightVision = configFile.Bind<bool>("Misc", "Reduce Night Vision", false, "Lower the distance you can see clearly in the dark without a light source, as it was in the original v80 beta.");
foggyLimit = configFile.Bind<bool>("Misc", "Nerf Foggy Weather", true, "Reduce the maximum intensity of foggy weather.");
randomIndoorFog = configFile.Bind<bool>("Misc", "Random Indoor Fog", true, "When the indoor fog event occurs, its density will be randomized between the vanilla value and a much less extreme value.");
spikeTrapDistance = configFile.Bind<bool>("Misc", "Safely Distance Spike Traps", true, "Spike traps are no longer allowed to spawn directly on top of building entrances.");
spikeTrapMineshaft = configFile.Bind<bool>("Misc", "Mineshaft Spike Traps", false, "Spike traps will be allowed in mineshaft interiors again, like before v80. It is *strongly recommended* to use \"Safely Distance Spike Traps\" in conjunction with this setting, or else spike traps will be allowed to spawn on top of the elevator!");
cavernsNoKeys = configFile.Bind<bool>("Misc", "No Keys in Caverns", true, "Adjusts key spawns in mineshafts, so that they can no longer spawn in cavern tiles, *similar* to pre-v80 behavior.\nAlso removes the distance limit from main entrance, which will allow keys to spawn near deep fire exits, normally impossible in vanilla.");
}
private static void InfestationConfig()
{
infestationRework = configFile.Bind<bool>("Infestations", "Rework Mechanics", true, "(REQUIRES SPAWN CYCLE FIXES!) Infestations no longer override a moon's power level, and enemy spawn chances are no longer altered. The \"infestation enemy\" takes up no power level during the event, and \"bonus spawns\" only occur until the infestation enemy hits their spawn cap.");
infestationButlers = configFile.Bind<bool>("Infestations", "Butler Infestations", true, "Allow butlers to be selected as the subject of an infestation.");
infestationMasked = configFile.Bind<bool>("Infestations", "Masked Infestations", true, "Allow \"masked\" to be selected as the subject of an infestation.");
infestationBarbers = configFile.Bind<bool>("Infestations", "Barber Infestations", false, "Allow Barbers to be selected as the subject of an infestation. Other enemy spawns will be disabled. Won't occur inside mineshafts.");
infestationThumpers = configFile.Bind<bool>("Infestations", "Thumper Infestations", false, "Allow thumpers to be selected as the subject of an infestation.");
infestationSnareFlea = configFile.Bind<bool>("Infestations", "Snare Flea Infestations", false, "Allow snare fleas to be selected as the subject of an infestation.");
infestationCoilhead = configFile.Bind<bool>("Infestations", "Coil-head Infestations", false, "Allow coil-heads to be selected as the subject of an infestation.");
infestationGunkfish = configFile.Bind<bool>("Infestations", "Backwater Gunkfish Infestations", false, "Allow Backwater Gunkfish to be selected as the subject of an infestation.");
}
private static void MigrateLegacyConfig()
{
if (foggyLimit.Value)
{
if (!configFile.Bind<bool>("Misc", "Rework Foggy Weather", true, "Legacy setting, doesn't work").Value)
{
foggyLimit.Value = false;
}
configFile.Remove(configFile["Misc", "Rework Foggy Weather"].Definition);
}
if (!adamanceNerfEclipse.Value)
{
if (configFile.Bind<bool>("Moon.Adamance", "Reduce Chaos", false, "Legacy setting, doesn't work").Value)
{
adamanceNerfEclipse.Value = true;
}
configFile.Remove(configFile["Moon.Adamance", "Reduce Chaos"].Definition);
}
(string, string)[] array = new(string, string)[22]
{
("Enemy.ForestKeeper", "Forget Out-of-Sight Players"),
("Item.TZPInhalant", "Expand Capacity"),
("Moon.Dine", "Buff Scrap"),
("Enemy.OldBird", "Restore Mech Riding"),
("Moon.March", "Shrink Interior"),
("Moon.March", "Always Rainy"),
("Misc", "Multiplayer Weather Multiplier"),
("Moon.Offense", "Mostly Mineshafts"),
("Misc", "Shrink Mineshafts"),
("Moon.Vow", "Adjust Scrap"),
("Moon.Experimentation", "No Nutcrackers"),
("Moon.Rend", "Rare Mineshafts"),
("Moon.Rend", "Adjust Scrap"),
("Moon.Dine", "Adjust Indoor Enemies"),
("Moon.Dine", "Adjust Spawn Curves"),
("Moon.Dine", "Add Masked"),
("Moon.Embrion", "Buff Scrap"),
("Moon.Embrion", "Increase Mineshafts"),
("Moon.Rend", "Adjust Indoor Enemies"),
("Enemy.KidnapperFox", "Squishy"),
("Moon.Titan", "Reduce Mineshafts"),
("Item.Jetpack", "v49 Controls")
};
for (int i = 0; i < array.Length; i++)
{
(string, string) tuple = array[i];
try
{
configFile.Bind<string>(tuple.Item1, tuple.Item2, string.Empty, "Legacy setting, doesn't work");
configFile.Remove(configFile[tuple.Item1, tuple.Item2].Definition);
}
catch
{
Plugin.Logger.LogWarning((object)("Can't delete \"" + tuple.Item1 + "\" - \"" + tuple.Item2 + "\" from config"));
}
}
configFile.Save();
}
}
internal static class LobbyCompatibility
{
internal static void Init()
{
PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.butterybalance", Version.Parse("0.5.0"), (CompatibilityLevel)2, (VersionStrictness)3);
}
}
[BepInPlugin("butterystancakes.lethalcompany.butterybalance", "ButteRyBalance", "0.5.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.butterybalance";
internal const string PLUGIN_NAME = "ButteRyBalance";
internal const string PLUGIN_VERSION = "0.5.0";
internal static ManualLogSource Logger;
private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";
private const string GUID_ARTIFICE_BLIZZARD = "butterystancakes.lethalcompany.artificeblizzard";
private const string GUID_BARBER_FIXES = "butterystancakes.lethalcompany.barberfixes";
private const string GUID_SPAWN_CYCLE_FIXES = "butterystancakes.lethalcompany.spawncyclefixes";
internal const string GUID_BUTTERY_FIXES = "butterystancakes.lethalcompany.butteryfixes";
internal const string GUID_LETHAL_FIXES = "uk.1a3.lethalfixes";
private void Awake()
{
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
NetcodePatch();
Logger = ((BaseUnityPlugin)this).Logger;
if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
{
Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
LobbyCompatibility.Init();
}
if (Chainloader.PluginInfos.ContainsKey("butterystancakes.lethalcompany.artificeblizzard"))
{
Logger.LogInfo((object)"CROSS-COMPATIBILITY - Artifice Blizzard detected");
Common.INSTALLED_ARTIFICE_BLIZZARD = true;
}
if (Chainloader.PluginInfos.ContainsKey("butterystancakes.lethalcompany.barberfixes"))
{
Logger.LogInfo((object)"CROSS-COMPATIBILITY - Barber Fixes detected");
Common.INSTALLED_BARBER_FIXES = true;
}
if (Chainloader.PluginInfos.ContainsKey("butterystancakes.lethalcompany.spawncyclefixes"))
{
Logger.LogInfo((object)"CROSS-COMPATIBILITY - Spawn Cycle Fixes detected");
Common.INSTALLED_SPAWN_CYCLE_FIXES = true;
}
Configuration.Init(((BaseUnityPlugin)this).Config);
new Harmony("butterystancakes.lethalcompany.butterybalance").PatchAll();
Logger.LogInfo((object)"ButteRyBalance v0.5.0 loaded");
}
private void NetcodePatch()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
for (int i = 0; i < types.Length; i++)
{
MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "ButteRyBalance";
public const string PLUGIN_NAME = "ButteRyBalance";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace ButteRyBalance.Utilities
{
internal static class KeySpawner
{
internal static void PostProcessKeyNodes(ref GameObject[] nodes, ref int count)
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
if (!((NetworkBehaviour)RoundManager.Instance).IsServer || !Configuration.cavernsNoKeys.Value)
{
return;
}
try
{
List<GameObject> list = new List<GameObject>(nodes);
List<GameObject> list2 = new List<GameObject>();
if (list.Count < 1)
{
Plugin.Logger.LogWarning((object)"Key spawner was fed an invalid array of nodes - this shouldn't happen");
list = new List<GameObject>(RoundManager.Instance.insideAINodes);
}
bool flag = false;
for (int num = list.Count - 1; num >= 0; num--)
{
if ((Object)(object)list[num] == (Object)null)
{
list.RemoveAt(num);
}
else
{
foreach (Bounds caveTile in Common.caveTiles)
{
Bounds current = caveTile;
if (((Bounds)(ref current)).Contains(list[num].transform.position))
{
list.RemoveAt(num);
flag = true;
break;
}
}
if (flag)
{
flag = false;
}
else
{
GameObject[] allCaveNodes = RoundManager.Instance.allCaveNodes;
foreach (GameObject val in allCaveNodes)
{
float num2 = Vector3.Distance(list[num].transform.position, val.transform.position);
if (num2 < 12f)
{
if (num2 > 8f)
{
list2.Add(list[num]);
}
list.RemoveAt(num);
break;
}
}
}
}
}
if (list.Count < 1)
{
if (list2.Count > 0)
{
Plugin.Logger.LogDebug((object)$"Key spawn nodes: {count} -> {list2.Count} (BACKUP)");
nodes = list2.ToArray();
count = nodes.Length;
}
else
{
Plugin.Logger.LogWarning((object)"Ignoring \"No Keys in Caverns\" for this round, because there are no valid nodes outside of cavern tiles");
}
}
else
{
Plugin.Logger.LogDebug((object)$"Key spawn nodes: {count} -> {list.Count}");
nodes = list.ToArray();
count = nodes.Length;
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)"An error occurred while filtering key spawns");
Plugin.Logger.LogError((object)ex);
}
}
}
}
namespace ButteRyBalance.Patches
{
[HarmonyPatch(typeof(GameNetworkManager))]
internal static class GameNetworkManagerPatches
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void GameNetworkManager_Post_Start()
{
BRBNetworker.Init();
}
[HarmonyPatch("Disconnect")]
[HarmonyPostfix]
private static void GameNetworkManager_Post_Disconnect()
{
if ((Object)(object)RoundManager.Instance != (Object)null && ((NetworkBehaviour)RoundManager.Instance).IsServer)
{
InfestationOverrides.EndInfestation();
}
Common.Disconnect();
}
}
[HarmonyPatch(typeof(RoundManager))]
internal class RoundManagerPatches
{
[HarmonyPatch("RefreshEnemiesList")]
[HarmonyPostfix]
private static void RoundManager_Post_RefreshEnemiesList(RoundManager __instance)
{
InfestationOverrides.EndInfestation();
Random random = new Random(StartOfRound.Instance.randomMapSeed + 5781);
if (((Object)__instance.currentLevel).name == "ExperimentationLevel" && BRBNetworker.Instance.ExperimentationNoEvents.Value && !BRBNetworker.Instance.MoonsKillSwitch.Value)
{
__instance.enemyRushIndex = -1;
__instance.currentMaxInsidePower = __instance.currentLevel.maxEnemyPowerCount;
((Component)__instance.indoorFog).gameObject.SetActive(false);
}
else
{
if (((NetworkBehaviour)__instance).IsServer && (__instance.enemyRushIndex >= 0 || (((Object)__instance.currentLevel).name == "EmbrionLevel" && BRBNetworker.Instance.EmbrionMega.Value && random.Next(100) <= 8)) && Configuration.infestationRework.Value && Common.INSTALLED_SPAWN_CYCLE_FIXES)
{
InfestationOverrides.CustomInfestation((__instance.enemyRushIndex >= 0 && ((Object)__instance.currentLevel.Enemies[__instance.enemyRushIndex].enemyType).name == "ClaySurgeon") ? __instance.enemyRushIndex : (-1));
}
if (((Component)__instance.indoorFog).gameObject.activeSelf && BRBNetworker.Instance.RandomIndoorFog.Value)
{
__instance.indoorFog.parameters.meanFreePath = random.Next(5, 11);
}
}
if (!((NetworkBehaviour)__instance).IsServer || !Configuration.barberDynamicSpawns.Value)
{
return;
}
if (Common.enemies.TryGetValue("ClaySurgeon", out var value))
{
if (RoundManager.Instance.currentDungeonType == 4 && InfestationOverrides.GetInfesterName() != "ClaySurgeon")
{
value.MaxCount = 1;
value.spawnInGroupsOf = 1;
Plugin.Logger.LogDebug((object)"Barber - Dynamic Spawn Settings: 1/1 (Mineshaft)");
}
else if (Common.INSTALLED_BARBER_FIXES)
{
value.MaxCount = 8;
if (Common.INSTALLED_SPAWN_CYCLE_FIXES)
{
value.spawnInGroupsOf = 2;
Plugin.Logger.LogDebug((object)$"Barber - Dynamic Spawn Settings: 2/8 (Interior ID: {RoundManager.Instance.currentDungeonType})");
}
else
{
Plugin.Logger.LogWarning((object)"Can't increase Barber spawn group because Spawn Cycle Fixes is not loaded. Please install it and make sure it works correctly");
}
}
else
{
Plugin.Logger.LogWarning((object)"Can't increase Barber max count because Barber Fixes is not loaded. Please install it and make sure it works correctly, or disable \"Dynamic Spawn Settings\" in the \"Enemy.Barber\" config");
}
}
else
{
Plugin.Logger.LogWarning((object)"Failed to reference Barber enemy type. This should never happen");
}
}
[HarmonyPatch("GenerateNewFloor")]
[HarmonyPrefix]
private static void RoundManager_Pre_GenerateNewFloor(RoundManager __instance)
{
if (BRBNetworker.Instance.MoonsKillSwitch.Value)
{
return;
}
switch (((Object)__instance.currentLevel).name)
{
case "VowLevel":
if (BRBNetworker.Instance.VowMineshafts.Value)
{
MoonOverrides.AdjustInteriors(__instance.currentLevel, VowOverrides.adjustedInteriors);
}
break;
case "AdamanceLevel":
if (BRBNetworker.Instance.AdamanceInteriors.Value)
{
MoonOverrides.AdjustInteriors(__instance.currentLevel, AdamanceOverrides.adjustedInteriors);
}
break;
case "DineLevel":
if (BRBNetworker.Instance.DineMineshafts.Value)
{
MoonOverrides.AdjustInteriors(__instance.currentLevel, DineOverrides.adjustedInteriors);
}
break;
case "ArtificeLevel":
if (BRBNetworker.Instance.ArtificeInteriors.Value)
{
MoonOverrides.AdjustInteriors(__instance.currentLevel, ArtificeOverrides.adjustedInteriors);
}
break;
case "EmbrionLevel":
if (BRBNetworker.Instance.EmbrionMega.Value)
{
MoonOverrides.AdjustInteriors(__instance.currentLevel, EmbrionOverrides.adjustedInteriors);
}
break;
}
}
[HarmonyPatch("FinishGeneratingNewLevelClientRpc")]
[HarmonyPostfix]
private static void RoundManager_Post_FinishGeneratingNewLevelClientRpc(RoundManager __instance)
{
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_034b: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
if (((Object)StartOfRound.Instance.currentLevel).name == "ArtificeLevel" && Common.INSTALLED_ARTIFICE_BLIZZARD)
{
Common.artificeBlizzard = GameObject.Find("/Systems/Audio/BlizzardAmbience");
if ((Object)(object)Common.artificeBlizzard != (Object)null)
{
Plugin.Logger.LogDebug((object)"Artifice Blizzard compatibility success");
}
}
string text = "/Environment/Lighting/BrightDay/Local Volumetric Fog";
if (StartOfRound.Instance.currentLevel.sceneName == "Level3Vow")
{
if (BRBNetworker.Instance.VowMisty.Value)
{
GameObject obj = GameObject.Find(text);
LocalVolumetricFog val = ((obj != null) ? obj.GetComponent<LocalVolumetricFog>() : null);
if ((Object)(object)val != (Object)null)
{
val.parameters.meanFreePath = 15.1f;
}
}
}
else if (StartOfRound.Instance.currentLevel.sceneName == "Level5Rend")
{
GameObject val2 = GameObject.Find(text + " (2)");
if ((Object)(object)val2 != (Object)null)
{
val2.SetActive(false);
}
}
else if (StartOfRound.Instance.currentLevel.sceneName == "Level10Adamance")
{
if ((Object)(object)__instance.mapPropsContainer == (Object)null)
{
__instance.mapPropsContainer = GameObject.FindGameObjectWithTag("MapPropsContainer");
}
Object.Instantiate<GameObject>(__instance.quicksandPrefab, new Vector3(-117.79688f, -23.5f, 51.95452f), Quaternion.identity, __instance.mapPropsContainer.transform);
}
if (((NetworkBehaviour)__instance).IsServer)
{
if (Configuration.spikeTrapDistance.Value)
{
SpikeRoofTrap[] array = Object.FindObjectsByType<SpikeRoofTrap>((FindObjectsSortMode)0);
EntranceTeleport[] array2 = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0);
MineshaftElevatorController val3 = __instance.currentMineshaftElevator ?? Object.FindAnyObjectByType<MineshaftElevatorController>();
SpikeRoofTrap[] array3 = array;
foreach (SpikeRoofTrap val4 in array3)
{
bool flag = false;
if ((Object)(object)val3?.elevatorBottomPoint != (Object)null && Vector3.Distance(((Component)val4.spikeTrapAudio).transform.position, val3.elevatorBottomPoint.position) < 7f)
{
Plugin.Logger.LogDebug((object)$"Spike trap #{((Object)val4).GetInstanceID()} will be destroyed (too close to the elevator)");
flag = true;
}
if (!flag)
{
EntranceTeleport[] array4 = array2;
foreach (EntranceTeleport val5 in array4)
{
if (!val5.isEntranceToBuilding && !((Object)(object)val5.entrancePoint == (Object)null) && Vector3.Distance(((Component)val4.spikeTrapAudio).transform.position, val5.entrancePoint.position) < 4.5f)
{
flag = true;
Plugin.Logger.LogDebug((object)$"Spike trap #{((Object)val4).GetInstanceID()} will be destroyed (too close to entrance \"{((Object)val5).name}\")");
break;
}
}
}
if (flag)
{
NetworkObject componentInParent = ((Component)val4).GetComponentInParent<NetworkObject>();
if ((Object)(object)componentInParent != (Object)null && componentInParent.IsSpawned)
{
componentInParent.Despawn(true);
}
else
{
Plugin.Logger.LogWarning((object)"Error occurred while despawning spike trap (could not find network object, or it was not network spawned yet)");
}
}
}
}
if ((__instance.currentDungeonType == 0 || __instance.currentDungeonType == 2 || __instance.currentDungeonType == 3) && BRBNetworker.Instance.ApparatusPrice.Value)
{
LungProp componentInChildren = __instance.mapPropsContainer.GetComponentInChildren<LungProp>();
if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isLungDocked && ((GrabbableObject)componentInChildren).scrapValue == 80)
{
BRBNetworker.Instance.SyncScrapPriceRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)componentInChildren).NetworkObject), new Random(StartOfRound.Instance.randomMapSeed).Next(40, 131), node: false);
}
}
}
Common.CacheCaveTiles();
}
[HarmonyPatch("SpawnOutsideHazards")]
[HarmonyPrefix]
private static void RoundManager_Pre_SpawnOutsideHazards(RoundManager __instance)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
if (__instance.currentLevel.levelID >= 13)
{
return;
}
if ((Object)(object)RoundManager.Instance?.mapPropsContainer == (Object)null)
{
Plugin.Logger.LogWarning((object)"Can't create SpawnDenialPoint(s) because mapPropsContainer is missing, this *might* cause desync with other clients");
return;
}
EntranceTeleport[] array = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0);
foreach (EntranceTeleport val in array)
{
if (val.isEntranceToBuilding)
{
CreateSpawnDenialPoint(val.entrancePoint.position);
Plugin.Logger.LogDebug((object)(((Object)__instance.currentLevel).name + ": SpawnDenialPoint (Entrance)"));
}
}
InteractTrigger[] array2 = Object.FindObjectsByType<InteractTrigger>((FindObjectsSortMode)0);
foreach (InteractTrigger val2 in array2)
{
if (val2.isLadder && (Object)(object)val2.bottomOfLadderPosition != (Object)null)
{
CreateSpawnDenialPoint(val2.bottomOfLadderPosition.position);
Plugin.Logger.LogDebug((object)(((Object)__instance.currentLevel).name + ": SpawnDenialPoint (Ladder)"));
}
}
if (!BRBNetworker.Instance.MoonsKillSwitch.Value)
{
int num = ((Object)__instance.currentLevel).name switch
{
"RendLevel" => BRBNetworker.Instance.RendSnowmen.Value,
"DineLevel" => BRBNetworker.Instance.DineSnowmen.Value,
"TitanLevel" => BRBNetworker.Instance.TitanSnowmen.Value,
_ => 0,
};
if (num > 0)
{
MoonOverrides.RestoreSnowmen(__instance.currentLevel, num > 1);
}
}
}
private static void CreateSpawnDenialPoint(Vector3 pos)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
Transform transform = new GameObject("SpawnDenialPointBRB")
{
tag = "SpawnDenialPoint"
}.transform;
transform.SetParent(RoundManager.Instance.mapPropsContainer.transform);
transform.position = pos;
}
[HarmonyPatch("PlotOutEnemiesForNextHour")]
[HarmonyPrefix]
private static void RoundManager_Pre_PlotOutEnemiesForNextHour(RoundManager __instance, ref bool __state)
{
__state = false;
if (((NetworkBehaviour)__instance).IsServer)
{
InfestationOverrides.SpawnInfestationWave();
if (((Object)__instance.currentLevel).name == "AdamanceLevel" && Configuration.adamanceReduceCadavers.Value && __instance.minEnemiesToSpawn < 1 && __instance.timeScript.hour > __instance.hourTimeBetweenEnemySpawnBatches && new Random(__instance.playersManager.randomMapSeed / Mathf.RoundToInt((float)__instance.timeScript.hour * __instance.timeScript.lengthOfHours)).NextDouble() < 0.8)
{
__state = true;
__instance.minEnemiesToSpawn = 1;
Plugin.Logger.LogDebug((object)("Adamance: Force inside spawn this batch (" + HUDManager.Instance.GetClockTimeFormatted(__instance.timeScript.normalizedTimeOfDay, (float)__instance.timeScript.numberOfHours, false) + ")"));
}
}
}
[HarmonyPatch("PlotOutEnemiesForNextHour")]
[HarmonyPostfix]
private static void RoundManager_Post_PlotOutEnemiesForNextHour(RoundManager __instance, bool __state)
{
if (__state)
{
__instance.minEnemiesToSpawn = 0;
}
}
[HarmonyPatch("SpawnEnemiesOutside")]
[HarmonyPostfix]
private static void RoundManager_Post_SpawnEnemiesOutside(RoundManager __instance)
{
if (((NetworkBehaviour)__instance).IsServer && __instance.allEnemyVents.Length != 0 && __instance.cannotSpawnMoreInsideEnemies)
{
InfestationOverrides.SpawnInfestationWave();
}
}
[HarmonyPatch("SpawnScrapInLevel")]
[HarmonyPrefix]
private static void RoundManager_Pre_SpawnScrapInLevel(RoundManager __instance, ref float[] __state)
{
__state = new float[2] { 1f, 1f };
if (BRBNetworker.Instance.MoonsKillSwitch.Value)
{
return;
}
switch (((Object)__instance.currentLevel).name)
{
case "VowLevel":
if (BRBNetworker.Instance.VowMineshafts.Value)
{
if (__instance.currentDungeonType != 4)
{
__instance.currentLevel.minScrap = 12;
__instance.currentLevel.maxScrap = 15;
}
else
{
__instance.currentLevel.minScrap = 10;
__instance.currentLevel.maxScrap = 13;
}
}
break;
case "AdamanceLevel":
if (Configuration.adamanceBuffScrap.Value)
{
if (__instance.currentDungeonType != 4 || !BRBNetworker.Instance.AdamanceInteriors.Value)
{
__instance.currentLevel.minScrap = 16;
__instance.currentLevel.maxScrap = 19;
}
else
{
__instance.currentLevel.minScrap = 14;
__instance.currentLevel.maxScrap = 17;
}
}
break;
case "DineLevel":
if (Configuration.dineScrapPool.Value == Configuration.DineScrap.Rollback)
{
break;
}
if (__instance.currentLevel.minScrap >= 200)
{
if (__instance.currentDungeonType != 4 || !BRBNetworker.Instance.DineMineshafts.Value)
{
__instance.currentLevel.minScrap = 200;
__instance.currentLevel.maxScrap = 250;
}
else
{
__instance.currentLevel.minScrap = 220;
__instance.currentLevel.maxScrap = 270;
}
}
if (Configuration.dineScrapPool.Value == Configuration.DineScrap.Consolidate)
{
__state[0] *= 0.4f;
__instance.scrapAmountMultiplier *= __state[0];
__state[1] *= 1.75f;
__instance.scrapValueMultiplier *= __state[1];
}
break;
case "TitanLevel":
if (Configuration.titanBuffScrap.Value)
{
if (__instance.currentDungeonType != 4)
{
__instance.currentLevel.minScrap = 28;
__instance.currentLevel.maxScrap = 36;
}
else
{
__instance.currentLevel.minScrap = 28;
__instance.currentLevel.maxScrap = 32;
}
}
break;
case "ArtificeLevel":
if (Configuration.artificeBuffScrap.Value)
{
if (__instance.currentDungeonType != 4)
{
__instance.currentLevel.minScrap = 31;
__instance.currentLevel.maxScrap = 38;
}
else
{
__instance.currentLevel.minScrap = 26;
__instance.currentLevel.maxScrap = 31;
}
}
break;
}
}
[HarmonyPatch("SpawnScrapInLevel")]
[HarmonyPostfix]
private static void RoundManager_Post_SpawnScrapInLevel(RoundManager __instance, float[] __state)
{
BRBNetworker.Instance.SetScanValueMultiplierRpc(__instance.scrapValueMultiplier);
__instance.scrapAmountMultiplier /= __state[0];
__instance.scrapValueMultiplier /= __state[1];
}
[HarmonyPatch("SetLockedDoors")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> RoundManager_Trans_SetLockedDoors(IEnumerable<CodeInstruction> instructions)
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
for (int i = 5; i < list.Count - 2; i++)
{
if (list[i].opcode == OpCodes.Div && list[i - 1].opcode == OpCodes.Ldc_I4_3 && list[i - 3].opcode == OpCodes.Ldlen)
{
list.InsertRange(i + 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldloca_S, list[i - 4].operand),
new CodeInstruction(OpCodes.Ldloca_S, list[i + 1].operand),
new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(KeySpawner), "PostProcessKeyNodes", (Type[])null, (Type[])null))
}));
Plugin.Logger.LogDebug((object)"Transpiler (Locked doors): Post process key spawns");
return list;
}
}
Plugin.Logger.LogWarning((object)"Locked doors transpiler failed");
return instructions;
}
[HarmonyPatch("DespawnPropsAtEndOfRound")]
[HarmonyPostfix]
private static void RoundManager_Post_DespawnPropsAtEndOfRound(RoundManager __instance)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
if (!((NetworkBehaviour)__instance).IsServer || !Configuration.cruiserItemSafety.Value || !((Object)(object)__instance.playersManager?.attachedVehicle != (Object)null) || __instance.playersManager.attachedVehicle.vehicleID != 0)
{
return;
}
Bounds bounds = __instance.playersManager.attachedVehicle.ontopOfTruckCollider.bounds;
VehicleController attachedVehicle = __instance.playersManager.attachedVehicle;
GrabbableObject[] array = ((attachedVehicle != null) ? ((Component)attachedVehicle).GetComponentsInChildren<GrabbableObject>() : null);
foreach (GrabbableObject val in array)
{
if (__instance.playersManager.attachedVehicle.backDoorOpen || ((Bounds)(ref bounds)).ClosestPoint(((Component)val).transform.position) == ((Component)val).transform.position)
{
Plugin.Logger.LogDebug((object)$"Cruiser item \"{((Object)val).name}\" (#{((Object)val).GetInstanceID()}) lost in orbit");
if ((Object)(object)((NetworkBehaviour)val).NetworkObject != (Object)null && ((NetworkBehaviour)val).NetworkObject.IsSpawned)
{
((NetworkBehaviour)val).NetworkObject.Despawn(true);
}
else
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
}
[HarmonyPatch("DestroyTreeAtPosition")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> RoundManager_Trans_DestroyTreeAtPosition(IEnumerable<CodeInstruction> instructions)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
FieldInfo fieldInfo = AccessTools.Field(typeof(RoundManager), "breakTreeAudio2");
for (int i = 0; i < list.Count - 2; i++)
{
if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == fieldInfo)
{
list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(VehicleControllerPatches), "JustDestroyedTree", (Type[])null, (Type[])null)));
Plugin.Logger.LogDebug((object)"Transpiler (Destroy tree): Send signal to Cruiser");
return list;
}
}
Plugin.Logger.LogWarning((object)"Destroy tree transpiler failed");
return instructions;
}
}
[HarmonyPatch(typeof(RuntimeDungeon))]
internal static class RuntimeDungeonPatches
{
[HarmonyPatch("Generate")]
[HarmonyPrefix]
private static void RuntimeDungeon_Pre_Generate(RuntimeDungeon __instance)
{
if (!BRBNetworker.Instance.MoonsKillSwitch.Value)
{
switch (((Object)RoundManager.Instance.currentLevel).name)
{
case "RendLevel":
if (BRBNetworker.Instance.RendShrink.Value)
{
DungeonGenerator generator2 = __instance.Generator;
generator2.LengthMultiplier /= 1.125f;
Plugin.Logger.LogDebug((object)"Shrink Rend");
}
break;
case "ArtificeLevel":
if (RoundManager.Instance.currentDungeonType != 4 && BRBNetworker.Instance.ArtificeInteriors.Value)
{
DungeonGenerator generator3 = __instance.Generator;
generator3.LengthMultiplier /= 0.9f;
Plugin.Logger.LogDebug((object)"Increase Artifice factory/manor");
}
break;
case "EmbrionLevel":
if (BRBNetworker.Instance.EmbrionMega.Value)
{
switch (RoundManager.Instance.currentDungeonType)
{
case 0:
__instance.Generator.LengthMultiplier = 2.35f * RoundManager.Instance.mapSizeMultiplier;
break;
case 1:
__instance.Generator.LengthMultiplier = 2.4f * RoundManager.Instance.mapSizeMultiplier;
break;
case 4:
__instance.Generator.LengthMultiplier = 2.4444447f * RoundManager.Instance.mapSizeMultiplier;
break;
default:
{
DungeonGenerator generator = __instance.Generator;
generator.LengthMultiplier *= 2f;
break;
}
}
}
break;
}
}
__instance.Generator.LengthMultiplier = Mathf.Floor(__instance.Generator.LengthMultiplier * 100f) / 100f;
Plugin.Logger.LogDebug((object)$"Final length multiplier: {__instance.Generator.LengthMultiplier} (Interior #{RoundManager.Instance.currentDungeonType}, seed: {StartOfRound.Instance.randomMapSeed})");
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal static class StartOfRoundPatches
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void StartOfRound_Post_Awake(StartOfRound __instance)
{
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Expected O, but got Unknown
//IL_0229: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Expected O, but got Unknown
if (Common.enemies.Count < 1)
{
SelectableLevel val = Object.FindAnyObjectByType<QuickMenuManager>()?.testAllEnemiesLevel;
if ((Object)(object)val != (Object)null)
{
List<SpawnableEnemyWithRarity>[] array = new List<SpawnableEnemyWithRarity>[3] { val.Enemies, val.OutsideEnemies, val.DaytimeEnemies };
for (int i = 0; i < array.Length; i++)
{
foreach (SpawnableEnemyWithRarity item in array[i])
{
if (!Common.enemies.ContainsKey(((Object)item.enemyType).name))
{
Common.enemies.Add(((Object)item.enemyType).name, item.enemyType);
}
}
}
}
}
EnemyType masked = Common.enemies["MaskedPlayerEnemy"];
EnemyType butler = Common.enemies["Butler"];
if ((Object)(object)masked != (Object)null && (Object)(object)butler != (Object)null)
{
SelectableLevel[] levels = __instance.levels;
foreach (SelectableLevel val2 in levels)
{
if ((Object)(object)masked != (Object)null && (val2.sceneName == "Level2Assurance" || val2.sceneName == "Level7Offense") && !val2.Enemies.Any((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType == (Object)(object)masked))
{
val2.Enemies.Add(new SpawnableEnemyWithRarity(masked, 0));
Plugin.Logger.LogDebug((object)("Added Masked to " + ((Object)val2).name + " pool on client (fallback)"));
}
else if ((Object)(object)butler != (Object)null && val2.sceneName == "Level10Adamance" && !val2.Enemies.Any((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType == (Object)(object)butler))
{
val2.Enemies.Add(new SpawnableEnemyWithRarity(butler, 0));
Plugin.Logger.LogDebug((object)("Added butlers to " + ((Object)val2).name + " pool on client (fallback)"));
}
}
}
else
{
Plugin.Logger.LogWarning((object)"Failed to reference \"masked\" or butler enemy types. This should never happen");
}
BRBNetworker.Create();
}
}
[HarmonyPatch(typeof(Terminal))]
internal static class TerminalPatches
{
internal static float fakeValueMultiplier = 0.4f;
[HarmonyPatch("TextPostProcess")]
[HarmonyPrefix]
[HarmonyBefore(new string[] { "butterystancakes.lethalcompany.butteryfixes", "uk.1a3.lethalfixes" })]
[HarmonyPriority(500)]
private static void Terminal_Pre_TextPostProcess(ref float __state)
{
__state = RoundManager.Instance.scrapValueMultiplier;
RoundManager.Instance.scrapValueMultiplier = fakeValueMultiplier;
}
[HarmonyPatch("TextPostProcess")]
[HarmonyPostfix]
private static void Terminal_Post_TextPostProcess(float __state)
{
RoundManager.Instance.scrapValueMultiplier = __state;
}
[HarmonyPatch("SetItemSales")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Terminal_Trans_SetItemSales(IEnumerable<CodeInstruction> instructions)
{
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Expected O, but got Unknown
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
MethodInfo methodInfo = AccessTools.DeclaredPropertyGetter(typeof(List<int>), "Count");
MethodInfo methodInfo2 = AccessTools.Method(typeof(Random), "Next", new Type[2]
{
typeof(int),
typeof(int)
}, (Type[])null);
MethodInfo methodInfo3 = AccessTools.Method(typeof(List<int>), "RemoveAt", (Type[])null, (Type[])null);
bool flag = false;
bool flag2 = false;
for (int i = 4; i < list.Count - 1; i++)
{
if (list[i].opcode == OpCodes.Callvirt)
{
if (!flag && list[i].operand as MethodInfo == methodInfo2 && list[i - 1].opcode == OpCodes.Callvirt && list[i - 1].operand as MethodInfo == methodInfo)
{
list.Insert(i + 1, new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.DeclaredPropertyGetter(typeof(List<int>), "Item")));
list.Insert(i - 4, new CodeInstruction(list[i - 2].opcode, list[i - 2].operand));
i++;
flag = true;
}
else if (!flag2 && list[i].operand as MethodInfo == methodInfo3)
{
list[i].operand = AccessTools.Method(typeof(List<int>), "Remove", (Type[])null, (Type[])null);
list.Insert(i + 1, new CodeInstruction(OpCodes.Pop, (object)null));
i++;
flag2 = true;
}
}
if (flag && flag2)
{
Plugin.Logger.LogDebug((object)"Transpiler (Terminal): Fix discount calculations");
return list;
}
}
Plugin.Logger.LogWarning((object)"Terminal transpiler failed");
return instructions;
}
}
[HarmonyPatch(typeof(TimeOfDay))]
internal static class TimeOfDayPatches
{
[HarmonyPatch("SetWeatherBasedOnVariables")]
[HarmonyPrefix]
private static void TimeOfDay_Pre_SetWeatherBasedOnVariables(TimeOfDay __instance)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Invalid comparison between Unknown and I4
if (!StartOfRound.Instance.isChallengeFile && !BRBNetworker.Instance.MoonsKillSwitch.Value && ((Object)RoundManager.Instance.currentLevel).name == "DineLevel" && (int)__instance.currentLevelWeather == 4 && BRBNetworker.Instance.DineFloods.Value)
{
TimeOfDay.Instance.currentWeatherVariable = -16f;
TimeOfDay.Instance.currentWeatherVariable2 = -5f;
}
}
[HarmonyPatch("SetWeatherBasedOnVariables")]
[HarmonyPostfix]
private static void TimeOfDay_Post_SetWeatherBasedOnVariables(TimeOfDay __instance)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Invalid comparison between Unknown and I4
if ((int)StartOfRound.Instance.currentLevel.currentWeather == 3 && ((Behaviour)__instance.foggyWeather).enabled && BRBNetworker.Instance.FoggyLimit.Value)
{
__instance.foggyWeather.parameters.meanFreePath = Mathf.Max(__instance.foggyWeather.parameters.meanFreePath, 7f);
}
}
[HarmonyPatch("DecideRandomDayEvents")]
[HarmonyPrefix]
private static bool TimeOfDay_Pre_DecideRandomDayEvents(TimeOfDay __instance)
{
if (((NetworkBehaviour)__instance).IsServer && Configuration.experimentationNoEvents.Value)
{
return !BRBNetworker.Instance.MoonsKillSwitch.Value;
}
return true;
}
}
[HarmonyPatch(typeof(VehicleController))]
internal static class VehicleControllerPatches
{
private const float MIN_STAMINA_DRAIN = 0.08f;
private const float MAX_STAMINA_DRAIN = 0.125f;
private const float STAMINA_MULT = 2f;
internal static int criticalDurability = 16;
internal static float regenInterval = 8f;
internal static float scrapingStress = 0.2f;
internal static float adjustableCrashSpeed = 28f;
private static float timeAtLastTreeDestroyed;
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void VehicleController_Post_Start(VehicleController __instance)
{
if (__instance.vehicleID == 0)
{
Common.vehicleController = __instance;
}
}
[HarmonyPatch("CarReactToObstacle")]
[HarmonyPrefix]
private static bool VehicleController_Pre_CarReactToObstacle(VehicleController __instance, ref int __state, CarObstacleType type, EnemyAI enemyScript, ref bool dealDamage)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Invalid comparison between Unknown and I4
__state = __instance.carHP;
if (__instance.vehicleID != 0)
{
return true;
}
if ((int)type == 1 && (Object)(object)enemyScript != (Object)null && BRBNetworker.Instance.FoxSlender.Value && enemyScript is BushWolfEnemy)
{
return false;
}
if ((int)type == 2 && Time.realtimeSinceStartup - timeAtLastTreeDestroyed < Time.fixedDeltaTime)
{
dealDamage = true;
Plugin.Logger.LogDebug((object)"Cruiser received damage in response to tree destruction");
}
return true;
}
[HarmonyPatch("CarReactToObstacle")]
[HarmonyPostfix]
private static void VehicleController_Post_CarReactToObstacle(VehicleController __instance, int __state, Vector3 vel, CarObstacleType type, float obstacleSize, EnemyAI enemyScript)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Invalid comparison between Unknown and I4
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
if (__instance.vehicleID != 0 || __instance.carHP <= 0 || (int)type != 1 || !((Object)(object)enemyScript != (Object)null) || __instance.carHP > __state || !BRBNetworker.Instance.CruiserEnemyDamage.Value)
{
return;
}
int num = __instance.carHP - (__state - 2);
if (num < 1)
{
return;
}
if (!__instance.ignitionStarted && (int)__instance.gear == 3 && (Object)(object)__instance.currentDriver == (Object)null && (Object)(object)__instance.currentPassenger == (Object)null)
{
bool flag = true;
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
if (!((Object)(object)StartOfRound.Instance.allPlayerScripts[i] == (Object)null) && (Object)(object)StartOfRound.Instance.allPlayerScripts[i].physicsParent != (Object)null && (Object)(object)StartOfRound.Instance.allPlayerScripts[i].physicsParent == (Object)(object)((Component)__instance).transform)
{
flag = false;
break;
}
}
if (flag)
{
return;
}
}
if (!(enemyScript is FlowerSnakeEnemy))
{
float num2 = ((obstacleSize > 2f) ? 15f : 9f);
Vector3 val = vel;
val.y = 0f;
if (!(((Vector3)(ref val)).magnitude >= num2))
{
Plugin.Logger.LogDebug((object)$"Cruiser takes extra {num} damage from collision with enemy \"{((Object)enemyScript).name}\" (#{((Object)enemyScript).GetInstanceID()})");
__instance.DealPermanentDamage(num, default(Vector3));
}
}
}
[HarmonyPatch("DoTurboBoost")]
[HarmonyPrefix]
private static bool VehicleController_Pre_DoTurboBoost(VehicleController __instance, CallbackContext context)
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
if (__instance.vehicleID != 0 || __instance.turboBoosts > 0 || !BRBNetworker.Instance.CruiserExhaust.Value)
{
return true;
}
if (((CallbackContext)(ref context)).performed && __instance.localPlayerInControl && !__instance.keyIsInDriverHand && (Object)(object)__instance.currentDriver == (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
if (__instance.currentDriver.isExhausted || __instance.currentDriver.sprintMeter <= 0.3f)
{
return false;
}
if (!__instance.jumpingInCar)
{
float num = 0.08f;
if (Vector3.Angle(Vector3.up, ((Component)__instance).transform.forward) < Vector3.Angle(Vector3.down, ((Component)__instance).transform.forward))
{
num = Mathf.Lerp(num, 0.125f, (Vector3.Angle(Vector3.up, ((Component)__instance).transform.up) - __instance.physicsRegion.maxTippingAngle) / (90f - __instance.physicsRegion.maxTippingAngle));
}
__instance.currentDriver.sprintMeter = Mathf.Clamp01(__instance.currentDriver.sprintMeter - num * 2f);
if (__instance.currentDriver.sprintMeter <= 0.3f)
{
__instance.currentDriver.sprintMeter = 0.1f;
__instance.currentDriver.isExhausted = true;
}
}
return true;
}
return true;
}
[HarmonyPatch("ReactToDamage")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> VehicleController_Trans_ReactToDamage(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = instructions.ToList();
FieldInfo fieldInfo = AccessTools.Field(typeof(VehicleController), "carHP");
FieldInfo fieldInfo2 = AccessTools.Field(typeof(VehicleController), "timeAtLastDamage");
bool flag = false;
bool flag2 = false;
for (int i = 2; i < list.Count; i++)
{
if (!flag && list[i].opcode == OpCodes.Ldc_I4_S && (sbyte)list[i].operand == criticalDurability && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == fieldInfo)
{
list[i].opcode = OpCodes.Ldsfld;
list[i].operand = AccessTools.Field(typeof(VehicleControllerPatches), "criticalDurability");
flag = true;
}
else if (!flag2 && list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == regenInterval && list[i - 1].opcode == OpCodes.Sub && list[i - 2].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 2].operand == fieldInfo2)
{
list[i].opcode = OpCodes.Ldsfld;
list[i].operand = AccessTools.Field(typeof(VehicleControllerPatches), "regenInterval");
flag2 = true;
}
if (flag && flag2)
{
Plugin.Logger.LogDebug((object)"Transpiler (Cruiser): Dynamic regen");
return list;
}
}
Plugin.Logger.LogWarning((object)"Cruiser regen transpiler failed");
return instructions;
}
internal static void JustDestroyedTree()
{
Plugin.Logger.LogDebug((object)"A tree was just destroyed");
if ((Object)(object)Common.vehicleController != (Object)null && Common.vehicleController.vehicleID == 0 && ((NetworkBehaviour)Common.vehicleController).IsOwner && BRBNetworker.Instance.CruiserTrees.Value)
{
timeAtLastTreeDestroyed = Time.realtimeSinceStartup;
}
}
internal static void DealExtraCrashDamage(VehicleController vehicleController, int damage)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)vehicleController != (Object)null && vehicleController.vehicleID == 0 && BRBNetworker.Instance.CruiserCrashDamage.Value)
{
Plugin.Logger.LogDebug((object)$"Cruiser takes extra {damage} damage from collision with geometry");
vehicleController.DealPermanentDamage(damage, default(Vector3));
}
}
[HarmonyPatch("OnCollisionEnter")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> VehicleController_Trans_OnCollisionEnter(IEnumerable<CodeInstruction> instructions)
{
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Expected O, but got Unknown
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Expected O, but got Unknown
//IL_0260: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Expected O, but got Unknown
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_02f3: Expected O, but got Unknown
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0301: Expected O, but got Unknown
//IL_030a: Unknown result type (might be due to invalid IL or missing references)
//IL_0310: Expected O, but got Unknown
//IL_0411: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Expected O, but got Unknown
//IL_041f: Unknown result type (might be due to invalid IL or missing references)
//IL_0425: Expected O, but got Unknown
//IL_042e: Unknown result type (might be due to invalid IL or missing references)
//IL_0434: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
MethodInfo methodInfo = AccessTools.Method(typeof(VehicleController), "SetInternalStress", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.DeclaredPropertyGetter(typeof(Vector3), "magnitude");
MethodInfo methodInfo3 = AccessTools.Method(typeof(VehicleController), "DealPermanentDamage", (Type[])null, (Type[])null);
MethodInfo methodInfo4 = AccessTools.Method(typeof(VehicleControllerPatches), "DealExtraCrashDamage", (Type[])null, (Type[])null);
FieldInfo fieldInfo = AccessTools.Field(typeof(VehicleController), "averageVelocity");
bool flag = false;
bool flag2 = false;
int num = 0;
for (int i = 4; i < list.Count - 1; i++)
{
if (list[i].opcode == OpCodes.Ldc_R4)
{
if (!flag && (float)list[i].operand == scrapingStress && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand as MethodInfo == methodInfo)
{
list[i].opcode = OpCodes.Ldsfld;
list[i].operand = AccessTools.Field(typeof(VehicleControllerPatches), "scrapingStress");
flag = true;
}
else if (!flag2 && (float)list[i].operand == adjustableCrashSpeed && list[i - 1].opcode == OpCodes.Call && list[i - 1].operand as MethodInfo == methodInfo2)
{
list[i].opcode = OpCodes.Ldsfld;
list[i].operand = AccessTools.Field(typeof(VehicleControllerPatches), "adjustableCrashSpeed");
flag2 = true;
}
}
else if (num == 0 && flag2 && list[i].opcode == OpCodes.Call && list[i].operand as MethodInfo == methodInfo3 && list[i - 4].opcode == OpCodes.Ldc_I4_2)
{
list.InsertRange(i + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldc_I4_4, (object)null),
new CodeInstruction(OpCodes.Call, (object)methodInfo4)
}));
i += 3;
num++;
}
else if (num == 1 && list[i].opcode == OpCodes.Call && list[i].operand as MethodInfo == methodInfo3 && list[i - 4].opcode == OpCodes.Ldc_I4_1)
{
list.InsertRange(i + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
new CodeInstruction(OpCodes.Call, (object)methodInfo4)
}));
i += 3;
num++;
}
else if (num == 2 && list[i].opcode == OpCodes.Call && list[i].operand as MethodInfo == methodInfo2 && list[i - 1].opcode == OpCodes.Ldflda && (FieldInfo)list[i - 1].operand == fieldInfo && list[i + 1].opcode == OpCodes.Ldc_R4 && (float)list[i + 1].operand == 1.5f && list[i - 3].opcode == OpCodes.Br)
{
list.InsertRange(i - 3, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
new CodeInstruction(OpCodes.Call, (object)methodInfo4)
}));
i += 3;
num++;
}
if (flag && flag2 && num == 3)
{
Plugin.Logger.LogDebug((object)"Transpiler (Cruiser): Extra crash damage");
return list;
}
}
Plugin.Logger.LogWarning((object)"Cruiser crash transpiler failed");
return instructions;
}
}
}
namespace ButteRyBalance.Patches.Items
{
[HarmonyPatch(typeof(LungProp))]
internal static class ApparatusPatches
{
[HarmonyPatch("EquipItem")]
[HarmonyPrefix]
private static void LungProp_Pre_EquipItem(LungProp __instance)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (((NetworkBehaviour)__instance).IsOwner && __instance.isLungDocked && BRBNetworker.Instance.ApparatusPrice.Value)
{
BRBNetworker.Instance.SyncScrapPriceRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)__instance).NetworkObject), ((GrabbableObject)__instance).scrapValue);
}
}
}
[HarmonyPatch(typeof(JetpackItem))]
internal static class JetpackPatches
{
private static readonly AnimationCurve accelerationCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4]
{
new Keyframe(1.5f, 10f),
new Keyframe(1.73f, 10f),
new Keyframe(2f, 4f),
new Keyframe(2.3f, 2f)
});
private static readonly AnimationCurve handlingCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4]
{
new Keyframe(1.5f, 20f),
new Keyframe(1.73f, 20f),
new Keyframe(2f, 35f),
new Keyframe(2.3f, 50f)
});
private static readonly AnimationCurve decelerationCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
{
new Keyframe(1.5f, 75f),
new Keyframe(2f, 50f),
new Keyframe(2.23f, 45f)
});
private static float timeSpentFlying;
[HarmonyPatch("EquipItem")]
[HarmonyPostfix]
private static void JetpackItem_Post_EquipItem(JetpackItem __instance)
{
if (BRBNetworker.Instance.JetpackBattery.Value)
{
((GrabbableObject)__instance).itemProperties.batteryUsage = 40f;
}
switch ((Configuration.JetpackControls)BRBNetworker.Instance.JetpackControls.Value)
{
case Configuration.JetpackControls.V49:
__instance.jetpackForceChangeSpeed = 1f;
__instance.jetpackDeaccelleration = 75f;
break;
case Configuration.JetpackControls.Vanilla:
__instance.jetpackForceChangeSpeed = 50f;
break;
}
}
[HarmonyPatch(typeof(JetpackItem), "Update")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> JetpackItem_Trans_Update(IEnumerable<CodeInstruction> instructions)
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
for (int i = 1; i < list.Count - 3; i++)
{
if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 50f && list[i + 1].opcode == OpCodes.Mul)
{
list[i].opcode = OpCodes.Ldfld;
list[i].operand = AccessTools.Field(typeof(JetpackItem), "jetpackForceChangeSpeed");
list.Insert(i, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
Plugin.Logger.LogDebug((object)"Transpiler (Jetpack): Dynamic inertia");
return list;
}
}
return instructions;
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
private static void JetpackItem_Pre_Update(JetpackItem __instance)
{
if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null || (Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)(object)GameNetworkManager.Instance?.localPlayerController)
{
return;
}
float num = 10f;
if (BRBNetworker.Instance.JetpackControls.Value == 2)
{
num = accelerationCurve.Evaluate(((GrabbableObject)__instance).playerHeldBy.carryWeight);
__instance.jetpackForceChangeSpeed = handlingCurve.Evaluate(((GrabbableObject)__instance).playerHeldBy.carryWeight);
__instance.jetpackDeaccelleration = decelerationCurve.Evaluate(((GrabbableObject)__instance).playerHeldBy.carryWeight);
}
if (BRBNetworker.Instance.JetpackWarmUp.Value)
{
if (!((GrabbableObject)__instance).playerHeldBy.jetpackControls)
{
timeSpentFlying = 0f;
}
else if (__instance.jetpackActivated)
{
timeSpentFlying += Time.deltaTime;
}
if (timeSpentFlying < 2f)
{
__instance.jetpackAcceleration = 2f * __instance.verticalMultiplier;
}
else
{
__instance.jetpackAcceleration = Mathf.Lerp(2f, num, Mathf.InverseLerp(2f, 4f, timeSpentFlying));
}
}
else
{
__instance.jetpackAcceleration = num;
}
}
}
[HarmonyPatch(typeof(KnifeItem))]
internal static class KnifePatches
{
private static float knifeCooldown = 0.43f;
private static float timeAtLastSwing;
private static InputAction activateItem;
[HarmonyPatch(typeof(GrabbableObject), "Start")]
[HarmonyPostfix]
private static void GrabbableObject_Post_Start(GrabbableObject __instance)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (((NetworkBehaviour)__instance).IsServer && !StartOfRound.Instance.inShipPhase && __instance.scrapValue == 35 && Configuration.butlerKnifePrice.Value && __instance is KnifeItem)
{
Plugin.Logger.LogInfo((object)"Trying to sync knife price on server");
BRBNetworker.Instance.SyncScrapPriceRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)__instance).NetworkObject), Random.Range(28, 84));
}
}
[HarmonyPatch("EquipItem")]
[HarmonyPostfix]
private static void KnifeItem_Post_EquipItem(KnifeItem __instance)
{
knifeCooldown = (BRBNetworker.Instance.KnifeShortCooldown.Value ? 0.37f : 0.43f);
}
[HarmonyPatch("HitKnife")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> KnifeItem_Trans_HitKnife(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = instructions.ToList();
for (int i = 0; i < list.Count; i++)
{
if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 0.43f)
{
list[i].opcode = OpCodes.Ldsfld;
list[i].operand = AccessTools.Field(typeof(KnifePatches), "knifeCooldown");
Plugin.Logger.LogDebug((object)"Transpiler (Knife): Dynamic cooldown");
return list;
}
}
return instructions;
}
[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
[HarmonyPostfix]
private static void PlayerControllerB_Post_OnEnable()
{
activateItem = InputSystem.actions.FindAction("ActivateItem", false);
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPostfix]
private static void PlayerControllerB_Post_Update(PlayerControllerB __instance)
{
if (!((Object)(object)__instance.currentlyHeldObjectServer != (Object)null) || !(__instance.timeSinceSwitchingSlots >= 0.075f))
{
return;
}
GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
KnifeItem val = (KnifeItem)(object)((currentlyHeldObjectServer is KnifeItem) ? currentlyHeldObjectServer : null);
if (val != null && Configuration.knifeAutoSwing.Value && __instance.CanUseItem() && activateItem.IsPressed() && Time.realtimeSinceStartup - timeAtLastSwing > 0.12f && Time.realtimeSinceStartup - val.timeAtLastDamageDealt > knifeCooldown)
{
if (Time.realtimeSinceStartup - timeAtLastSwing <= 0.5f)
{
ShipBuildModeManager.Instance.CancelBuildMode(true);
__instance.currentlyHeldObjectServer.UseItemOnClient(true);
__instance.timeSinceSwitchingSlots = 0f;
}
timeAtLastSwing = Time.realtimeSinceStartup + Random.Range(0f, 0.01f);
}
}
}
[HarmonyPatch(typeof(Shovel))]
internal static class ShovelPatches
{
private static float timeLastBuffered;
private static InputAction activateItem;
[HarmonyPatch("ItemActivate")]
[HarmonyPrefix]
private static void Shovel_Post_ItemActivate(Shovel __instance, bool buttonDown)
{
if (buttonDown && __instance.reelingUp)
{
timeLastBuffered = Time.realtimeSinceStartup;
}
}
[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
[HarmonyPostfix]
private static void PlayerControllerB_Post_OnEnable()
{
activateItem = InputSystem.actions.FindAction("ActivateItem", false);
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPostfix]
private static void PlayerControllerB_Post_Update(PlayerControllerB __instance)
{
if ((Object)(object)__instance.currentlyHeldObjectServer != (Object)null && __instance.timeSinceSwitchingSlots >= 0.075f && __instance.currentlyHeldObjectServer is Shovel && Configuration.shovelBuffer.Value && __instance.CanUseItem() && activateItem.IsPressed() && Time.realtimeSinceStartup - timeLastBuffered < 0.5f)
{
if (Time.realtimeSinceStartup - timeLastBuffered <= 0.5f)
{
ShipBuildModeManager.Instance.CancelBuildMode(true);
__instance.currentlyHeldObjectServer.UseItemOnClient(true);
__instance.timeSinceSwitchingSlots = 0f;
}
timeLastBuffered = Time.realtimeSinceStartup + Random.Range(0f, 0.01f);
}
}
}
[HarmonyPatch(typeof(PatcherTool))]
internal static class ZapGunPatches
{
[HarmonyPatch("EquipItem")]
[HarmonyPostfix]
private static void PatcherTool_Post_EquipItem(PatcherTool __instance)
{
if (BRBNetworker.Instance.ZapGunBattery.Value)
{
((GrabbableObject)__instance).itemProperties.batteryUsage = 120f;
}
}
}
}
namespace ButteRyBalance.Patches.Enemies
{
[HarmonyPatch(typeof(StingrayAI))]
internal static class BackwaterGunkfishPatches
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void StingrayAI_Post_Start(StingrayAI __instance)
{
if (BRBNetworker.Instance.GunkfishSquishy.Value)
{
((EnemyAI)__instance).enemyHP = 3;
}
}
}
[HarmonyPatch(typeof(ButlerEnemyAI))]
internal static class ButlerPatches
{
[HarmonyPatch("OnCollideWithPlayer")]
[HarmonyPrefix]
private static bool ButlerEnemyAI_Pre_OnCollideWithPlayer(ButlerEnemyAI __instance, Collider other)
{
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
if (!BRBNetworker.Instance.ButlerStealthStab.Value && !BRBNetworker.Instance.ButlerLongCooldown.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex != 2 && __instance.berserkModeTimer <= 0f)
{
if (Time.realtimeSinceStartup - __instance.timeSinceStealthStab < 10f)
{
return false;
}
__instance.timeSinceStealthStab = Time.realtimeSinceStartup;
if (Random.Range(0, 100) < 95)
{
return false;
}
}
float num = 0.25f;
if (BRBNetworker.Instance.ButlerLongCooldown.Value && __instance.timeAtLastButlerDamage <= 0f && __instance.berserkModeTimer <= 3f)
{
num = 0.35f;
}
if (__instance.timeSinceHittingPlayer < num)
{
return false;
}
PlayerControllerB val = ((EnemyAI)__instance).MeetsStandardPlayerCollisionConditions(other, false, false);
if ((Object)(object)val != (Object)null)
{
__instance.timeSinceHittingPlayer = 0f;
val.DamagePlayer(10, true, true, (CauseOfDeath)14, 0, false, default(Vector3));
bool flag = ((EnemyAI)__instance).currentBehaviourStateIndex != 2;
if (flag && BRBNetworker.Instance.ButlerStealthStab.Value)
{
flag = !val.NearOtherPlayers(15f);
if (flag)
{
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
if (!((Object)(object)StartOfRound.Instance.allPlayerScripts[i] == (Object)(object)GameNetworkManager.Instance.localPlayerController) && !StartOfRound.Instance.allPlayerScripts[i].isPlayerDead && StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position, 110f, 60, 2f, (Transform)null))
{
flag = false;
break;
}
}
}
}
if (flag)
{
__instance.berserkModeTimer = 3f;
}
__instance.StabPlayerServerRpc((int)val.playerClientId, flag);
}
return false;
}
[HarmonyPatch("HitEnemy")]
[HarmonyPrefix]
private static void ButlerEnemyAI_Pre_HitEnemy(ButlerEnemyAI __instance, ref int force, int hitID)
{
if (force > 2 && BRBNetworker.Instance.ButlerSquishy.Value && hitID != 1)
{
force += 3;
}
}
[HarmonyPatch("HitEnemy")]
[HarmonyPostfix]
private static void ButlerEnemyAI_Post_HitEnemy(ButlerEnemyAI __instance, PlayerControllerB playerWhoHit)
{
if ((Object)(object)playerWhoHit != (Object)null && BRBNetworker.Instance.ButlerLongCooldown.Value)
{
__instance.timeAtLastButlerDamage = Time.realtimeSinceStartup;
}
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void ButlerEnemyAI_Post_Start(ButlerEnemyAI __instance)
{
if (BRBNetworker.Instance.ButlerLongCooldown.Value)
{
((EnemyAI)__instance).enemyHP = Mathf.Max(((EnemyAI)__instance).enemyHP, 3);
}
}
}
[HarmonyPatch(typeof(SpringManAI))]
internal static class CoilHeadPatches
{
[HarmonyPatch(typeof(EnemyAI), "SetEnemyStunned")]
[HarmonyPrefix]
private static void EnemyAI_Pre_SetEnemyStunned(EnemyAI __instance, float setToStunTime)
{
SpringManAI val = (SpringManAI)(object)((__instance is SpringManAI) ? __instance : null);
if (val != null && ((NetworkBehaviour)__instance).IsServer && Configuration.coilheadStunReset.Value && val.onCooldownPhase <= 0f && setToStunTime > 0.5f)
{
val.onCooldownPhase = setToStunTime * __instance.enemyType.stunTimeMultiplier;
val.setOnCooldown = true;
val.inCooldownAnimation = true;
val.SetCoilheadOnCooldownServerRpc(true);
}
}
[HarmonyPatch("SetCoilheadOnCooldownClientRpc")]
[HarmonyPostfix]
private static void SpringManAI_Post_SetCoilheadOnCooldownClientRpc(SpringManAI __instance, bool setTrue)
{
if (setTrue)
{
__instance.onCooldownPhase = Mathf.Max(__instance.onCooldownPhase, ((EnemyAI)__instance).stunNormalizedTimer * ((EnemyAI)__instance).enemyType.stunTimeMultiplier);
}
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void SpringManAI_Post_Update(SpringManAI __instance)
{
if (!((EnemyAI)__instance).isEnemyDead && !__instance.setOnCooldown && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && ((EnemyAI)__instance).creatureAnimator.GetFloat("walkSpeed") == 4.7f)
{
((EnemyAI)__instance).creatureAnimator.SetFloat("walkSpeed", 2.5f);
}
if (((NetworkBehaviour)__instance).IsServer && Configuration.coilheadPersistence.Value)
{
__instance.timeSpentMoving = 0f;
}
}
}
[HarmonyPatch(typeof(ForestGiantAI))]
internal static class ForestKeeperPatches
{
[HarmonyPatch(typeof(EnemyAI), "GetAllPlayersInLineOfSight")]
[HarmonyPrefix]
private static void EnemyAI_Pre_GetAllPlayersInLineOfSight(EnemyAI __instance, ref int range)
{
if (__instance.isOutside && !__instance.enemyType.canSeeThroughFog && range > 30 && ((NetworkBehaviour)__instance).IsOwner && __instance is ForestGiantAI && Configuration.giantSnowSight.Value && Common.IsSnowLevel())
{
range = 30;
}
}
[HarmonyPatch("HitEnemy")]
[HarmonyPrefix]
private static void ForestGiantAI_Pre_HitEnemy(ref int force, int hitID)
{
if (force != 12 || !BRBNetworker.Instance.GiantSquishy.Value)
{
return;
}
switch (hitID)
{
default:
if (!((Object)(object)Common.vehicleController != (Object)null))
{
break;
}
goto case 331;
case 331:
force += 100;
break;
case 1:
case 5:
break;
}
}
}
[HarmonyPatch(typeof(HoarderBugAI))]
internal static class HoardingBugPatches
{
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void HoarderBugAI_Post_Update(HoarderBugAI __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && Configuration.hoarderAngerManagement.Value && __instance.angryTimer > 0f)
{
__instance.annoyanceMeter = 0f;
}
}
}
[HarmonyPatch(typeof(JesterAI))]
internal static class JesterPatches
{
[HarmonyPatch(typeof(EnemyAI), "SwitchToBehaviourStateOnLocalClient")]
[HarmonyPostfix]
private static void EnemyAI_Post_SwitchToBehaviourStateOnLocalClient(EnemyAI __instance, int stateIndex)
{
JesterAI val = (JesterAI)(object)((__instance is JesterAI) ? __instance : null);
if (val != null && stateIndex == 1 && BRBNetworker.Instance.JesterWalkThrough.Value)
{
val.mainCollider.isTrigger = true;
}
}
[HarmonyPatch("SetJesterInitialValues")]
[HarmonyPostfix]
private static void JesterAI_Post_SetJesterInitialValues(JesterAI __instance)
{
if (StartOfRound.Instance.connectedPlayersAmount < 4 && BRBNetworker.Instance.JesterLongCooldown.Value)
{
__instance.beginCrankingTimer = Mathf.Max(__instance.beginCrankingTimer, Random.Range(12f, 28f));
}
}
}
[HarmonyPatch(typeof(CaveDwellerAI))]
internal class ManeaterPatches
{
private static bool playersHaveEnteredBuilding;
private static float GROWTH_SPEED_MULTIPLIER = 0.045f;
[HarmonyPatch("HitEnemy")]
[HarmonyPrefix]
private static void CaveDwellerAI_Pre_HitEnemy(CaveDwellerAI __instance, ref float __state)
{
__state = __instance.growthMeter;
}
[HarmonyPatch("HitEnemy")]
[HarmonyPostfix]
private static void CaveDwellerAI_Post_HitEnemy(CaveDwellerAI __instance, float __state, PlayerControllerB playerWhoHit)
{
if (((NetworkBehaviour)__instance).IsServer && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && (Object)(object)playerWhoHit == (Object)null && !__instance.hasPlayerFoundBaby && BRBNetworker.Instance.ManeaterLimitGrowth.Value)
{
__instance.growthMeter = __state;
}
}
[HarmonyPatch("KillEnemy")]
[HarmonyPrefix]
private static void CaveDwellerAI_Pre_KillEnemy(CaveDwellerAI __instance, ref float __state)
{
__state = __instance.growthMeter;