Decompiled source of HullBreaker Company Ambigous Fork v2.2.5
BepInEx/plugins/HullBreakerCompany.dll
Decompiled 3 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FacilityMeltdown.API; using GameNetcodeStuff; using HarmonyLib; using HullBreakerCompany.Events; using HullBreakerCompany.Events.Enemy; using HullBreakerCompany.Events.Integrated; using HullBreakerCompany.Events.Integrated.AdvancedCompany; using HullBreakerCompany.Events.Integrated.SCP; using HullBreakerCompany.Events.Integrated.Surfaced; using HullBreakerCompany.Events.Misc; using HullBreakerCompany.Events.Scrap; using HullBreakerCompany.Hull; using LethalQuantities.Objects; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HullBreakerCompany")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Making it more challenging to work for the company")] [assembly: AssemblyFileVersion("2.2.4.0")] [assembly: AssemblyInformationalVersion("2.2.4+944c96a1d7648df457957a007c7929e0f5682b33")] [assembly: AssemblyProduct("HullBreakerCompany")] [assembly: AssemblyTitle("HullBreakerCompany")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HullBreakerCompany { public class LevelModifier { private SelectableLevel targetLevel; private readonly Dictionary<string, int> enemyComponentRarityModifications; private readonly Dictionary<string, int> enemyComponentRarityBackups; private readonly Dictionary<string, int> enemyComponentMaxCountModifications; private readonly Dictionary<string, int> enemyComponentMaxCountBackups; private readonly Dictionary<string, float> enemyComponentPowerModifications; private readonly Dictionary<string, float> enemyComponentPowerBackups; private int targetLevelEnemyRarityTotal; private readonly Dictionary<string, int> outsideEnemyComponentRarityModifications; private readonly Dictionary<string, int> outsideEnemyComponentRarityBackups; private readonly Dictionary<string, int> outsideEnemyComponentMaxCountModifications; private readonly Dictionary<string, int> outsideEnemyComponentMaxCountBackups; private readonly Dictionary<string, float> outsideEnemyComponentPowerModifications; private readonly Dictionary<string, float> outsideEnemyComponentPowerBackups; private int targetLevelOutsideEnemyRarityTotal; private readonly Dictionary<string, int> daytimeEnemyComponentRarityModifications; private readonly Dictionary<string, int> daytimeEnemyComponentRarityBackups; private readonly Dictionary<string, int> daytimeEnemyComponentMaxCountModifications; private readonly Dictionary<string, int> daytimeEnemyComponentMaxCountBackups; private readonly Dictionary<string, float> daytimeEnemyComponentPowerModifications; private readonly Dictionary<string, float> daytimeEnemyComponentPowerBackups; private int targetLevelDaytimeEnemyRarityTotal; private readonly Dictionary<string, int> spawnableScrapRarityModifications; private readonly Dictionary<string, int> spawnableScrapRarityBackups; private int targetLevelScrapRarityTotal; private int maxEnemyPower; private int maxOutsideEnemyPower; private int maxDaytimeEnemyPower; private int enemySpawnChanceThroughoutDay; private AnimationCurve enemySpawnChanceThroghoutDayBackup; private int outsideEnemySpawnChanceThroughoutDay; private AnimationCurve outsideEnemySpawnChanceThroghoutDayBackup; private int daytimeEnemySpawnChanceThroughoutDay; private AnimationCurve daytimeEnemySpawnChanceThroghoutDayBackup; private readonly Dictionary<string, int> traps; private readonly Dictionary<string, AnimationCurve> trapBackups; private float timeScale; private bool Active { get; set; } public LevelModifier(SelectableLevel level) { targetLevel = level; enemyComponentRarityModifications = new Dictionary<string, int>(); enemyComponentRarityBackups = new Dictionary<string, int>(); enemyComponentMaxCountModifications = new Dictionary<string, int>(); enemyComponentMaxCountBackups = new Dictionary<string, int>(); enemyComponentPowerModifications = new Dictionary<string, float>(); enemyComponentPowerBackups = new Dictionary<string, float>(); outsideEnemyComponentRarityModifications = new Dictionary<string, int>(); outsideEnemyComponentRarityBackups = new Dictionary<string, int>(); outsideEnemyComponentMaxCountModifications = new Dictionary<string, int>(); outsideEnemyComponentMaxCountBackups = new Dictionary<string, int>(); outsideEnemyComponentPowerModifications = new Dictionary<string, float>(); outsideEnemyComponentPowerBackups = new Dictionary<string, float>(); daytimeEnemyComponentRarityModifications = new Dictionary<string, int>(); daytimeEnemyComponentRarityBackups = new Dictionary<string, int>(); daytimeEnemyComponentMaxCountModifications = new Dictionary<string, int>(); daytimeEnemyComponentMaxCountBackups = new Dictionary<string, int>(); daytimeEnemyComponentPowerModifications = new Dictionary<string, float>(); daytimeEnemyComponentPowerBackups = new Dictionary<string, float>(); spawnableScrapRarityModifications = new Dictionary<string, int>(); spawnableScrapRarityBackups = new Dictionary<string, int>(); traps = new Dictionary<string, int>(); trapBackups = new Dictionary<string, AnimationCurve>(); base..ctor(); } private void OnSceneUnloaded(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) Plugin.Mls.LogInfo((object)("Unloading scene: " + ((Scene)(ref scene)).name)); SelectableLevel currentLevel = RoundManager.Instance.currentLevel; if ((Object)(object)currentLevel == (Object)null) { Plugin.Mls.LogInfo((object)"Scene does not contain a level!"); } else if (currentLevel.levelID == 3) { Plugin.Mls.LogInfo((object)"Scene contains company building level!"); } else if ((Object)(object)currentLevel != (Object)(object)targetLevel) { Plugin.Mls.LogWarning((object)("currentLevel (" + currentLevel.PlanetName + ") levelModifier (" + targetLevel.PlanetName + ") mismatch!")); } else if (new List<string>(3) { "MainMenu", "InitScene", "SampleSceneRelay" }.Any((string str) => str == ((Scene)(ref scene)).name)) { Plugin.Mls.LogInfo((object)"Ignoring scene. Not reverting any modifications!"); } else { UndoModifications(); EventsHandler.Reset(); } } private void ApplyEnemyComponentRarity(bool undo = false) { if (enemyComponentRarityModifications.Count <= 0) { return; } if (targetLevelEnemyRarityTotal == 0) { targetLevelEnemyRarityTotal = targetLevel.Enemies.Sum((SpawnableEnemyWithRarity enemy) => enemy.rarity); } foreach (KeyValuePair<string, int> rarityPair in enemyComponentRarityModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(rarityPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (undo) { current.rarity = enemyComponentRarityBackups[rarityPair.Key]; } else { enemyComponentRarityBackups.TryAdd(rarityPair.Key, current.rarity); current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelEnemyRarityTotal - current.rarity)); } Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}"); } } } private void ApplyEnemyComponentMaxCount(bool undo = false) { if (enemyComponentMaxCountModifications.Count <= 0) { return; } foreach (KeyValuePair<string, int> maxCountPair in enemyComponentMaxCountModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(maxCountPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { enemyComponentMaxCountBackups.TryAdd(maxCountPair.Key, current.enemyType.MaxCount); } current.enemyType.MaxCount = (undo ? enemyComponentMaxCountBackups[maxCountPair.Key] : maxCountPair.Value); Plugin.Mls.LogInfo((object)$"Setting maxCount of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.MaxCount}"); } } } private void ApplyEnemyComponentPower(bool undo = false) { if (enemyComponentPowerModifications.Count <= 0) { return; } foreach (KeyValuePair<string, float> powerPair in enemyComponentPowerModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(powerPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { enemyComponentPowerBackups.TryAdd(powerPair.Key, (float)Math.Round(current.enemyType.PowerLevel)); } current.enemyType.PowerLevel = (undo ? enemyComponentPowerBackups[powerPair.Key] : powerPair.Value); Plugin.Mls.LogInfo((object)$"Setting power of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.PowerLevel}"); } } } private void ApplyOutsideEnemyComponentRarity(bool undo = false) { if (outsideEnemyComponentRarityModifications.Count <= 0) { return; } if (targetLevelOutsideEnemyRarityTotal == 0) { targetLevelOutsideEnemyRarityTotal = targetLevel.OutsideEnemies.Sum((SpawnableEnemyWithRarity enemy) => enemy.rarity); } foreach (KeyValuePair<string, int> rarityPair in outsideEnemyComponentRarityModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.OutsideEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(rarityPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (undo) { current.rarity = outsideEnemyComponentRarityBackups[rarityPair.Key]; } else { outsideEnemyComponentRarityBackups.TryAdd(rarityPair.Key, current.rarity); current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelOutsideEnemyRarityTotal - current.rarity)); } Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}"); } } } private void ApplyOutsideEnemyComponentMaxCount(bool undo = false) { if (outsideEnemyComponentMaxCountModifications.Count <= 0) { return; } foreach (KeyValuePair<string, int> maxCountPair in outsideEnemyComponentMaxCountModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.OutsideEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(maxCountPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { outsideEnemyComponentMaxCountBackups.TryAdd(maxCountPair.Key, current.enemyType.MaxCount); } current.enemyType.MaxCount = (undo ? outsideEnemyComponentMaxCountBackups[maxCountPair.Key] : maxCountPair.Value); Plugin.Mls.LogInfo((object)$"Setting maxCount of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.MaxCount}"); } } } private void ApplyOutsideEnemyComponentPower(bool undo = false) { if (outsideEnemyComponentPowerModifications.Count <= 0) { return; } foreach (KeyValuePair<string, float> powerPair in outsideEnemyComponentPowerModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.OutsideEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(powerPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { outsideEnemyComponentPowerBackups.TryAdd(powerPair.Key, (float)Math.Round(current.enemyType.PowerLevel)); } current.enemyType.PowerLevel = (undo ? outsideEnemyComponentPowerBackups[powerPair.Key] : powerPair.Value); Plugin.Mls.LogInfo((object)$"Setting power of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.PowerLevel}"); } } } private void ApplyDaytimeEnemyComponentRarity(bool undo = false) { if (daytimeEnemyComponentRarityModifications.Count <= 0) { return; } if (targetLevelDaytimeEnemyRarityTotal == 0) { targetLevelDaytimeEnemyRarityTotal = targetLevel.DaytimeEnemies.Sum((SpawnableEnemyWithRarity enemy) => enemy.rarity); } foreach (KeyValuePair<string, int> rarityPair in daytimeEnemyComponentRarityModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.DaytimeEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(rarityPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (undo) { current.rarity = daytimeEnemyComponentRarityBackups[rarityPair.Key]; } else { daytimeEnemyComponentRarityBackups.TryAdd(rarityPair.Key, current.rarity); current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelDaytimeEnemyRarityTotal - current.rarity)); } Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}"); } } } private void ApplyDaytimeEnemyComponentMaxCount(bool undo = false) { if (daytimeEnemyComponentMaxCountModifications.Count <= 0) { return; } foreach (KeyValuePair<string, int> maxCountPair in daytimeEnemyComponentMaxCountModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.DaytimeEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(maxCountPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { daytimeEnemyComponentMaxCountBackups.TryAdd(maxCountPair.Key, current.enemyType.MaxCount); } current.enemyType.MaxCount = (undo ? daytimeEnemyComponentMaxCountBackups[maxCountPair.Key] : maxCountPair.Value); Plugin.Mls.LogInfo((object)$"Setting maxCount of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.MaxCount}"); } } } private void ApplyDaytimeEnemyComponentPower(bool undo = false) { if (daytimeEnemyComponentPowerModifications.Count <= 0) { return; } foreach (KeyValuePair<string, float> powerPair in daytimeEnemyComponentPowerModifications) { using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = targetLevel.DaytimeEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name.Equals(powerPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableEnemyWithRarity current = enumerator2.Current; if (!undo) { daytimeEnemyComponentPowerBackups.TryAdd(powerPair.Key, (float)Math.Round(current.enemyType.PowerLevel)); } current.enemyType.PowerLevel = (undo ? daytimeEnemyComponentPowerBackups[powerPair.Key] : powerPair.Value); Plugin.Mls.LogInfo((object)$"Setting power of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.PowerLevel}"); } } } private void ApplyLootRarity(bool undo = false) { if (spawnableScrapRarityModifications.Count <= 0) { return; } if (targetLevelScrapRarityTotal == 0) { targetLevelScrapRarityTotal = targetLevel.spawnableScrap.Sum((SpawnableItemWithRarity scrap) => scrap.rarity); } foreach (KeyValuePair<string, int> rarityPair in spawnableScrapRarityModifications) { using IEnumerator<SpawnableItemWithRarity> enumerator2 = targetLevel.spawnableScrap.Where((SpawnableItemWithRarity item) => item.spawnableItem.itemName.Equals(rarityPair.Key, StringComparison.OrdinalIgnoreCase)).GetEnumerator(); if (enumerator2.MoveNext()) { SpawnableItemWithRarity current = enumerator2.Current; if (undo) { current.rarity = spawnableScrapRarityBackups[rarityPair.Key]; } else { spawnableScrapRarityBackups.TryAdd(rarityPair.Key, current.rarity); current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelScrapRarityTotal - current.rarity)); } Plugin.Mls.LogInfo((object)$"Setting rarity of {current.spawnableItem.itemName} to {current.rarity}"); } } } private void ApplyMaxEnemyPower(bool undo = false) { if (maxEnemyPower > 0) { if (!undo) { int num = maxEnemyPower; maxEnemyPower = targetLevel.maxEnemyPowerCount; SelectableLevel obj = targetLevel; obj.maxEnemyPowerCount += num; } else { targetLevel.maxEnemyPowerCount = maxEnemyPower; } Plugin.Mls.LogInfo((object)$"Setting global max enemy power to {targetLevel.maxEnemyPowerCount}"); } } private void ApplyMaxOutsideEnemyPower(bool undo = false) { if (maxOutsideEnemyPower > 0) { if (!undo) { int num = maxOutsideEnemyPower; maxOutsideEnemyPower = targetLevel.maxOutsideEnemyPowerCount; SelectableLevel obj = targetLevel; obj.maxOutsideEnemyPowerCount += num; } else { targetLevel.maxOutsideEnemyPowerCount = maxOutsideEnemyPower; } Plugin.Mls.LogInfo((object)$"Setting global outside max enemy power to {targetLevel.maxOutsideEnemyPowerCount}"); } } private void ApplyMaxDaytimeEnemyPower(bool undo = false) { if (maxDaytimeEnemyPower > 0) { if (!undo) { int num = maxDaytimeEnemyPower; maxDaytimeEnemyPower = targetLevel.maxDaytimeEnemyPowerCount; SelectableLevel obj = targetLevel; obj.maxDaytimeEnemyPowerCount += num; } else { targetLevel.maxDaytimeEnemyPowerCount = maxDaytimeEnemyPower; } Plugin.Mls.LogInfo((object)$"Setting global daytime max enemy power to {targetLevel.maxDaytimeEnemyPowerCount}"); } } private void ApplyEnemySpawnChanceThroughoutDay(bool undo = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (enemySpawnChanceThroughoutDay > 0) { if (!undo) { enemySpawnChanceThroghoutDayBackup = targetLevel.enemySpawnChanceThroughoutDay; targetLevel.enemySpawnChanceThroughoutDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1] { new Keyframe(0f, (float)enemySpawnChanceThroughoutDay) }); Plugin.Mls.LogInfo((object)$"Setting global enemy spawn chance to {enemySpawnChanceThroughoutDay}"); } else { targetLevel.enemySpawnChanceThroughoutDay = enemySpawnChanceThroghoutDayBackup; Plugin.Mls.LogInfo((object)"Reverting global enemy spawn chance"); } } } private void ApplyOutsideEnemySpawnChanceThroughoutDay(bool undo = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (outsideEnemySpawnChanceThroughoutDay > 0) { if (!undo) { outsideEnemySpawnChanceThroghoutDayBackup = targetLevel.outsideEnemySpawnChanceThroughDay; targetLevel.outsideEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1] { new Keyframe(0f, (float)outsideEnemySpawnChanceThroughoutDay) }); Plugin.Mls.LogInfo((object)$"Setting global outside enemy spawn chance to {outsideEnemySpawnChanceThroughoutDay}"); } else { targetLevel.outsideEnemySpawnChanceThroughDay = outsideEnemySpawnChanceThroghoutDayBackup; Plugin.Mls.LogInfo((object)"Reverting global outside enemy spawn chance"); } } } private void ApplyDaytimeEnemySpawnChanceThroughoutDay(bool undo = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (daytimeEnemySpawnChanceThroughoutDay > 0) { if (!undo) { daytimeEnemySpawnChanceThroghoutDayBackup = targetLevel.daytimeEnemySpawnChanceThroughDay; targetLevel.daytimeEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1] { new Keyframe(0f, (float)daytimeEnemySpawnChanceThroughoutDay) }); Plugin.Mls.LogInfo((object)$"Setting global daytime enemy spawn chance to {daytimeEnemySpawnChanceThroughoutDay}"); } else { targetLevel.daytimeEnemySpawnChanceThroughDay = daytimeEnemySpawnChanceThroghoutDayBackup; Plugin.Mls.LogInfo((object)"Reverting global daytime enemy spawn chance"); } } } private void ApplyTimeScale(bool undo = false) { if (timeScale != 0f) { if (!undo) { float globalTimeSpeedMultiplier = TimeOfDay.Instance.globalTimeSpeedMultiplier; TimeOfDay instance = TimeOfDay.Instance; instance.globalTimeSpeedMultiplier *= timeScale; timeScale = globalTimeSpeedMultiplier; Plugin.Mls.LogInfo((object)$"Setting TimeSpeedMultiplier to {TimeOfDay.Instance.globalTimeSpeedMultiplier}: Timescale {(int)Math.Round(timeScale * 100f)}%"); } else { TimeOfDay.Instance.globalTimeSpeedMultiplier = timeScale; Plugin.Mls.LogInfo((object)$"Reset TimeSpeedMultiplier: {timeScale}"); } } } private void ApplyUnitModification(bool undo = false) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown foreach (KeyValuePair<string, int> trap in traps) { string text = ((!(trap.Key == Util.getTrapUnitByType(typeof(Turret)))) ? trap.Key : "Turret"); SpawnableMapObject[] spawnableMapObjects = targetLevel.spawnableMapObjects; foreach (SpawnableMapObject val in spawnableMapObjects) { if (!((Object)val.prefabToSpawn).name.Equals(trap.Key, StringComparison.OrdinalIgnoreCase)) { continue; } if (!undo) { if (trap.Value <= 0) { return; } trapBackups.Add(trap.Key, val.numberToSpawn); val.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[1] { new Keyframe(0f, (float)trap.Value) }); Plugin.Mls.LogInfo((object)$"Overriding {text} amount: {trap.Value}"); continue; } if (trapBackups[trap.Key] == null) { Plugin.Mls.LogError((object)("Backup for " + text + " (" + trap.Key + ") not found!")); return; } val.numberToSpawn = trapBackups[trap.Key]; Plugin.Mls.LogInfo((object)("Restoring original " + text + " spawn curve")); } } } private bool IsTargetLevelSet() { if ((Object)(object)targetLevel == (Object)null) { Plugin.Mls.LogWarning((object)"Target level not set!"); return false; } return true; } public void AddEnemyComponentRarity(string enemy, int percentOfTotalRarity) { enemyComponentRarityModifications.TryAdd(enemy, percentOfTotalRarity); } public void AddEnemyComponentMaxCount(string enemy, int maxCount) { enemyComponentMaxCountModifications.TryAdd(enemy, maxCount); } public void AddEnemyComponentPower(string enemy, float power) { enemyComponentPowerModifications.TryAdd(enemy, power); } public void AddOutsideEnemyComponentRarity(string enemy, int percentOfTotalRarity) { outsideEnemyComponentRarityModifications.TryAdd(enemy, percentOfTotalRarity); } public void AddOutsideEnemyComponentMaxCount(string enemy, int maxCount) { outsideEnemyComponentMaxCountModifications.TryAdd(enemy, maxCount); } public void AddOutsideEnemyComponentPower(string enemy, float power) { outsideEnemyComponentPowerModifications.TryAdd(enemy, power); } public void AddDaytimeEnemyComponentRarity(string enemy, int percentOfTotalRarity) { daytimeEnemyComponentRarityModifications.TryAdd(enemy, percentOfTotalRarity); } public void AddDaytimeEnemyComponentMaxCount(string enemy, int maxCount) { daytimeEnemyComponentMaxCountModifications.TryAdd(enemy, maxCount); } public void AddDaytimeEnemyComponentPower(string enemy, float power) { daytimeEnemyComponentPowerModifications.TryAdd(enemy, power); } public void AddSpawnableScrapRarity(string item, int percentOfTotalRarity) { spawnableScrapRarityModifications.TryAdd(item, percentOfTotalRarity); } public void AddSpawnableScrapRarityDict(Dictionary<string, int> scrapToSpawn) { foreach (KeyValuePair<string, int> item in scrapToSpawn) { AddSpawnableScrapRarity(item.Key, item.Value); } } public void AddMaxEnemyPower(int power) { maxEnemyPower = power; } public void AddMaxOutsideEnemyPower(int power) { maxOutsideEnemyPower = power; } public void AddMaxDaytimeEnemyPower(int power) { maxDaytimeEnemyPower = power; } public void AddEnemySpawnChanceThroughoutDay(int value) { enemySpawnChanceThroughoutDay += value; } public void AddOutsideEnemySpawnChanceThroughoutDay(int value) { outsideEnemySpawnChanceThroughoutDay += value; } public void AddDaytimeEnemySpawnChanceThroughoutDay(int value) { daytimeEnemySpawnChanceThroughoutDay += value; } public void AddTrapUnit(string unit, int value) { if (traps.ContainsKey(unit)) { traps[unit] += value; } else { traps.Add(unit, value); } } public bool SetTimeScale(float value) { if (timeScale != 0f) { throw new Exception("Timescale already set!"); } timeScale = value; return true; } public bool IsEnemySpawnable(string enemyName) { if (!IsTargetLevelSet()) { return false; } if (targetLevel.Enemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName, StringComparison.OrdinalIgnoreCase))) { return true; } Plugin.Mls.LogWarning((object)("Can't spawn enemy " + enemyName + " on this moon.")); return false; } public bool IsOutsideEnemySpawnable(string enemyName) { if (!IsTargetLevelSet()) { return false; } if (targetLevel.OutsideEnemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName, StringComparison.OrdinalIgnoreCase))) { return true; } Plugin.Mls.LogWarning((object)("Can't spawn outside " + enemyName + " on this moon.")); return false; } public bool IsDaytimeEnemySpawnable(string enemyName) { if (!IsTargetLevelSet()) { return false; } if (targetLevel.DaytimeEnemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName, StringComparison.OrdinalIgnoreCase))) { return true; } Plugin.Mls.LogWarning((object)("Can't spawn daytime enemy " + enemyName + " on this moon.")); return false; } public bool IsTrapUnitSpawnable(string unit) { if (!IsTargetLevelSet()) { return false; } if (targetLevel.spawnableMapObjects.Any((SpawnableMapObject mapObject) => ((Object)mapObject.prefabToSpawn).name == unit)) { return true; } Plugin.Mls.LogWarning((object)("Can't spawn " + unit + " on this moon.")); return false; } public bool IsUnitSpawnable<T>() { if (!IsTargetLevelSet()) { return false; } if (targetLevel.spawnableMapObjects.Any((SpawnableMapObject mapObject) => mapObject.prefabToSpawn.GetComponentInChildren<T>() != null)) { return true; } Plugin.Mls.LogWarning((object)"Can't spawn T on this moon."); return false; } public bool IsScrapSpawnable(string itemName, bool logging = true) { if (!IsTargetLevelSet()) { return false; } if (targetLevel.spawnableScrap.Any((SpawnableItemWithRarity item) => item.spawnableItem.itemName.Equals(itemName, StringComparison.OrdinalIgnoreCase))) { return true; } if (logging) { Plugin.Mls.LogWarning((object)("Can't spawn scrap " + itemName + " on this moon.")); } return false; } public void ApplyModificationsToLevel() { if (IsTargetLevelSet()) { HullManager.LogBox("APPLYING LEVEL MODIFICATIONS"); ApplyEnemyComponentRarity(); ApplyEnemyComponentMaxCount(); ApplyEnemyComponentPower(); ApplyEnemySpawnChanceThroughoutDay(); ApplyMaxEnemyPower(); ApplyOutsideEnemyComponentRarity(); ApplyOutsideEnemyComponentMaxCount(); ApplyOutsideEnemyComponentPower(); ApplyOutsideEnemySpawnChanceThroughoutDay(); ApplyMaxOutsideEnemyPower(); ApplyDaytimeEnemyComponentRarity(); ApplyDaytimeEnemyComponentMaxCount(); ApplyDaytimeEnemyComponentPower(); ApplyDaytimeEnemySpawnChanceThroughoutDay(); ApplyMaxDaytimeEnemyPower(); ApplyLootRarity(); ApplyTimeScale(); ApplyUnitModification(); SceneManager.sceneUnloaded += OnSceneUnloaded; Active = true; } } public void UndoModifications() { if (IsTargetLevelSet()) { if (!Active) { Plugin.Mls.LogError((object)("Tried to undo modifications for " + targetLevel.PlanetName + " but levelmodifier is not active!")); return; } HullManager.LogBox("REVERTING LEVEL MODIFICATIONS"); Plugin.Mls.LogInfo((object)("Reverting all modifications to " + targetLevel.PlanetName + "!")); ApplyEnemyComponentRarity(undo: true); ApplyEnemyComponentMaxCount(undo: true); ApplyEnemyComponentPower(undo: true); ApplyEnemySpawnChanceThroughoutDay(undo: true); ApplyMaxEnemyPower(undo: true); ApplyOutsideEnemyComponentRarity(undo: true); ApplyOutsideEnemyComponentMaxCount(undo: true); ApplyOutsideEnemyComponentPower(undo: true); ApplyOutsideEnemySpawnChanceThroughoutDay(undo: true); ApplyMaxOutsideEnemyPower(undo: true); ApplyDaytimeEnemyComponentRarity(undo: true); ApplyDaytimeEnemyComponentMaxCount(undo: true); ApplyDaytimeEnemyComponentPower(undo: true); ApplyDaytimeEnemySpawnChanceThroughoutDay(undo: true); ApplyMaxDaytimeEnemyPower(undo: true); ApplyLootRarity(undo: true); ApplyTimeScale(undo: true); ApplyUnitModification(undo: true); SceneManager.sceneUnloaded -= OnSceneUnloaded; Active = false; } } public void UndoModificationsEarly() { SelectableLevel currentLevel = RoundManager.Instance.currentLevel; if ((Object)(object)currentLevel == (Object)null) { Plugin.Mls.LogWarning((object)"Trying to revert modifications when current level is null!"); } else if (currentLevel.levelID == 3) { Plugin.Mls.LogWarning((object)"Trying to revert modifications but current level is company building!"); } else if ((Object)(object)currentLevel != (Object)(object)targetLevel) { Plugin.Mls.LogWarning((object)("Tyring to undo modifications but currentLevel (" + currentLevel.PlanetName + ") levelModifier (" + targetLevel.PlanetName + ") don't match!")); } else { UndoModifications(); EventsHandler.Reset(); } } } [BepInPlugin("HullBreakerCompany", "HullBreakerCompany", "2.2.4")] public class Plugin : BaseUnityPlugin { private static bool _loaded; public static ManualLogSource Mls; public static bool compatibilityLQ; public static float BunkerEnemyScale; public static int LandmineScale; public static int SpikeTrapScale; public static int TurretScale; public static bool UseShortChatMessages; public static bool EnableEventMessages; public static bool UniqueEventMessages; public static bool ColoredEventMessages; public static bool UseHullBreakerLevelSettings; public static bool UseVanillaGameSettings; public static string LevelSettings; public static int MaxEnemyPowerCount; public static int MaxOutsideEnemyPowerCount; public static int MaxDaytimeEnemyPowerCount; public static bool IncreaseEventCountPerDay; public static int EventCount; public static int BountyRewardMin; public static int BountyRewardMax; public static int BountyRewardLimit; public static int HullBreakEventCreditsMin; public static int HullBreakEventCreditsMax; private readonly Harmony _harmony = new Harmony("HULLBREAKER"); private void Awake() { Mls = Logger.CreateLogSource("HULLBREAKER 2.2.4"); Mls.LogInfo((object)"Ready to break hull; HullBreakerCompany"); _harmony.PatchAll(typeof(Plugin)); _harmony.PatchAll(typeof(EventsHandler)); if (!_loaded) { Initialize(); } } public void Start() { if (!_loaded) { Initialize(); } } public void OnDestroy() { if (!_loaded) { Initialize(); } } public void Initialize() { //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_0010: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("HullManager"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<HullManager>(); SceneManager.sceneUnloaded += AfterGameInit; Mls.LogInfo((object)"HullManager created"); _loaded = true; } private void AfterGameInit(Scene scene) { if (!(((Scene)(ref scene)).name != "InitScene") || !(((Scene)(ref scene)).name != "InitSceneLANMode")) { if (Chainloader.PluginInfos.ContainsKey("LethalQuantities")) { Mls.LogInfo((object)"Lethal Quantities found! Applying compatibility patch!"); Harmony.CreateAndPatchAll(typeof(EventsManager), (string)null); } EventsManager.AddModEvents(); EventsManager.AddCustomEvents(); ConfigManager.RefreshConfig(); ConfigManager.GetWeights(); SceneManager.sceneUnloaded -= AfterGameInit; } } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] [HarmonyPriority(50)] private static bool ModifiedLoad(ref SelectableLevel newLevel) { Mls.LogInfo((object)("Client is host: " + ((NetworkBehaviour)RoundManager.Instance).IsHost)); if (!((NetworkBehaviour)RoundManager.Instance).IsHost) { Mls.LogInfo((object)"LoadNewLevel called as client. Stopping.."); return true; } HullManager.LogBox("MODIFIED LEVEL LOAD"); Mls.LogInfo((object)$"Attempting to load and modify new level. ID: {newLevel.levelID}, Scene: {newLevel.sceneName}, Planet: {newLevel.PlanetName}"); if (newLevel.levelID == 3) { Mls.LogInfo((object)"Level is company."); Mls.LogInfo((object)"Skipping modifications.."); return true; } ConfigManager.RefreshConfig(); EventsManager.ExecuteEvents(newLevel); return true; } private static void LQCompaitiblityPatch() { if (!compatibilityLQ && Chainloader.PluginInfos.ContainsKey("LethalQuantities")) { Mls.LogInfo((object)"Lethal Quantities found! Applying compatibility patch!"); Harmony.CreateAndPatchAll(typeof(EventsManager), (string)null); compatibilityLQ = true; } } } public static class PluginInfo { public const string PLUGIN_GUID = "HullBreakerCompany"; public const string PLUGIN_NAME = "HullBreakerCompany"; public const string PLUGIN_VERSION = "2.2.4"; } } namespace HullBreakerCompany.Hull { public class ConfigManager { private static string _configPath = Path.Combine(Paths.ConfigPath, "HullBreakerCompany.cfg"); private static ConfigFile _configFile; private static T GetConfigValue<T>(string section, string key, T defaultValue, string description = null) { EnsureConfigExists(); return _configFile.Bind<T>(section, key, defaultValue, description).Value; } private static void SetConfigValue() { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown Plugin.EventCount = GetConfigValue("1 - Event Settings", "EventCount", 1, "Maximum number of active events. Less are possible depending on NothingEvent's weight."); Plugin.IncreaseEventCountPerDay = GetConfigValue("1 - Event Settings", "IncreaseEventCountPerDay", defaultValue: true, "Whether to increase EventCount by one for each day passed. Resets when a new quota begins.\nSetting this to \"true\" and EventCount to n will roll n events on the first day, n+1 on the second, .."); Plugin.EnableEventMessages = GetConfigValue("1.1 - Event Messages", "EnableEventMessages", defaultValue: true, "Enable chat event messages"); Plugin.UseShortChatMessages = GetConfigValue("1.1 - Event Messages", "UseShortChatMessages", defaultValue: false, "Use short event message"); Plugin.UniqueEventMessages = GetConfigValue("1.1 - Event Messages", "UseUniqueChatMessages", defaultValue: false, "If true will use non ambigous messages in chat. Every event has a unique message that doesn't change."); Plugin.ColoredEventMessages = GetConfigValue("1.1 - Event Messages", "UseColoredChatMessages", defaultValue: false, "If true will use colors for event messages to indicate whether they are 'good' or 'bad' events."); Plugin.LandmineScale = GetConfigValue("1.2 - Event Configuration", "LandmineScale", 32, "The amount of additional landmines spawned by landmine event (there are more events that spawns mines and thus scale with the value set here)"); Plugin.TurretScale = GetConfigValue("1.2 - Event Configuration", "TurretScale", 12, "The amount of additional turrets spawned by turret event"); Plugin.SpikeTrapScale = GetConfigValue("1.2 - Event Configuration", "SpikeTrapScale", 12, "The amount of additional spike traps spawned by SpikeTrap event"); Plugin.BountyRewardMin = GetConfigValue("1.2 - Event Configuration", "BountyRewardMin", 20, "Minimum amount of credits rewarded for killing an enemy during EnemyBountyEvent"); Plugin.BountyRewardMax = GetConfigValue("1.2 - Event Configuration", "BountyRewardMax", 70, "Maximum amount of credits rewarded for killing an enemy during EnemyBountyEvent"); Plugin.BountyRewardLimit = GetConfigValue("1.2 - Event Configuration", "BountyRewardLimit", 10, "Limits the number of times you can get rewarded for kills during EnemyBountyEvent. Final reward will always pay `BountyRewardMax` * 1.5\nSet this to 0 for unlimited number of rewards."); Plugin.HullBreakEventCreditsMin = GetConfigValue("1.2 - Event Configuration", "HullBreakEventCreditsMin", 50, "Minimum amount of credits granted by HullBreakEvent"); Plugin.HullBreakEventCreditsMax = GetConfigValue("1.2 - Event Configuration", "HullBreakEventCreditsMax", 200, "Maximum amount of credits granted by HullBreakEvent"); Plugin.LevelSettings = _configFile.Bind<string>("2 - Level Settings", "LevelSettings", "vanilla", new ConfigDescription("Specifies the settings to apply to every level by default\nThese are baseline settings. Changes by events will always apply on top.\n'vanilla': keep level settings as they are\n'hullbreaker': hard difficulty. Significantly increases spawn rate inside and outside. Increases max power of inside and outside nemies by 16 and 20 respectively\n'custom': uses the values you specified below. Defaults for 'custom' are the values used in 'hullbreaker'\n", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "vanilla", "hullbreaker", "custom" }), Array.Empty<object>())).Value; Plugin.MaxEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxEnemyPowerCount", 16, "Increase max enemy power count by this value"); Plugin.MaxOutsideEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxOutsideEnemyPowerCount", 20, "Increase max outside enemy power count by this value (e.g. moutdog or forestgiant)"); Plugin.MaxDaytimeEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxDaytimeEnemyPowerCount", 0, "Increase max daytime enemy power count by this value (e.g. bees)"); Plugin.BunkerEnemyScale = GetConfigValue("2.1 - Level Settings", "Spawn curve override", 256, "Change spawn rate for inside enemies. A value of '256' will max out the amount of monsters spawned in each spawn wave starting as soon as you land."); } public static void RefreshConfig() { Plugin.Mls.LogInfo((object)"Refreshing config.."); _configFile = null; SetConfigValue(); } public static Dictionary<string, int> GetWeights() { Plugin.Mls.LogInfo((object)"Refreshing weights.."); EnsureConfigExists(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (HullEvent item in EventsManager.EventDictionary) { dictionary[item.GetID()] = _configFile.Bind<int>("3 - Event Weights", item.GetID(), item.GetWeight(), string.Format(item.GetID() + " event: " + item.GetDescription())).Value; } return dictionary; } private static void EnsureConfigExists() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (_configFile == null) { if (!File.Exists(_configPath)) { CreateDefaultConfigFile(); } _configFile = new ConfigFile(_configPath, true); } } private static void CreateDefaultConfigFile() { using StreamWriter streamWriter = File.CreateText(_configPath); streamWriter.WriteLine("[3 - Event Weights]"); foreach (HullEvent item in EventsManager.EventDictionary) { streamWriter.WriteLine(item.GetID() + "=" + item.GetWeight()); } } } public class CustomEventLoader { public static void LoadCustomEvents() { List<Dictionary<string, string>> list = LoadEventDataFromCfgFiles(); if (list.Count == 0) { return; } foreach (Dictionary<string, string> item in list) { CustomEvent customEvent = new CustomEvent(); customEvent.SetID(item["EventID"]); customEvent.SetWeight(int.Parse(item["EventWeight"])); foreach (string item2 in ParseMessages(item["InGameMessage"])) { customEvent.AddMessage(item2); } foreach (string item3 in ParseMessages(item["InGameShortMessage"])) { customEvent.AddShortMessage(item3); } if (item.ContainsKey("SpawnableEnemies")) { Plugin.Mls.LogDebug((object)"SpawnableEnemies defined. Parsing.."); customEvent.EnemySpawnList = ParseEnemies(item["SpawnableEnemies"]); } if (item.ContainsKey("SpawnableOutsideEnemies")) { Plugin.Mls.LogDebug((object)"SpawnableOutsideEnemies defined. Parsing.."); customEvent.OutsideEnemySpawnList = ParseEnemies(item["SpawnableOutsideEnemies"]); } if (item.ContainsKey("SpawnableDaytimeEnemies")) { Plugin.Mls.LogDebug((object)"SpawnableDaytimeEnemies defined. Parsing.."); customEvent.DaytimeEnemySpawnList = ParseEnemies(item["SpawnableDaytimeEnemies"]); } if (item.ContainsKey("SpawnableScrap")) { Plugin.Mls.LogDebug((object)"SpawnableScrap defined. Parsing.."); customEvent.ScrapSpawnList = ParseScrap(item["SpawnableScrap"]); } if (item.ContainsKey("GlobalPowerIncrease")) { Plugin.Mls.LogDebug((object)"GlobalPowerIncrease defined. Parsing.."); customEvent.addPower = int.Parse(item["GlobalPowerIncrease"]); } if (item.ContainsKey("GlobalOutsidePowerIncrease")) { Plugin.Mls.LogDebug((object)"GlobalOutsidePowerIncrease defined. Parsing.."); customEvent.addOutsidePower = int.Parse(item["GlobalOutsidePowerIncrease"]); } if (item.ContainsKey("GlobalDaytimePowerIncrease")) { Plugin.Mls.LogDebug((object)"GlobalDaytimePowerIncrease defined. Parsing.."); customEvent.addDaytimePower = int.Parse(item["GlobalDaytimePowerIncrease"]); } if (item.ContainsKey("GlobalInsideSpawnRateOverride")) { Plugin.Mls.LogDebug((object)"GlobalInsideSpawnRateOverride defined. Parsing.."); customEvent.overrideSpawnRate = int.Parse(item["GlobalInsideSpawnRateOverride"]); } if (item.ContainsKey("GlobalOutsideSpawnRateOverride")) { Plugin.Mls.LogDebug((object)"GlobalOutsideSpawnRateOverride defined. Parsing.."); customEvent.overrideOutsideSpawnRate = int.Parse(item["GlobalOutsideSpawnRateOverride"]); } if (item.ContainsKey("GlobalDaytimeSpawnRateOverride")) { Plugin.Mls.LogDebug((object)"GlobalDaytimeSpawnRateOverride defined. Parsing.."); customEvent.overrideDaytimeSpawnRate = int.Parse(item["GlobalDaytimeSpawnRateOverride"]); } AddEvent(customEvent); } } private static List<Dictionary<string, string>> LoadEventDataFromCfgFiles() { List<string> customEventDirectoryPaths = GetCustomEventDirectoryPaths(); List<string> list = new List<string>(); foreach (string item in customEventDirectoryPaths) { list.AddRange(Directory.GetFiles(item, "*.cfg")); } if (list.Count == 0) { return new List<Dictionary<string, string>>(); } List<Dictionary<string, string>> list2 = new List<Dictionary<string, string>>(); foreach (string item2 in list) { Dictionary<string, string> dictionary = ParseConfigFile(item2); if (dictionary != null) { list2.Add(dictionary); Plugin.Mls.LogInfo((object)("Loading custom event: " + dictionary["EventID"] + " (" + item2 + ")")); } } return list2; } private static List<string> GetCustomEventDirectoryPaths() { try { return (from dir in Directory.GetDirectories(Paths.BepInExRootPath, "*", SearchOption.AllDirectories) where Path.GetFileName(dir).Equals("HullEvents", StringComparison.OrdinalIgnoreCase) select dir).ToList(); } catch (Exception) { Plugin.Mls.LogInfo((object)"Custom event folder 'HullEvents' not found. Skipping custom event loading."); return new List<string>(); } } private static Dictionary<string, string> ParseConfigFile(string file) { string[] array = File.ReadAllLines(file); Dictionary<string, string> dictionary = new Dictionary<string, string>(); string[] array2 = array; foreach (string text in array2) { if (text.StartsWith("[DISABLED]")) { Plugin.Mls.LogInfo((object)("Custom Event configuration file (" + file + ") is disabled. Skipping..")); return null; } if (!text.StartsWith("[") && !text.StartsWith("#") && !string.IsNullOrWhiteSpace(text)) { string[] array3 = text.Split('='); if (array3.Length == 2) { string key = array3[0].Trim(); string value = array3[1].Trim(); dictionary.Add(key, value); } } } return dictionary; } private static List<string> ParseMessages(string configValue) { List<string> list = new List<string>(); string[] array = configValue.Split(';'); if (array.Length < 1) { Plugin.Mls.LogError((object)"Error while parsing custom event messages: no message defined"); return list; } string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrWhiteSpace(text)) { list.Add(text.Trim()); } } return list; } private static Dictionary<string, List<int>> ParseEnemies(string configValue) { Dictionary<string, List<int>> dictionary = new Dictionary<string, List<int>>(); string[] array = configValue.Split(','); foreach (string text in array) { string[] array2 = text.Split(":"); if (array2.Length < 2) { Plugin.Mls.LogWarning((object)("Invalid enemies format: " + text)); continue; } string text2 = array2[0].Trim(); int num = int.Parse(array2[1].Trim()); int num2 = ((array2.Length > 2) ? int.Parse(array2[2].Trim()) : (-1)); int num3 = ((array2.Length > 3) ? int.Parse(array2[3].Trim()) : (-1)); Plugin.Mls.LogDebug((object)$"Parsed enemy: (name = {text2}, rarity = {num}, maxCount = {num2}, Power = {num3})"); dictionary.Add(text2, new List<int>(3) { num, num2, num3 }); } return dictionary; } private static Dictionary<string, int> ParseScrap(string configValue) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); string[] array = configValue.Split(','); foreach (string text in array) { string[] array2 = text.Split(":"); if (array2.Length != 2) { Plugin.Mls.LogWarning((object)("Invalid scrap format: " + text)); continue; } string text2 = array2[0].Trim(); int num = int.Parse(array2[1].Trim()); Plugin.Mls.LogDebug((object)$"Parsed scrap item: (name = {text2}, rarity = {num})"); dictionary.Add(text2, num); } return dictionary; } private static void AddEvent(HullEvent newEvent) { if (EventsManager.EventDictionary.Any((HullEvent e) => e.GetID() == newEvent.GetID())) { Plugin.Mls.LogWarning((object)("Custom event " + newEvent.GetID() + " can't be added because an event with the same ID already exists! Check for duplicate config files.")); return; } Plugin.Mls.LogInfo((object)("Adding " + newEvent.GetID() + " to event dictionary")); EventsManager.EventDictionary.Add(newEvent); } public static void DebugLoadCustomEvents() { Plugin.Mls.LogInfo((object)"Listing all loaded custom events.."); foreach (HullEvent item in EventsManager.EventDictionary) { if (item is CustomEvent customEvent) { Plugin.Mls.LogInfo((object)("Event ID: " + customEvent.GetID())); Plugin.Mls.LogInfo((object)("Messages: " + customEvent.GetReadableMessages())); Plugin.Mls.LogInfo((object)("Short messages: " + customEvent.GetReadableShortMessage())); Plugin.Mls.LogInfo((object)("Enemies: " + string.Join("; ", customEvent.EnemySpawnList.Select((KeyValuePair<string, List<int>> enemy) => "[" + enemy.Key + ": Rarity percent = " + enemy.Value[0] + ", Max Count = " + enemy.Value[1] + ", Power Level = " + enemy.Value[2] + "]")))); Plugin.Mls.LogInfo((object)("Outside Enemies: " + string.Join("; ", customEvent.OutsideEnemySpawnList.Select((KeyValuePair<string, List<int>> enemy) => "[" + enemy.Key + ": Rarity percent = " + enemy.Value[0] + ", Max Count = " + enemy.Value[1] + ", Power Level = " + enemy.Value[2] + "]")))); Plugin.Mls.LogInfo((object)("Daytime Enemies: " + string.Join("; ", customEvent.DaytimeEnemySpawnList.Select((KeyValuePair<string, List<int>> enemy) => "[" + enemy.Key + ": Rarity percent = " + enemy.Value[0] + ", Max Count = " + enemy.Value[1] + ", Power Level = " + enemy.Value[2] + "]")))); Plugin.Mls.LogInfo((object)("Scrap: " + string.Join(", ", customEvent.ScrapSpawnList))); Plugin.Mls.LogInfo((object)$"Global power increase: {customEvent.addPower}"); Plugin.Mls.LogInfo((object)$"Global outside power increase: {customEvent.addOutsidePower}"); Plugin.Mls.LogInfo((object)$"Global daytime power increase: {customEvent.addDaytimePower}"); Plugin.Mls.LogInfo((object)$"Global spawn chance override: {customEvent.overrideSpawnRate}"); Plugin.Mls.LogInfo((object)$"Global outside spawn chance override: {customEvent.overrideOutsideSpawnRate}"); Plugin.Mls.LogInfo((object)$"Global daytime spawn chance override: {customEvent.overrideDaytimeSpawnRate}"); } } } } public abstract class EventsHandler { public static bool BountyIsActive; public static int BountyRewards; public static bool OneForAllIsActive; public static bool BountyFirstKill; public static bool MeltdownActive; public static bool OnAPowderKegActive; public static void Reset() { Plugin.Mls.LogInfo((object)"Resetting EventsHandler variables."); BountyIsActive = false; BountyRewards = 0; OneForAllIsActive = false; MeltdownActive = false; OnAPowderKegActive = false; } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "KillEnemy")] private static void EnemyBounty(bool destroy) { Plugin.Mls.LogInfo((object)$"Enemy killed, instance isHost: {((NetworkBehaviour)RoundManager.Instance).IsHost}"); if (!((NetworkBehaviour)RoundManager.Instance).IsHost) { return; } Plugin.Mls.LogInfo((object)$"Enemy killed, bounty is active: {BountyIsActive}; destroy is {destroy}"); if (BountyIsActive && !destroy) { int num = Random.Range(Plugin.BountyRewardMin, Plugin.BountyRewardMax); BountyRewards++; if (BountyFirstKill) { List<string> list = new List<string> { "Threat neutralized! Keep up the good work. The company sends [AMOUNT] credits.", "Enemy killed! Your work keeps the company happy. You receive [AMOUNT] credits.", "Monster killed! The company values your commitment. [AMOUNT] credits received." }; StringBuilder stringBuilder = new StringBuilder("<color=white>" + list[Random.Range(0, list.Count)] + "</color>"); stringBuilder.Replace("[AMOUNT]", "</color><color=green>" + num + "</color><color=white>"); HullManager.SendChatEventMessage(stringBuilder.ToString()); BountyFirstKill = false; } else if (Plugin.BountyRewardLimit > 0 && BountyRewards >= Plugin.BountyRewardLimit) { BountyIsActive = false; num = (int)Math.Floor((float)Plugin.BountyRewardMax * 1.5f); Plugin.Mls.LogInfo((object)("<color=white>Bounty complete! You receive </color><color=green>" + num + "</color><color=white> credits. Your handwork is invaluable to the company.")); } else { HullManager.SendChatEventMessage("<color=white>Bounty reward: </color><color=green>" + num + "</color><color=white> credits</color>"); } HullManager.Instance.AddMoney(num); Plugin.Mls.LogInfo((object)$"Bounty credits rewarded: {num}"); } } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "KillPlayerServerRpc")] private static void OneForAll() { if (((NetworkBehaviour)RoundManager.Instance).IsHost) { Plugin.Mls.LogInfo((object)$"Player killed, one for all is active: {OneForAllIsActive}"); if (OneForAllIsActive) { OneForAllIsActive = false; HullManager.Instance.timeOfDay.votedShipToLeaveEarlyThisRound = true; HullManager.Instance.timeOfDay.SetShipLeaveEarlyServerRpc(); HullManager.SendChatEventMessage("<color=red>Employee signal lost! Ship will leave in two hours!</color>"); } } } } public abstract class EventsManager { public static int DaysPassed; public static bool modEventsLoaded = false; public static bool customEventsLoaded = false; private static LevelModifier levelModifier; public static List<HullEvent> EventDictionary = new List<HullEvent> { new ArachnophobiaEvent(), new BeeEvent(), new BarberEvent(), new ButlerEvent(), new CrawlerEvent(), new DevochkaPizdecEvent(), new FlowerManEvent(), new HellEvent(), new HoarderBugEvent(), new LizardsEvent(), new MaskedEvent(), new NutcrackerEvent(), new SlimeEvent(), new SpringManEvent(), new EnemyBountyEvent(), new HackedTurretsEvent(), new HordeModeEvent(), new HullBreakEvent(), new LandMineEvent(), new NothingEvent(), new OnAPowderKegEvent(), new OneForAllEvent(), new OpenTheNoorEvent(), new OutSideEnemyDayEvent(), new SpikeTrapEvent(), new TimeAnomalyEvent(), new TimeDilationEvent(), new TurretEvent(), new ArmdayEvent(), new BabkinPogrebEvent(), new ChristmasEveEvent(), new ClownshowEvent(), new DayDrinkingEvent(), new LuckyDayEvent(), new SelfDefenseEvent() }; public static void AddModEvents() { if (modEventsLoaded) { return; } Plugin.Mls.LogInfo((object)"Checking for compatible mods.."); foreach (KeyValuePair<string, List<HullEvent>> item in new Dictionary<string, List<HullEvent>> { { "evaisa.lethalthings", new List<HullEvent>(1) { new BoombaEvent() } }, { "Kittenji.HerobrineMod", new List<HullEvent>(1) { new HerobrineEvent() } }, { "me.loaforc.facilitymeltdown", new List<HullEvent>(1) { new MeltdownEvent() } }, { "Scopophobia", new List<HullEvent>(1) { new ShyGuyEvent() } }, { "com.potatoepet.AdvancedCompany", new List<HullEvent>(3) { new BunnyEvent(), new ControllerEvent(), new RGBShoesEvent() } }, { "Dackie.SCP106", new List<HullEvent>(1) { new RottingManEvent() } }, { "ProjectSCP.SCP3199", new List<HullEvent>(1) { new EggmanEvent() } }, { "ProjectSCP.SCP966", new List<HullEvent>(1) { new InvisibleGuestEvent() } }, { "Surfaced", new List<HullEvent>(3) { new BruceAlmightyEvent(), new SeaMineEvent(), new UrchinEvent() } }, { "TestAccount666.TestAccountVariety", new List<HullEvent>(3) { new CageMineEvent(), new GiftMimicEvent(), new PropulsionMineEvent() } } }) { if (Chainloader.PluginInfos.ContainsKey(item.Key)) { Plugin.Mls.LogInfo((object)(Chainloader.PluginInfos[item.Key].Metadata.Name + " found! Enabling events: " + string.Join(", ", item.Value.Select((HullEvent e) => e.GetID())))); foreach (HullEvent item2 in item.Value) { EventDictionary.Add(item2); } } else { Plugin.Mls.LogDebug((object)(item.Key + " not present! Not loading associated events..")); } } modEventsLoaded = true; } public static void AddCustomEvents() { if (!customEventsLoaded) { Plugin.Mls.LogInfo((object)"Checking for custom events.."); CustomEventLoader.LoadCustomEvents(); CustomEventLoader.DebugLoadCustomEvents(); customEventsLoaded = true; } } public static void ExecuteEvents(SelectableLevel newLevel) { HullManager.LogBox("EVENT EXECUTION"); levelModifier = new LevelModifier(newLevel); UpdateLevelSettings(); RefreshDaysPassed(); List<HullEvent> list = new List<HullEvent>(); int num = (Plugin.IncreaseEventCountPerDay ? (Plugin.EventCount + DaysPassed) : Plugin.EventCount); Plugin.Mls.LogInfo((object)$"Round events: {num}"); Plugin.Mls.LogInfo((object)"Start event selection.."); RandomSelector.InitializeWeights(); while (list.Count() < num) { string newEvent = RandomSelector.GetRandomGameEvent(); if (newEvent == null) { Plugin.Mls.LogInfo((object)"Event selection failed. No events left to execute.."); break; } HullEvent hullEvent = EventDictionary.FirstOrDefault((HullEvent e) => e.GetID() == newEvent); if (hullEvent == null) { Plugin.Mls.LogWarning((object)("Couldn't find event " + newEvent + " in event dictionary!")); continue; } Plugin.Mls.LogInfo((object)("Got event: " + hullEvent.GetID())); if (hullEvent.Execute(newLevel, levelModifier)) { list.Add(hullEvent); } else { Plugin.Mls.LogInfo((object)("Skipping event: " + hullEvent.GetID())); } } Plugin.Mls.LogInfo((object)$"Selected events: {list.Count()}"); Plugin.Mls.LogInfo((object)string.Format("Nothing events: {0}", list.Where((HullEvent e) => e.GetID().Equals("Nothing")).Count())); list.RemoveAll((HullEvent e) => e.GetID().Equals("Nothing")); Plugin.Mls.LogInfo((object)string.Format("Active events: {0} [{1}]", list.Count(), string.Join(", ", list.Select((HullEvent e) => e.GetID())))); levelModifier.ApplyModificationsToLevel(); HullManager.SendChatEventMessages(); PrintDebugLogs(newLevel); } private static int RefreshDaysPassed() { DaysPassed = HullManager.Instance.timeOfDay.quotaVariables.deadlineDaysAmount - HullManager.Instance.timeOfDay.daysUntilDeadline; Plugin.Mls.LogInfo((object)$"Days passed: {DaysPassed}"); return DaysPassed; } private static void UpdateLevelSettings() { Plugin.Mls.LogInfo((object)("Level Settings config value: " + Plugin.LevelSettings)); string levelSettings = Plugin.LevelSettings; if (!(levelSettings == "hullbreaker")) { if (levelSettings == "custom") { Plugin.Mls.LogInfo((object)"Applying custom level settings from config"); levelModifier.AddMaxEnemyPower(Plugin.MaxEnemyPowerCount); levelModifier.AddMaxOutsideEnemyPower(Plugin.MaxOutsideEnemyPowerCount); levelModifier.AddMaxDaytimeEnemyPower(Plugin.MaxDaytimeEnemyPowerCount); levelModifier.AddEnemySpawnChanceThroughoutDay((int)Plugin.BunkerEnemyScale); } else { Plugin.Mls.LogInfo((object)"Keeping Vanilla level settings"); } } else { Plugin.Mls.LogInfo((object)"Applying Hullbreaker level settings"); levelModifier.AddMaxEnemyPower(16); levelModifier.AddMaxOutsideEnemyPower(20); levelModifier.AddEnemySpawnChanceThroughoutDay(256); levelModifier.AddDaytimeEnemySpawnChanceThroughoutDay(5); } } private static void PrintDebugLogs(SelectableLevel level) { HullManager.LogEnemies(level.Enemies, "INSIDE ENEMIES"); HullManager.LogEnemies(level.OutsideEnemies, "OUTSIDE ENEMIES"); HullManager.LogEnemies(level.DaytimeEnemies, "DAYTIME ENEMIES"); HullManager.LogScrapRarity(level.spawnableScrap, "LOOT TABLE"); HullManager.LogMapHazards(level.spawnableMapObjects.ToList(), "MAP HAZARDS"); } [HarmonyPatch(typeof(RoundState), "OnDestroy")] [HarmonyPrefix] public static void RoundStateOnDestroyPrefix() { if (levelModifier == null) { Plugin.Mls.LogInfo((object)"No levelModifier found. No modifications to revert."); return; } levelModifier.UndoModificationsEarly(); levelModifier = null; } } public abstract class HullEvent { public string ID = "Default"; public int Weight; public string Description = "Default description"; public List<string> MessagesList = new List<string>(1) { "Default event message" }; public List<string> shortMessagesList = new List<string>(1) { "MESSAGE" }; public virtual string GetID() { return ID; } public virtual int GetWeight() { return Weight; } public virtual string GetDescription() { return Description; } public virtual string GetMessage() { if (Plugin.UniqueEventMessages) { return MessagesList.Last(); } return MessagesList[Random.Range(0, MessagesList.Count)]; } public virtual string GetShortMessage() { if (Plugin.UniqueEventMessages) { return shortMessagesList.Last(); } return shortMessagesList[Random.Range(0, shortMessagesList.Count)]; } public virtual bool Execute(SelectableLevel level, LevelModifier levelModifier) { return true; } public virtual bool SimulateExecution(SelectableLevel level, LevelModifier levelModifier, Dictionary<string, List<int>> enemies, Dictionary<string, List<int>> OutsideEnemies, Dictionary<string, List<int>> DaytimeEnemies, Dictionary<string, int> scrap) { if (enemies != null && enemies.Count > 0 && enemies.Any((KeyValuePair<string, List<int>> enemy) => !levelModifier.IsEnemySpawnable(enemy.Key))) { return false; } if (OutsideEnemies != null && OutsideEnemies.Count > 0 && OutsideEnemies.Any((KeyValuePair<string, List<int>> enemy) => !levelModifier.IsOutsideEnemySpawnable(enemy.Key))) { return false; } if (DaytimeEnemies != null && DaytimeEnemies.Count > 0 && DaytimeEnemies.Any((KeyValuePair<string, List<int>> enemy) => !levelModifier.IsDaytimeEnemySpawnable(enemy.Key))) { return false; } if (scrap != null && scrap.Count > 0 && scrap.All((KeyValuePair<string, int> item) => !levelModifier.IsScrapSpawnable(item.Key))) { Plugin.Mls.LogWarning((object)(GetID() + ": has scrap defined but none of them are spawnable in this level.")); return false; } return true; } public virtual Dictionary<string, int> CalculateScrapRarities(Dictionary<string, int> inputScrap, LevelModifier levelModifier, bool logging = true) { int num = 0; int num2 = 0; Dictionary<string, int> dictionary = new Dictionary<string, int>(); Plugin.Mls.LogInfo((object)(GetID() + ": Scrap rarities (% of total) [" + string.Join(", ", inputScrap.Select((KeyValuePair<string, int> scrap) => scrap.Key + ":" + scrap.Value)) + "]")); foreach (KeyValuePair<string, int> item in inputScrap) { num += item.Value; if (levelModifier.IsScrapSpawnable(item.Key, logging: false)) { num2 += item.Value; dictionary.TryAdd(item.Key, item.Value); } } new Dictionary<string, int>(dictionary); foreach (KeyValuePair<string, int> item2 in inputScrap) { if (dictionary.ContainsKey(item2.Key)) { dictionary[item2.Key] = (int)Math.Round((double)item2.Value / (double)num2 * (double)num); } } if (dictionary.Count() != inputScrap.Count()) { Plugin.Mls.LogInfo((object)"Recalculated scrap rarities to compensate for items that are not in this moon's loot table.."); Plugin.Mls.LogInfo((object)(GetID() + ": New rarities (% of total) [" + string.Join(", ", dictionary.Select((KeyValuePair<string, int> scrap) => scrap.Key + ":" + scrap.Value)) + "]")); } return dictionary; } } public class HullManager : MonoBehaviour { public TimeOfDay timeOfDay; public static List<string> chatMessages = new List<string>(); public static HullManager Instance { get; private set; } public void Update() { if ((Object)(object)timeOfDay == (Object)null) { timeOfDay = Object.FindFirstObjectByType<TimeOfDay>(); } } public void Start() { Plugin.Mls.LogDebug((object)"Start: HullManager"); } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } public void AddMoney(int amount) { Terminal val = Object.FindObjectOfType<Terminal>(); val.groupCredits += amount; val.SyncGroupCreditsServerRpc(val.groupCredits, val.numberOfItemsInDropship); } public void ExecuteAfterDelay(Action action, float delay) { ((MonoBehaviour)this).StartCoroutine(DelayedExecution(action, delay)); } private IEnumerator DelayedExecution(Action action, float delay) { yield return (object)new WaitForSeconds(delay); action(); } public static void AddChatEventMessage(HullEvent hullEvent) { string text = ""; if ((Object)(object)HUDManager.Instance != (Object)null && hullEvent != null && Plugin.EnableEventMessages) { text = (Plugin.UseShortChatMessages ? hullEvent.GetShortMessage() : hullEvent.GetMessage()); } chatMessages.Add("<color=white>" + text + "</color>"); } public static void AddChatEventMessageColored(HullEvent hullEvent, string color = "white") { string text = ""; if ((Object)(object)HUDManager.Instance != (Object)null && hullEvent != null && Plugin.EnableEventMessages) { text = (Plugin.UseShortChatMessages ? hullEvent.GetShortMessage() : hullEvent.GetMessage()); } chatMessages.Add("<color=" + color + ">" + text + "</color>"); } public static void AddChatEventMessage(string message, bool addAsFirst = false) { if ((Object)(object)HUDManager.Instance != (Object)null && message != null && Plugin.EnableEventMessages) { if (!addAsFirst) { chatMessages.Add(message); } else { chatMessages.Insert(0, message); } } } public static void SendChatEventMessage(string message) { if ((Object)(object)HUDManager.Instance != (Object)null && message != null && Plugin.EnableEventMessages) { HUDManager.Instance.AddTextToChatOnServer(message, -1); } } public static void SendChatEventMessages() { if ((Object)(object)HUDManager.Instance != (Object)null && Plugin.EnableEventMessages && chatMessages.Count > 0) { if (Plugin.ColoredEventMessages) { AddChatEventMessage("NOTES ABOUT MOON:", addAsFirst: true); } else { AddChatEventMessage("<color=red>NOTES ABOUT MOON:</color>", addAsFirst: true); } foreach (string chatMessage in chatMessages) { HUDManager.Instance.AddTextToChatOnServer(chatMessage, -1); } } chatMessages.Clear(); } public static void LogEnemies(List<SpawnableEnemyWithRarity> enemies, string title) { LogBoxHeader(title); Plugin.Mls.LogInfo((object)string.Format("╠{0, -40}╦{1, 12}╤{2, 12}╤{3, 12}╤{4, 12}╗", new string('═', 39).Insert(title.Length + 2, "╩"), new string('═', 12), new string('═', 12), new string('═', 12), new string('═', 12))); Plugin.Mls.LogInfo((object)string.Format("║ {0, -38} ║ {1, 10} │ {2, 10} │ {3, 10} │ {4, 10} ║", "Enemy", "Rarity", "Chance", "MaxCount", "Power")); Plugin.Mls.LogInfo((object)$"╠{new string('═', 40),-40}╬{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╣"); int num = 0; foreach (SpawnableEnemyWithRarity enemy in enemies) { num += enemy.rarity; } foreach (SpawnableEnemyWithRarity enemy2 in enemies) { try { Plugin.Mls.LogInfo((object)$"║ {((Object)enemy2.enemyType.enemyPrefab).name,-38} ║ {enemy2.rarity,10} │ {$"{Math.Round((float)enemy2.rarity / (float)num * 100f, 2)}%",10} │ {enemy2.enemyType.MaxCount,10} │ {enemy2.enemyType.PowerLevel,10} ║"); } catch (Exception ex) { Plugin.Mls.LogError((object)ex.Message); } } Plugin.Mls.LogInfo((object)$"╠{new string('═', 40),-40}╬{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╣"); Plugin.Mls.LogInfo((object)string.Format("║ {0, -38} ║ {1, 10} │ {2, 10} │ {3, 10} │ {4, 10} ║", "Sum", num, "", "", "")); Plugin.Mls.LogInfo((object)$"╚{new string('═', 40),-40}╩{new string('═', 12),12}╧{new string('═', 12),12}╧{new string('═', 12),12}╧{new string('═', 12),12}╝"); } public static void LogScrapRarity(List<SpawnableItemWithRarity> loot, string title) { LogBoxHeader(title); Plugin.Mls.LogInfo((object)string.Format("╠{0, -30}╤{1, 12}╤{2, 12}╗", new string('═', 29).Insert(title.Length + 2, "╩"), new string('═', 12), new string('═', 12))); Plugin.Mls.LogInfo((object)string.Format("║ {0, -28} │ {1, 10} │ {2, 10} ║", "Scrap item", "Rarity", "Chance")); Plugin.Mls.LogInfo((object)$"╠{new string('═', 30),-30}╪{new string('═', 12),12}╪{new string('═', 12),12}╣"); int num = 0; foreach (SpawnableItemWithRarity item in loot) { if (item != null) { num += item.rarity; } } foreach (SpawnableItemWithRarity item2 in loot) { if (item2 != null) { Plugin.Mls.LogInfo((object)$"║ {item2.spawnableItem.itemName,-28} │ {item2.rarity,10} │ {$"{Math.Round((float)item2.rarity / (float)num * 100f, 2)}%",10} ║"); } } Plugin.Mls.LogInfo((object)$"╠{new string('═', 30),-30}╪{new string('═', 12),12}╪{new string('═', 12),12}╣"); Plugin.Mls.LogInfo((object)string.Format("║ {0, -28} │ {1, 10} │ {2, 10} ║", "Sum", num, "")); Plugin.Mls.LogInfo((object)$"╚{new string('═', 30),-30}╧{new string('═', 12),12}╧{new string('═', 12),12}╝"); } public static void LogMapHazards(List<SpawnableMapObject> hazards, string title) { LogBoxHeader(title); Plugin.Mls.LogInfo((object)string.Format("╠{0, -30}╤{1, 12}╗", new string('═', 29).Insert(title.Length + 2, "╩"), new string('═', 12))); Plugin.Mls.LogInfo((object)string.Format("║ {0, -28} │ {1, 10} ║", "Map Hazard", "AvgCount")); Plugin.Mls.LogInfo((object)$"╠{new string('═', 30),-30}╪{new string('═', 12),12}╣"); foreach (SpawnableMapObject hazard in hazards) { if (hazard != null) { int num = (int)(hazard.numberToSpawn.GetKeys().Sum((Keyframe key) => key.m_Value) / (float)hazard.numberToSpawn.GetKeys().Length); Plugin.Mls.LogInfo((object)$"║ {((Object)hazard.prefabToSpawn).name,-28} │ {num,10} ║"); } } Plugin.Mls.LogInfo((object)$"╚{new string('═', 30),-30}╧{new string('═', 12),12}╝"); } public static void LogBox(string title) { Plugin.Mls.LogInfo((object)("╔" + new string('═', title.Length + 2) + "╗")); Plugin.Mls.LogInfo((object)("║ " + title + " ║")); Plugin.Mls.LogInfo((object)("╚" + new string('═', title.Length + 2) + "╝")); } private static void LogBoxHeader(string title) { Plugin.Mls.LogInfo((object)("╔" + new string('═', title.Length + 2) + "╗")); Plugin.Mls.LogInfo((object)("║ " + title + " ║")); } } public abstract class RandomSelector { private static readonly Random _random = new Random(); private static Dictionary<string, int> weights = new Dictionary<string, int>(); public static void InitializeWeights() { weights = ConfigManager.GetWeights(); } public static string GetRandomGameEvent() { int num = weights.Where((KeyValuePair<string, int> x) => x.Value > 0).Sum((KeyValuePair<string, int> x) => x.Value); if (num < 1) { return null; } string text = ""; int num2 = _random.Next(num); foreach (KeyValuePair<string, int> weight in weights) { if (weight.Value != 0) { if (num2 < weight.Value) { text = weight.Key; break; } num2 -= weight.Value; } } if (string.IsNullOrEmpty(text)) { return null; } if (text != "Nothing") { weights.Remove(text); } return text; } private static void Shuffle<T>(IList<T> list) { int num = list.Count; while (num > 1) { num--; int num2 = _random.Next(num + 1); int index = num2; int index2 = num; T value = list[num]; T value2 = list[num2]; list[index] = value; list[index2] = value2; } } } internal class Util { private static Dictionary<string, Type> EnemyBase = new Dictionary<string, Type> { { "flowerman", typeof(FlowermanAI) }, { "hoarderbug", typeof(HoarderBugAI) }, { "springman", typeof(SpringManAI) }, { "crawler", typeof(CrawlerAI) }, { "sandspider", typeof(SandSpiderAI) }, { "jester", typeof(JesterAI) }, { "centipede", typeof(CentipedeAI) }, { "blobai", typeof(BlobAI) }, { "dressgirl", typeof(DressGirlAI) }, { "pufferenemy", typeof(PufferAI) }, { "eyelessdogs", typeof(MouthDogAI) }, { "forestgiant", typeof(ForestGiantAI) }, { "sandworm", typeof(SandWormAI) }, { "baboonbird", typeof(BaboonBirdAI) }, { "nutcrackerenemy", typeof(NutcrackerEnemyAI) }, { "maskedplayerenemy", typeof(MaskedPlayerEnemy) } }; private static Dictionary<Type, string> EnemiesByType = new Dictionary<Type, string> { { typeof(FlowermanAI), "Flowerman" }, { typeof(HoarderBugAI), "HoarderBug" }, { typeof(SpringManAI), "SpringMan" }, { typeof(CrawlerAI), "Crawler" }, { typeof(SandSpiderAI), "SandSpider" }, { typeof(JesterAI), "Jester" }, { typeof(CentipedeAI), "Centipede" }, { typeof(BlobAI), "Blob" }, { typeof(DressGirlAI), "DressGirl" }, { typeof(PufferAI), "PufferEnemy" }, { typeof(MouthDogAI), "MouthDog" }, { typeof(ForestGiantAI), "ForestGiant" }, { typeof(SandWormAI), "SandWorm" }, { typeof(BaboonBirdAI), "BaboonBird" }, { typeof(NutcrackerEnemyAI), "NutcrackerEnemy" }, { typeof(MaskedPlayerEnemy), "MaskedPlayerEnemy" }, { typeof(ButlerEnemyAI), "ButlerEnemy" }, { typeof(RedLocustBees), "RedLocustBees" } }; private static Dictionary<Type, string> TrapUnitsByType = new Dictionary<Type, string> { { typeof(Landmine), "Landmine" }, { typeof(Turret), "TurretContainer" }, { typeof(SpikeRoofTrap), "SpikeRoofTrapHazard" } }; public static string getEnemyByType(Type type) { try { EnemiesByType.TryGetValue(type, out var value); return value; } catch { return null; } } public static Type getEnemyByString(string str) { try { EnemyBase.TryGetValue(str, out var value); return value; } catch { return null; } } public static string getTrapUnitByType(Type type) { try { TrapUnitsByType.TryGetValue(type, out var value); return value; } catch { return null; } } } } namespace HullBreakerCompany.Events { public class CustomEvent : HullEvent { private string _id; private int _weight; private List<string> MessageList = new List<string>(); private List<string> ShortMessageList = new List<string>(); public Dictionary<string, List<int>> EnemySpawnList = new Dictionary<string, List<int>>(); public Dictionary<string, List<int>> OutsideEnemySpawnList = new Dictionary<string, List<int>>(); public Dictionary<string, List<int>> DaytimeEnemySpawnList = new Dictionary<string, List<int>>(); public Dictionary<string, int> ScrapSpawnList = new Dictionary<string, int>(); public int addPower; public int addOutsidePower; public int addDaytimePower; public int overrideSpawnRate; public int overrideOutsideSpawnRate; public int overrideDaytimeSpawnRate; public override string GetID() { return _id; } public void SetID(string value) { _id = value; } public void SetWeight(int value) { _weight = value; } public override int GetWeight() { return _weight; } public void AddMessage(string msg) { MessageList.Add(msg); } public void AddShortMessage(string msg) { ShortMessageList.Add(msg); } public override string GetMessage() { return "<color=white>" + MessageList[Random.Range(0, MessageList.Count)] + "</color>"; } public string GetReadableMessages() { return string.Join("; ", MessageList); } public override string GetShortMessage() { return "<color=white>" + ShortMessageList[Random.Range(0, ShortMessageList.Count)] + "</color>"; } public string GetReadableShortMessage() { return string.Join("; ", ShortMessageList); } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!SimulateExecution(level, levelModifier, EnemySpawnList, OutsideEnemySpawnList, DaytimeEnemySpawnList, ScrapSpawnList)) { return false; } foreach (KeyValuePair<string, List<int>> enemySpawn in EnemySpawnList) { levelModifier.AddEnemyComponentRarity(enemySpawn.Key, enemySpawn.Value[0]); if (enemySpawn.Value[1] > -1) { levelModifier.AddEnemyComponentMaxCount(enemySpawn.Key, enemySpawn.Value[1]); } if (enemySpawn.Value[2] > -1) { levelModifier.AddEnemyComponentPower(enemySpawn.Key, enemySpawn.Value[2]); } } foreach (KeyValuePair<string, List<int>> outsideEnemySpawn in OutsideEnemySpawnList) { levelModifier.AddOutsideEnemyComponentRarity(outsideEnemySpawn.Key, outsideEnemySpawn.Value[0]); if (outsideEnemySpawn.Value[1] > -1) { levelModifier.AddOutsideEnemyComponentMaxCount(outsideEnemySpawn.Key, outsideEnemySpawn.Value[1]); } if (outsideEnemySpawn.Value[2] > -1) { levelModifier.AddOutsideEnemyComponentPower(outsideEnemySpawn.Key, outsideEnemySpawn.Value[2]); } } foreach (KeyValuePair<string, List<int>> daytimeEnemySpawn in DaytimeEnemySpawnList) { levelModifier.AddDaytimeEnemyComponentRarity(daytimeEnemySpawn.Key, daytimeEnemySpawn.Value[0]); if (daytimeEnemySpawn.Value[1] > -1) { levelModifier.AddDaytimeEnemyComponentMaxCount(daytimeEnemySpawn.Key, daytimeEnemySpawn.Value[1]); } if (daytimeEnemySpawn.Value[2] > -1) { levelModifier.AddDaytimeEnemyComponentPower(daytimeEnemySpawn.Key, daytimeEnemySpawn.Value[2]); } } if (ScrapSpawnList.Count > 0) { ScrapSpawnList = CalculateScrapRarities(ScrapSpawnList, levelModifier); if (ScrapSpawnList != null && ScrapSpawnList.Count > 0) { levelModifier.AddSpawnableScrapRarityDict(ScrapSpawnList); } } if (addPower > 0) { levelModifier.AddMaxEnemyPower(addPower); } if (addOutsidePower > 0) { levelModifier.AddMaxOutsideEnemyPower(addOutsidePower); } if (addDaytimePower > 0) { levelModifier.AddMaxDaytimeEnemyPower(addDaytimePower); } if (overrideSpawnRate > 0) { levelModifier.AddEnemySpawnChanceThroughoutDay(overrideSpawnRate); } if (overrideOutsideSpawnRate > 0) { levelModifier.AddOutsideEnemySpawnChanceThroughoutDay(overrideOutsideSpawnRate); } if (overrideDaytimeSpawnRate > 0) { levelModifier.AddDaytimeEnemySpawnChanceThroughoutDay(overrideDaytimeSpawnRate); } HullManager.AddChatEventMessage(this); return true; } } } namespace HullBreakerCompany.Events.Scrap { public class ArmdayEvent : HullEvent { public ArmdayEvent() { ID = "Armday"; Weight = 20; Description = "Spawns a lot of heavy loot."; MessagesList = new List<string> { "Expect a lot of big heavy scrap!", "Grip strength required! Heavy duty scrap.", "Slipped disks are not covered by company insurance!", "Lift heavy objects with a jerking twisting motion!", "Lower back pain" }; shortMessagesList = new List<string> { "HEAVY" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { Dictionary<string, int> inputScrap = new Dictionary<string, int> { { "Metal sheet", 20 }, { "Large axle", 10 }, { "V-type Engine", 10 }, { "Stop sign", 10 }, { "Yield sign", 10 }, { "Fire hydrant", 15 }, { "Broken engine", 10 }, { "Anvil", 5 } }; inputScrap = CalculateScrapRarities(inputScrap, levelModifier); if (inputScrap.Count == 0) { return false; } levelModifier.AddSpawnableScrapRarityDict(inputScrap); HullManager.AddChatEventMessage(this); return true; } } public class BabkinPogrebEvent : HullEvent { public static List<SpawnableItemWithRarity> scrapList = new List<SpawnableItemWithRarity>(); public BabkinPogrebEvent() { ID = "BabkinPogreb"; Weight = 20; Description = "Spawns a lot of pickle jars."; MessagesList = new List<string> { "Scans indicate all scrap is.. organic?", "There is something wrong with the scrap..", "We lost Rick. Find him!", "Quite a pickle indeed!" }; shortMessagesList = new List<string> { "QUITE A PICKLE" }; } public override string GetMessage() { return MessagesList[Random.Range(0, MessagesList.Count)]; } public override string GetShortMessage() { return shortMessagesList[Random.Range(0, shortMessagesList.Count)]; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { string text = "Jar of pickles"; if (levelModifier.IsScrapSpawnable(text)) { levelModifier.AddSpawnableScrapRarity(text, 100); HullManager.AddChatEventMessage(this); return true; } return false; } } public class ChristmasEveEvent : HullEvent { public ChristmasEveEvent() { ID = "ChristmasEve"; Weight = 20; Description = "Spawns a lot of gifts."; MessagesList = new List<string> { "Is it Christmas already?", "Help Santa collect the presents!", "The Company wishes a Merry Christmas!" }; shortMessagesList = new List<string> { "XMAS" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { string text = "Gift"; if (levelModifier.IsScrapSpawnable(text)) { levelModifier.AddSpawnableScrapRarity(text, 300); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "green"); } else { HullManager.AddChatEventMessage(this); } return true; } return false; } } public class ClownshowEvent : HullEvent { public ClownshowEvent() { ID = "Clownshow"; Weight = 20; Description = "Spawns a lot of noisy scrap."; MessagesList = new List<string> { "This is a clown show!", "Your clown nose fell off.." }; shortMessagesList = new List<string> { "CLOWN" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { Dictionary<string, int> inputScrap = new Dictionary<string, int> { { "Airhorn", 30 }, { "Clown horn", 30 }, { "Candy", 30 }, { "Whoopie cushion", 10 } }; inputScrap = CalculateScrapRarities(inputScrap, levelModifier); if (inputScrap.Count == 0) { return false; } levelModifier.AddSpawnableScrapRarityDict(inputScrap); HullManager.AddChatEventMessage(this); return true; } } public class DayDrinkingEvent : HullEvent { public DayDrinkingEvent() { ID = "DayDrinking"; Weight = 20; Description = "Spawns a lot of alcoholic beverages."; MessagesList = new List<string> { "Let's crack a beer or two!", "Alcohol use prohibited during work hours!", "There is something wrong with the scrap.." }; shortMessagesList = new List<string> { "DAYDRINKING" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { Dictionary<string, int> inputScrap = new Dictionary<string, int> { { "Bottles", 30 }, { "Alcohol Flask", 25 }, { "Wine bottle", 10 }, { "Canteen", 25 } }; inputScrap = CalculateScrapRarities(inputScrap, levelModifier); if (inputScrap.Count == 0) { return false; } levelModifier.AddSpawnableScrapRarityDict(inputScrap); HullManager.AddChatEventMessage(this); return true; } } public class EasterEvent : HullEvent { public EasterEvent() { ID = "Easter"; Weight = 10; Description = "Spawns a lot of easter eggs."; MessagesList = new List<string> { "Festive decorations", "Help the Easter bunny collect the Easter eggs!", "Is this an Easter egg?", "↑ ↑ ↓ ↓ ← → ← → Ⓐ Ⓑ" }; shortMessagesList = new List<string> { "EGG" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { string text = "Easter egg"; if (levelModifier.IsScrapSpawnable(text)) { levelModifier.AddSpawnableScrapRarity(text, 33); HullManager.AddChatEventMessage(this); return true; } return false; } } public class LuckyDayEvent : HullEvent { public LuckyDayEvent() { ID = "LuckyDay"; Weight = 5; Description = "Increases spawn chance of high value loot."; MessagesList = new List<string> { "High value scrap detected!", "Supposed to hold some very valuable scrap", "Today's your lucky day!" }; shortMessagesList = new List<string> { "LUCKY" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { Dictionary<string, int> inputScrap = new Dictionary<string, int> { { "Cash register", 20 }, { "Gold bar", 20 } }; inputScrap = CalculateScrapRarities(inputScrap, levelModifier); if (inputScrap.Count == 0) { return false; } levelModifier.AddSpawnableScrapRarityDict(inputScrap); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "green"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class SelfDefenseEvent : HullEvent { public SelfDefenseEvent() { ID = "SelfDefense"; Weight = 20; Description = "Spawns a lot of scrap that can be utilized as weapon."; MessagesList = new List<string> { "Weapons scattered all around!", "DIY self defense training today!" }; shortMessagesList = new List<string> { "WEAPONS" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { Dictionary<string, int> inputScrap = new Dictionary<string, int> { { "Plunger", 20 }, { "Stop sign", 15 }, { "Yield sign", 15 }, { "Baseball bat", 15 }, { "Toy Hammer", 10 }, { "Fireaxe", 5 } }; inputScrap = CalculateScrapRarities(inputScrap, levelModifier); if (inputScrap.Count == 0) { return false; } levelModifier.AddSpawnableScrapRarityDict(inputScrap); HullManager.AddChatEventMessage(this); return true; } } } namespace HullBreakerCompany.Events.Misc { public class MeltdownEvent : HullEvent { public int dayInSeconds; public int currentDaysLeft; public MeltdownEvent() { ID = "Meltdown"; Weight = 10; Description = "Starts reactor meltdown sequence sometime during the day."; MessagesList = new List<string> { "Unstable reactor core. Extract and leave immediately!", "Elevated radiation levels. Reactor meltdown imminent!", "Prevent a nuclear disaster by gracefully removing the apparatus core", "Increased radiation levels. Don't wander too far off the ship." }; shortMessagesList = new List<string> { "SURPRISE", "MELTDOWN" }; } public override string GetMessage() { return MessagesList[Random.Range(0, MessagesList.Count)]; } public override string GetShortMessage() { return shortMessagesList[Random.Range(0, shortMessagesList.Count)]; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { currentDaysLeft = TimeOfDay.Instance.daysUntilDeadline; dayInSeconds = (int)HullManager.Instance.timeOfDay.lengthOfHours * HullManager.Instance.timeOfDay.numberOfHours; if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } HullManager.Instance.ExecuteAfterDelay(delegate { StartMeltdown(); }, Random.Range((float)dayInSeconds * 0.3f, (float)dayInSeconds * 0.8f)); EventsHandler.MeltdownActive = true; return true; } private void StartMeltdown() { if (!EventsHandler.MeltdownActive || TimeOfDay.Instance.playersManager.inShipPhase || RoundManager.Instance.currentLevel.levelID == 3) { Plugin.Mls.LogInfo((object)($"Meltdown Event abort. Reason: MeltdownActive: {EventsHandler.MeltdownActive}; " + $"inShipPhase: {TimeOfDay.Instance.playersManager.inShipPhase}; " + $"currentLevel: {RoundManager.Instance.currentLevel.PlanetName} (ID {RoundManager.Instance.currentLevel.levelID})")); return; } Plugin.Mls.LogInfo((object)(GetID() + " Event: Meltdown initiated")); MeltdownAPI.StartMeltdown("HullBreakerCompany"); HullManager.SendChatEventMessage("<color=red>NUCLEAR MELTDOWN! ABANDON MISSION!</color>"); } } public class SeaMineEvent : HullEvent { public SeaMineEvent() { ID = "SeaMine"; Weight = 15; Description = "Spawns additional seamines inside. Uses LandmineScale config."; MessagesList = new List<string> { "High security compound", "They rigged this place up", "Watch your head!", "Expect mines", "Lots of mines might block your path" }; shortMessagesList = new List<string> { "SEAMINES" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!levelModifier.IsTrapUnitSpawnable("Old Seamine")) { return false; } levelModifier.AddTrapUnit("Old Seamine", Plugin.LandmineScale); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class CageMineEvent : HullEvent { public CageMineEvent() { ID = "PrisonMine"; Weight = 15; Description = "Spawns additional cage/prison mines inside. Uses TurretScale config."; MessagesList = new List<string> { "High security compound", "They rigged this place up", "Don't get trapped.", "Behind bars..", "Cages used to trap wildlife are stored here" }; shortMessagesList = new List<string> { "CAGE" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!levelModifier.IsTrapUnitSpawnable("CageMine")) { return false; } levelModifier.AddTrapUnit("CageMine", Plugin.TurretScale); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class GiftMimicEvent : HullEvent { public GiftMimicEvent() { ID = "GiftMimic"; Weight = 15; Description = "Spawns additional GiftMimics inside. Uses LandmineScale config divided by 3."; MessagesList = new List<string> { "High security compound", "They rigged this place up", "Don't get fooled.", "Is this a gift.. for me?" }; shortMessagesList = new List<string> { "GIFT?" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!levelModifier.IsTrapUnitSpawnable("GiftMimic")) { return false; } levelModifier.AddTrapUnit("GiftMimic", Plugin.LandmineScale / 3); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class PropulsionMineEvent : HullEvent { public PropulsionMineEvent() { ID = "PropulsionMine"; Weight = 15; Description = "Spawns additional propulsion mines inside. Uses LandmineScale config."; MessagesList = new List<string> { "High security compound", "They rigged this place up", "Watch your step!", "Expect special mines", "Riddled with propulsion mines" }; shortMessagesList = new List<string> { "YEET" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!levelModifier.IsTrapUnitSpawnable("Yeetmine")) { return false; } levelModifier.AddTrapUnit("Yeetmine", Plugin.LandmineScale); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class EnemyBountyEvent : HullEvent { public EnemyBountyEvent() { ID = "EnemyBounty"; Weight = 30; Description = "Company rewards enemy kills with bonus credits."; MessagesList = new List<string> { "Company bounty: neutralize threats", "The company pays you for killing monsters", "Bounty assigned: kill enemies", "Company bounty: RIP AND TEAR" }; shortMessagesList = new List<string> { "KILL BOUNTY", "COMPANY BOUNTY" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { EventsHandler.BountyIsActive = true; EventsHandler.BountyFirstKill = true; if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "green"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class HackedTurretsEvent : HullEvent { public HackedTurretsEvent() { ID = "HackedTurrets"; Weight = 20; Description = "All turrets are permanently disabled."; MessagesList = new List<string> { "Security systems offline", "Abandoned after their defense systems were hacked", "The company disabled all turrets on this moon" }; shortMessagesList = new List<string> { "SECURITY OFFLINE", "TURRETS HACKED" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if ((Object)(object)HullManager.Instance == (Object)null) { Plugin.Mls.LogError((object)"HullManager.Instance is null"); return false; } if ((Object)(object)level == (Object)null) { Plugin.Mls.LogError((object)"level is null"); return false; } if (!levelModifier.IsTrapUnitSpawnable(Util.getTrapUnitByType(typeof(Turret)))) { return false; } levelModifier.AddTrapUnit(Util.getTrapUnitByType(typeof(Turret)), Plugin.TurretScale / 3 * 2); HullManager.Instance.ExecuteAfterDelay(HackTurrets, 16f); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "green"); } else { HullManager.AddChatEventMessage(this); } return true; } private void HackTurrets() { Turret[] array = Object.FindObjectsOfType<Turret>(); for (int i = 0; i < array.Length; i++) { array[i].ToggleTurretServerRpc(false); } } } public class HordeModeEvent : HullEvent { public HordeModeEvent() { ID = "HordeMode"; Weight = 5; Description = "Increases inside enemy spawn rate. Spawns enemies earlier and more frequently."; MessagesList = new List<string> { "Extreme activity levels!", "No one has ever returned from here..", "Caution! Activity level 9 9 9 9 9 9 9 9 9 9 9 9", "The company wishes the best of luck!" }; shortMessagesList = new List<string> { "HORDEMODE" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (Plugin.UseHullBreakerLevelSettings) { Plugin.Mls.LogInfo((object)"Spawn chance already increased by HullBreaker level settings"); return false; } levelModifier.AddEnemySpawnChanceThroughoutDay(512); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class HullBreakEvent : HullEvent { private static int bonus_credits; public HullBreakEvent() { ID = "HullBreak"; Weight = 10; Description = "The company sends a bonus payment. Take a break from stressfull events."; MessagesList = new List<string> { "KPI report: underperforming\nYou are granted </color><color=green>[AMOUNT]</color><color=white> credits. Use them to prove your worth to the company!", "The company appreciates your loyalty. You receive </color><color=green>[AMOUNT]</color><color=white> credits", "Bonus payment received: </color><color=green>[AMOUNT]</color><color=white> credits. Keep up the good work!" }; shortMessagesList = new List<string> { "BONUS CREDITS: </color><color=green>[AMOUNT]", "BONUS PAYMENT: </color><color=green>[AMOUNT]" }; } public override string GetMessage() { return ("<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>").Replace("[AMOUNT]", bonus_credits.ToString()); } public override string GetShortMessage() { return ("<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>").Replace("[AMOUNT]", bonus_credits.ToString()); } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { bonus_credits = Random.Range(Plugin.HullBreakEventCreditsMin, Plugin.HullBreakEventCreditsMax); HullManager.Instance.AddMoney(bonus_credits); HullManager.AddChatEventMessage(this); return true; } } public class LandMineEvent : HullEvent { public LandMineEvent() { ID = "LandMine"; Weight = 30; Description = "Spawns additional landmines inside."; MessagesList = new List<string> { "High security compound", "They rigged this place up", "Watch your step!", "Expect mines", "Lots of mines might block your path" }; shortMessagesList = new List<string> { "LANDMINES" }; } public override bool Execute(SelectableLevel level, LevelModifier levelModifier) { if (!levelModifier.IsTrapUnitSpawnable(Util.getTrapUnitByType(typeof(Landmine)))) { return false; } levelModifier.AddTrapUnit(Util.getTrapUnitByType(typeof(Landmine)), Plugin.LandmineScale); if (Plugin.ColoredEventMessages) { HullManager.AddChatEventMessageColored(this, "red"); } else { HullManager.AddChatEventMessage(this); } return true; } } public class NothingEvent : HullEvent { public NothingEvent() { ID = "Nothing"; Weight = 100; Description = "Nothing happens - This event means there is no event.\nAdjust weight to set overall chance of getting an event vs. not getting an event for each time an event is randomly selected."; MessagesList = new List<string> { "<color=white>...</color>", "<color=white>---</color>", "<color=white> </color>" }; } public override string