using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BrutalEvent.Common;
using BrutalEvent.Enums;
using BrutalEvent.Models;
using BrutalEvent.Services;
using BrutalEvent.Services.Abstract;
using BrutalEvent.Services.Abstract.Interface;
using BrutalEvent.Services.Events;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BrutalEvent")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BrutalEvent")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0a74de6b-63ee-4bb8-93f7-ed2e9b5480b9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BrutalEvent
{
[HarmonyPatch(typeof(TimeOfDay), "Awake")]
public class QuotaAjuster
{
[HarmonyPostfix]
private static void Prefix(TimeOfDay __instance)
{
Configuration.mls.LogWarning((object)"Changing quota variables in patch!");
__instance.quotaVariables.startingQuota = Plugin._config.StartingQuota.Value;
__instance.quotaVariables.startingCredits = Plugin._config.StartingCredits.Value;
__instance.quotaVariables.baseIncrease = Plugin._config.BaseIncrease.Value;
__instance.quotaVariables.deadlineDaysAmount = Plugin._config.DeadlineDaysAmount.Value;
}
}
[BepInPlugin("Liquid.BetterBrutalEvent", "BetterBrutalEvent", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
private const string MyGUID = "Liquid.BetterBrutalEvent";
private const string PluginName = "BetterBrutalEvent";
private const string VersionString = "1.0.0";
private Harmony _harmony = new Harmony("BetterBrutalEvent");
public static ConfigValues _config;
private static EventFactory _eventFactory;
private static MasterEnviroment _masterEnviroment;
public static Plugin Instance { get; set; }
private void Awake()
{
Instance = this;
_config = new LoadConfig().BindConfigSettings();
_eventFactory = new EventFactory();
_masterEnviroment = new MasterEnviroment();
Configuration.mls = Logger.CreateLogSource("BrutalEvent");
_harmony.PatchAll(typeof(Plugin));
Configuration.mls = ((BaseUnityPlugin)this).Logger;
Configuration.mls.LogInfo((object)"Loaded NEW Brutal Company and applying patches.");
}
[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
[HarmonyPrefix]
private static bool ModifyLevel(ref SelectableLevel newLevel)
{
ShowLogo();
if (!((NetworkBehaviour)RoundManager.Instance).IsHost)
{
Configuration.mls.LogWarning((object)" YOU ARE NOT A HOST! (>_<)");
Configuration.mls.LogWarning((object)" BRUTAL EVENT DIDN'T LOADING");
return false;
}
Configuration.RarityLevelValue.TryGetValue(newLevel, out var value);
Configuration.mls.LogInfo((object)"NORMALIZATION ENEMIES");
_masterEnviroment.NormalizeEnemiesRarity(newLevel);
Configuration.mls.LogInfo((object)"GENERATE EVENT");
LevelEvent levelEvent = ((newLevel.sceneName == "CompanyBuilding") ? _eventFactory.CreateEvent(EventEnum.None) : _eventFactory.GetRandomEvent());
_masterEnviroment.SetupRateLimit(newLevel, _eventFactory.EventEnum, _config);
UpdateHUDAndCredits(newLevel, value);
Configuration.mls.LogInfo((object)"SETUP SCRAP LIMIT");
_masterEnviroment.SetupLevelScrap(newLevel, _config);
Configuration.mls.LogInfo((object)"ON LOAD NEW LEVEL");
levelEvent.OnLoadNewLevel(ref newLevel, _config, value);
Configuration.mls.LogInfo((object)"RARITY BY LEVEL[newLevel]");
Configuration.RarityLevelValue[newLevel] = Mathf.Clamp(value + 15f, 0f, _config.MaxRate.Value);
HUDManager.Instance.AddTextToChatOnServer(levelEvent.GetEventName() ?? "", -1);
Configuration.mls.LogWarning((object)("EVENT : " + levelEvent.GetEventName()));
Configuration.mls.LogInfo((object)"ShowEnemyRarirty");
_masterEnviroment.ShowEnemyRarirty(newLevel, value);
return true;
}
private static void UpdateHUDAndCredits(SelectableLevel newLevel, float currentEventRate)
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
HUDManager.Instance.AddTextToChatOnServer($"<color=yellow>MOON IS AT {currentEventRate} %RATE</color>", -1);
if (currentEventRate > _config.LimitRate.Value)
{
HUDManager.Instance.AddTextToChatOnServer($"<color=red>HEAT LEVEL IS DANGEROUSLY HIGH : {currentEventRate} " + "<color=white>\nVISIT OTHER MOONS TO LOWER HEAT LEVEL.</color>", -1);
}
if (!newLevel.sceneName.Contains("CompanyBuilding"))
{
Terminal val = (Terminal)(((object)Object.FindObjectOfType<Terminal>()) ?? ((object)new Terminal()));
val.groupCredits += _config.AddCredits.Value;
val.SyncGroupCreditsServerRpc(val.groupCredits, val.numberOfItemsInDropship);
}
}
public static void ShowLogo()
{
Configuration.mls.LogInfo((object)"\r\n______ _ _ ______ _ _ _____ _ \r\n| ___ \\ | | | | | ___ \\ | | | | | ___| | | \r\n| |_/ / ___| |_| |_ ___ _ __ | |_/ /_ __ _ _| |_ __ _| | | |____ _____ _ __ | |_ \r\n| ___ \\/ _ \\ __| __/ _ \\ '__| | ___ \\ '__| | | | __/ _` | | | __\\ \\ / / _ \\ '_ \\| __|\r\n| |_/ / __/ |_| || __/ | | |_/ / | | |_| | || (_| | | | |___\\ V / __/ | | | |_ \r\n\\____/ \\___|\\__|\\__\\___|_| \\____/|_| \\__,_|\\__\\__,_|_| \\____/ \\_/ \\___|_| |_|\\__|\r\n \r\n \r\n");
}
private static void Update()
{
}
}
}
namespace BrutalEvent.Services
{
public class EventFactory : IEventFactory
{
private Random random = new Random();
public EventEnum EventEnum { get; set; } = EventEnum.None;
public LevelEvent GetRandomEvent()
{
EventEnum = (EventEnum)random.Next(Enum.GetValues(typeof(EventEnum)).Length);
return CreateEvent(EventEnum);
}
public LevelEvent GetCustomEvent(EventEnum eventEnum)
{
return CreateEvent(eventEnum);
}
public LevelEvent CreateEvent(EventEnum gameEvent)
{
if (1 == 0)
{
}
LevelEvent result = gameEvent switch
{
EventEnum.None => new NoneEvent(),
EventEnum.All => new AllEvent(),
EventEnum.Chaos => new ChaosEvent(),
EventEnum.Unfair => new UnFairEvent(),
EventEnum.Landmine => new LandMineEvent(),
EventEnum.Kleptomania => new KleptomaniaEvent(),
EventEnum.Arachnophobia => new ArachnophobiaEvent(),
EventEnum.SecuritySystem => new SecurityEvent(),
EventEnum.AllSnareFlea => new AllSnareEvent(),
EventEnum.BrackenAndCoil => new BrackerAndCoilEvent(),
EventEnum.BlobApocalypsis => new BlobApocalypsis(),
EventEnum.WhoLetTheDogsOut => new WhoLetTheDogEvent(),
EventEnum.DidYouSeeHer => new DidYouSeeHerEvent(),
EventEnum.Tremors => new TremorsEvent(),
EventEnum.GoToRent => new GoToRentEvent(),
EventEnum.Delivery => new DeliveryEvent(),
EventEnum.LetsFly => new LetsFlyEvent(),
EventEnum.ReplaceItems => new ReplaceItemsEvent(),
_ => new NoneEvent(),
};
if (1 == 0)
{
}
return result;
}
}
public class NormalDistributionService : INormalDistributionService
{
public float CalculateRarity(SelectableLevel currentLevel, float currentRate)
{
int count = RoundManager.Instance.playersManager.ClientPlayerList.Count;
float num = (float)Math.Pow(Math.PI, count);
float mu = currentRate + (float)count * num;
float sigma = currentRate / (float)count;
float num2 = NormalDistribution(mu, sigma, count);
return Mathf.Clamp(num2, 0f, 100f);
}
public float NormalDistribution(float mu, float sigma, int players)
{
float num = 0f;
List<float> list = new List<float>();
for (int i = 0; i < players; i++)
{
list.Add(Random.Range(0f, 1f));
num += list.LastOrDefault();
}
float num2 = num - list.Sum() / (float)list.Count;
return mu + sigma * num2;
}
}
}
namespace BrutalEvent.Services.Events
{
internal class AllEvent : LevelEvent
{
private EventFactory eventFactory;
public AllEvent()
{
eventFactory = new EventFactory();
}
public override string GetEventName()
{
return "<color=red>LEAVE THIS MOON! NOW!</color>";
}
public override LevelEvent CreateEvent()
{
return new AllEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
foreach (object value in Enum.GetValues(typeof(EventEnum)))
{
eventFactory.CreateEvent((EventEnum)value);
}
}
}
internal class AllSnareEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=orange>WATCH YOUR HEAD!</color>";
}
public override LevelEvent CreateEvent()
{
return new AllSnareEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<CentipedeAI>(newLevel, currentRate, 2f);
}
public override void OnLoadNewLevelCleanup(ref SelectableLevel newLevel)
{
newLevel.enemySpawnChanceThroughoutDay = oldAnimationCurve;
}
}
internal class ArachnophobiaEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>ARACHNOPHOBIA!</color>";
}
public override LevelEvent CreateEvent()
{
return new ArachnophobiaEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<SandSpiderAI>(newLevel, currentRate, 2f);
}
}
internal class BlobApocalypsis : LevelEvent
{
public override string GetEventName()
{
return "<color=orange>BLOBAPOCALYPSIS</color>";
}
public override LevelEvent CreateEvent()
{
return new BlobApocalypsis();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<BlobAI>(newLevel, currentRate, 3f);
}
}
internal class BrackerAndCoilEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>THE HUNT BEGIN!</color>";
}
public override LevelEvent CreateEvent()
{
return new BrackerAndCoilEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.ResetEnemiesRarity(newLevel);
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<FlowermanAI>(newLevel, currentRate, 2f);
_enviroment.GenerateEnemiesEvent<CrawlerAI>(newLevel, currentRate, 2f);
}
}
internal class ChaosEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>LEAVE THIS MOON! CHAOS!</color>";
}
public override LevelEvent CreateEvent()
{
return new ChaosEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<FlowermanAI>(newLevel, currentRate, 1f);
_enviroment.GenerateEnemiesEvent<BlobAI>(newLevel, currentRate, 1f);
_enviroment.GenerateEnemiesEvent<SandSpiderAI>(newLevel, currentRate, 1f);
_enviroment.GenerateEnemiesEvent<CentipedeAI>(newLevel, currentRate, 1f);
_enviroment.GenerateEnemiesEvent<CrawlerAI>(newLevel, currentRate, 1f);
_enviroment.GenerateEnemiesEvent<HoarderBugAI>(newLevel, currentRate, 2f);
_enviroment.GenerateEnemiesEvent<SpringManAI>(newLevel, currentRate, 1f);
}
}
internal class DeliveryEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=green>EZ DELIVERY!</color>";
}
public override LevelEvent CreateEvent()
{
return new DeliveryEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
Terminal val = Object.FindObjectOfType<Terminal>();
int num = Random.Range(3, 9);
for (int i = 0; i < num; i++)
{
int item = Random.Range(0, 6);
val.orderedItemsFromTerminal.Add(item);
}
}
}
internal class DidYouSeeHerEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>DID YOU SEE HER?!</color>";
}
public override LevelEvent CreateEvent()
{
return new DidYouSeeHerEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<DressGirlAI>(newLevel, currentRate, 1f);
}
}
internal class GoToRentEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=green>GO TO RENT!</color>";
}
public override LevelEvent CreateEvent()
{
return new GoToRentEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
Terminal val = Object.FindObjectOfType<Terminal>();
Item[] buyableItemsList = val.buyableItemsList;
foreach (Item val2 in buyableItemsList)
{
val2.creditsWorth += (int)((double)currentRate + (double)val2.creditsWorth * 0.5);
}
}
}
internal class KleptomaniaEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=orange>KLEPTOMANIA!</color>";
}
public override LevelEvent CreateEvent()
{
return new KleptomaniaEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
_enviroment.GenerateEnemiesEvent<HoarderBugAI>(newLevel, currentRate, 2.5f);
}
}
internal class LandMineEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>MINE MINE MINE!</color>";
}
public override LevelEvent CreateEvent()
{
return new LandMineEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
SpawnableMapObject[] spawnableMapObjects = newLevel.spawnableMapObjects;
foreach (SpawnableMapObject val in spawnableMapObjects)
{
if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<Landmine>() != (Object)null)
{
val.numberToSpawn = _curveGenerator.CreateSpawnCurve(new float[2]
{
0f,
25f * configs.Multiplier.Value
}, new float[2]
{
100f,
500f + currentRate * 3f
});
}
}
}
}
internal class LetsFlyEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=green>ITS A FLY?! NO ITS A PLANE!</color>";
}
public override LevelEvent CreateEvent()
{
return new LetsFlyEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
int item = 9;
Terminal val = Object.FindObjectOfType<Terminal>();
for (int i = 0; i < 5; i++)
{
val.orderedItemsFromTerminal.Add(item);
}
}
}
public class NoneEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=green>NONE EVENT</color>";
}
public override LevelEvent CreateEvent()
{
return new NoneEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.NormalizeEnemiesRarity(newLevel);
}
}
internal class ReplaceItemsEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=orange>DID YOU BUY FLASHLIGHT? RIGHT?</color>";
}
public override LevelEvent CreateEvent()
{
return new ReplaceItemsEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
Terminal val = Object.FindObjectOfType<Terminal>();
int num = val.buyableItemsList.Length;
Item[] array = val.buyableItemsList.ToArray();
val.buyableItemsList = null;
for (int num2 = num; num2 > 0; num2--)
{
CollectionExtensions.AddItem<Item>((IEnumerable<Item>)val.buyableItemsList, array[num2]);
}
}
}
internal class SecurityEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=orange>COMPANY SECURITY SYSTEM! GLHF :)</color>";
}
public override LevelEvent CreateEvent()
{
return new SecurityEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupEnemyChance(newLevel, currentRate, configs.Multiplier.Value);
SpawnableMapObject[] spawnableMapObjects = newLevel.spawnableMapObjects;
SpawnableMapObject[] array = spawnableMapObjects;
foreach (SpawnableMapObject val in array)
{
if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<Turret>() != (Object)null)
{
val.numberToSpawn = _curveGenerator.CreateSpawnCurve(new float[2]
{
0f,
25f + currentRate
}, new float[2]
{
100f,
100f + currentRate * 3f
});
}
}
}
}
internal class TremorsEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>DID YOU SAW THIS MOVIE?)</color>";
}
public override LevelEvent CreateEvent()
{
return new TremorsEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
SpawnableMapObject[] spawnableMapObjects = newLevel.spawnableMapObjects;
for (int i = 0; i < newLevel.outsideEnemySpawnChanceThroughDay.length; i++)
{
if (newLevel.OutsideEnemies[i].enemyType.enemyName != "SandWormAI")
{
newLevel.OutsideEnemies[i].rarity = 0;
}
}
SpawnableMapObject[] array = spawnableMapObjects;
foreach (SpawnableMapObject val in array)
{
if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<SandWormAI>() != (Object)null)
{
val.numberToSpawn = _curveGenerator.CreateSpawnCurve(new float[2] { 0f, 15f }, new float[2]
{
0.5f,
50f + currentRate * 3f
});
}
}
}
}
internal class UnFairEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=green>THIS IS UNFAIR! :(</color>";
}
public override LevelEvent CreateEvent()
{
return new UnFairEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
_enviroment.SetupLevelScrap(newLevel, configs, 2.5f);
_enviroment.ResetEnemiesRarity(newLevel);
}
}
internal class WhoLetTheDogEvent : LevelEvent
{
public override string GetEventName()
{
return "<color=red>WHO LET THE DOGS OUT, WOOF WOOF</color>";
}
public override LevelEvent CreateEvent()
{
return new WhoLetTheDogEvent();
}
public override void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate)
{
SpawnableMapObject[] spawnableMapObjects = newLevel.spawnableMapObjects;
for (int i = 0; i < newLevel.outsideEnemySpawnChanceThroughDay.length; i++)
{
if (newLevel.OutsideEnemies[i].enemyType.enemyName != "MouthDogAI")
{
newLevel.OutsideEnemies[i].rarity = 0;
}
}
SpawnableMapObject[] array = spawnableMapObjects;
foreach (SpawnableMapObject val in array)
{
if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<MouthDogAI>() != (Object)null)
{
val.numberToSpawn = _curveGenerator.CreateSpawnCurve(new float[2] { 0f, 50f }, new float[2]
{
100f,
100f + currentRate * 3f
});
}
}
}
}
}
namespace BrutalEvent.Services.Abstract
{
public class MasterEnviroment
{
private const int AdditionalMaxScrap = 45;
private const int MaxEnemyPowerIncrement = 10;
private const int MaxOutsideEnemyPowerIncrement = 5;
private const int MaxDaytimeEnemyPowerIncrement = 10;
private readonly SpawnCurveGenerator _curveGenerator;
public MasterEnviroment()
{
_curveGenerator = new SpawnCurveGenerator();
}
public void GenerateEnemiesEvent<T>(SelectableLevel currentLevel, float currentRate, float multiplier = 1f) where T : EnemyAI
{
if (multiplier < 1f || multiplier > 3f)
{
multiplier = 1f;
}
currentRate = ((currentRate == 0f) ? 1f : currentRate);
float num = new NormalDistributionService().CalculateRarity(currentLevel, currentRate);
for (int i = 0; i < currentLevel.Enemies.Count; i++)
{
SpawnableEnemyWithRarity enemy = currentLevel.Enemies[i];
if ((Object)(object)enemy.enemyType.enemyPrefab.GetComponent<T>() != (Object)null)
{
int rarity = ((IEnumerable<SpawnableEnemyWithRarity>)Configuration.OriginalEnemiesRarities[currentLevel]).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => x.enemyType.enemyName.Equals(enemy.enemyType.enemyName))).rarity;
enemy.rarity = (int)(num * multiplier) + rarity;
EnemyType enemyType = enemy.enemyType;
enemyType.MaxCount += (int)(num * multiplier);
enemy.enemyType.probabilityCurve = _curveGenerator.CreateSpawnCurve(new float[2]
{
0f,
40f + multiplier * currentRate
}, new float[2]
{
100f,
100f + multiplier * currentRate + (float)rarity
});
}
}
}
public void NormalizeEnemiesRarity(SelectableLevel currentLevel, List<string> typesEnemyCollection = null)
{
if (!Configuration.OriginalEnemiesRarities.ContainsKey(currentLevel))
{
Configuration.mls.LogInfo((object)"START METHOD NORMALIZATION ENEMIES");
List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>(((IEnumerable<SpawnableEnemyWithRarity>)currentLevel.Enemies).Select((Func<SpawnableEnemyWithRarity, SpawnableEnemyWithRarity>)((SpawnableEnemyWithRarity e) => new SpawnableEnemyWithRarity
{
enemyType = e.enemyType,
rarity = e.rarity
})));
Configuration.mls.LogInfo((object)$"ORIGINAL ENEMIES : {list.Count}");
Configuration.OriginalEnemiesRarities[currentLevel] = list;
}
Configuration.mls.LogInfo((object)"MID METHOD NORMALIZATION ENEMIES");
List<SpawnableEnemyWithRarity> source = Configuration.OriginalEnemiesRarities[currentLevel];
foreach (SpawnableEnemyWithRarity enemy in currentLevel.Enemies)
{
if (typesEnemyCollection == null || typesEnemyCollection.Contains(enemy.enemyType.enemyName))
{
SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)source).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => x.enemyType.enemyName == enemy.enemyType.enemyName));
if (val != null)
{
enemy.rarity = val.rarity;
}
}
}
}
public void ResetEnemiesRarity(SelectableLevel currentLevel, List<string> typesEnemyCollection = null)
{
HashSet<string> hashSet = ((typesEnemyCollection != null) ? new HashSet<string>(typesEnemyCollection) : null);
foreach (SpawnableEnemyWithRarity enemy in currentLevel.Enemies)
{
if (hashSet == null || hashSet.Contains(enemy.enemyType.enemyName))
{
enemy.rarity = 0;
}
}
}
public void SetupRateLimit(SelectableLevel currentLevel, EventEnum eventEnum, ConfigValues config)
{
if (!Configuration.RarityLevelValue.ContainsKey(currentLevel))
{
Configuration.RarityLevelValue.Add(currentLevel, 0f);
}
if (Configuration.Enemies == null)
{
Configuration.Enemies = new Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>>();
}
if (!Configuration.Enemies.ContainsKey(currentLevel))
{
Configuration.mls.LogInfo((object)("Initializing enemies for level " + (((currentLevel != null) ? ((Object)currentLevel).name : null) ?? "NULL")));
List<SpawnableEnemyWithRarity> value = currentLevel?.Enemies?.Select((Func<SpawnableEnemyWithRarity, SpawnableEnemyWithRarity>)((SpawnableEnemyWithRarity enemy) => new SpawnableEnemyWithRarity
{
enemyType = enemy.enemyType,
rarity = enemy.rarity
})).ToList() ?? new List<SpawnableEnemyWithRarity>();
Configuration.Enemies[currentLevel] = value;
}
Configuration.Enemies[currentLevel] = ((IEnumerable<SpawnableEnemyWithRarity>)Configuration.Enemies[currentLevel]).Select((Func<SpawnableEnemyWithRarity, SpawnableEnemyWithRarity>)((SpawnableEnemyWithRarity enemy) => new SpawnableEnemyWithRarity
{
enemyType = enemy.enemyType,
rarity = enemy.rarity
})).ToList();
foreach (SelectableLevel item in Configuration.RarityLevelValue.Keys.ToList())
{
if (Configuration.RarityLevelValue.TryGetValue(item, out var value2))
{
float value3 = Mathf.Clamp(value2, config.RarityMin.Value, config.RarityMax.Value);
if (eventEnum == EventEnum.All)
{
Configuration.RarityLevelValue[item] = 0f;
}
else
{
Configuration.RarityLevelValue[item] = value3;
}
}
}
}
public SelectableLevel SetupLevelScrap(SelectableLevel newLevel, ConfigValues config, float multiplier = 1f)
{
if (!Configuration.levelsModified.Contains(newLevel))
{
Configuration.levelsModified.Add(newLevel);
ModifyDaySettings(newLevel, config, multiplier);
}
return newLevel;
}
public void ModifyDaySettings(SelectableLevel level, ConfigValues config, float multiplier = 1f)
{
level.maxScrap += (int)(45f * multiplier);
level.maxTotalScrapValue += (int)(Random.Range(config.MinScrap.Value, config.MaxScrap.Value) * multiplier);
level.maxEnemyPowerCount += 10;
level.maxOutsideEnemyPowerCount += 5;
level.maxDaytimeEnemyPowerCount += 10;
}
public void ShowEnemyRarirty(SelectableLevel newLevel, float currentEventRate)
{
Configuration.mls.LogWarning((object)("|" + new string('-', 4) + "All ENEMIES RARITY" + new string('-', 4) + "|"));
Configuration.mls.LogWarning((object)$"| Current Rate: {currentEventRate}% |");
foreach (SpawnableEnemyWithRarity enemy in newLevel.Enemies)
{
Configuration.mls.LogInfo((object)$"| {enemy.enemyType.enemyName,17} : {enemy.rarity,-3}% |");
}
Configuration.mls.LogWarning((object)("|" + new string('-', 26) + "|"));
}
public SelectableLevel SetupEnemyChance(SelectableLevel newLevel, float currentEventRate, float multiplier = 1f)
{
if (multiplier < 1f || multiplier > 3f)
{
multiplier = 1f;
}
newLevel.daytimeEnemySpawnChanceThroughDay = _curveGenerator.CreateSpawnCurve(new float[2]
{
0f,
1f * multiplier
}, new float[2]
{
5f,
25f + currentEventRate * multiplier
});
newLevel.enemySpawnChanceThroughoutDay = _curveGenerator.CreateSpawnCurve(new float[2]
{
0f,
1f * multiplier
}, new float[2]
{
0.4f,
33f + currentEventRate * multiplier
});
newLevel.outsideEnemySpawnChanceThroughDay = _curveGenerator.CreateSpawnCurve(new float[2] { 0f, -10f }, new float[2]
{
0.8f,
10f + currentEventRate
});
return newLevel;
}
}
public class SpawnCurveGenerator
{
public AnimationCurve CreateSpawnCurve(float[] times, float[] values)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
if (times.Length != values.Length)
{
throw new ArgumentException("Times and values arrays must have the same length.");
}
Keyframe[] array = (Keyframe[])(object)new Keyframe[times.Length];
for (int i = 0; i < times.Length; i++)
{
array[i] = new Keyframe(times[i], values[i]);
}
return new AnimationCurve(array);
}
}
public abstract class LevelEvent
{
protected MasterEnviroment _enviroment;
protected AnimationCurve oldAnimationCurve;
protected readonly SpawnCurveGenerator _curveGenerator;
public LevelEvent()
{
_enviroment = new MasterEnviroment();
_curveGenerator = new SpawnCurveGenerator();
}
public abstract string GetEventName();
public abstract LevelEvent CreateEvent();
public abstract void OnLoadNewLevel(ref SelectableLevel newLevel, ConfigValues configs, float currentRate);
public virtual void OnLoadNewLevelCleanup(ref SelectableLevel newLevel)
{
}
public virtual bool IsValid(ref SelectableLevel newLevel)
{
return true;
}
}
}
namespace BrutalEvent.Services.Abstract.Interface
{
public interface IEventFactory
{
LevelEvent CreateEvent(EventEnum eventEnum);
}
public interface INormalDistributionService
{
float CalculateRarity(SelectableLevel currentLevel, float currentRate);
float NormalDistribution(float mu, float sigma, int players);
}
}
namespace BrutalEvent.Models
{
public class ConfigValues
{
public ConfigEntry<float> MinScrap { get; set; }
public ConfigEntry<float> MaxScrap { get; set; }
public ConfigEntry<float> LimitRate { get; set; }
public ConfigEntry<float> MaxRate { get; set; }
public ConfigEntry<float> RarityMin { get; set; }
public ConfigEntry<float> RarityMax { get; set; }
public ConfigEntry<int> AddCredits { get; set; }
public ConfigEntry<int> StartingQuota { get; set; }
public ConfigEntry<int> StartingCredits { get; set; }
public ConfigEntry<float> BaseIncrease { get; set; }
public ConfigEntry<float> Multiplier { get; set; }
public ConfigEntry<int> DeadlineDaysAmount { get; set; }
}
public static class Configuration
{
public static bool loaded { get; set; }
public static List<SelectableLevel> levelsModified { get; set; } = new List<SelectableLevel>();
public static Dictionary<SelectableLevel, float> RarityLevelValue { get; set; } = new Dictionary<SelectableLevel, float>();
public static Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>> Enemies { get; set; } = new Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>>();
public static Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>> OriginalEnemiesRarities { get; set; } = new Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>>();
public static ManualLogSource mls { get; set; }
}
}
namespace BrutalEvent.Common
{
public class LoadConfig
{
private string _sectionName = "BrutalEventSettings";
public ConfigValues BindConfigSettings()
{
ConfigValues configValues = new ConfigValues();
configValues.MinScrap = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "MinScrap", 250f, "MinScrap");
configValues.MaxScrap = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "MaxScrap", 650f, "MaxScrap");
configValues.LimitRate = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "LimitRate", 50f, "LimitRate");
configValues.MaxRate = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "MaxRate", 100f, "MaxRate");
configValues.RarityMin = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "RarityMin", 10f, "RarityMin");
configValues.RarityMax = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName, "RarityMax", 100f, "RarityMax");
configValues.AddCredits = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<int>(_sectionName, "AddCredits", 45, "Additional credits on each mission");
configValues.StartingQuota = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<int>(_sectionName ?? "", "StartingQuota", 299, "StartingQuota Value");
configValues.StartingCredits = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<int>(_sectionName ?? "", "StartingCredits", 150, "StartingCredits Value");
configValues.BaseIncrease = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName ?? "", "BaseIncrease", 51f, "Increase Quota value each round");
configValues.Multiplier = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<float>(_sectionName ?? "", "RandomizerMultiplier", 1f, "Multiplier spawnable chance Value [1.0 .. 3.0]");
configValues.DeadlineDaysAmount = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<int>(_sectionName ?? "", "DeadlineDaysAmount", 5, "Deadline Days Amount");
return configValues;
}
}
}
namespace BrutalEvent.Enums
{
public enum EventEnum
{
None,
All,
Chaos,
Unfair,
Landmine,
Kleptomania,
Arachnophobia,
SecuritySystem,
AllSnareFlea,
BrackenAndCoil,
BlobApocalypsis,
WhoLetTheDogsOut,
DidYouSeeHer,
Tremors,
GoToRent,
Delivery,
LetsFly,
ReplaceItems
}
}