using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using LethalNetworkAPI.Utils;
using TMPro;
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("LethalCompanyEconomyMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalCompanyEconomyMod")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("11dfcace-cb6f-4ed9-b69c-c5bd5a6e6722")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LethalCompanyEconomyMod;
[BepInPlugin("com.raalplay.lethalcompanyeconomy", "EconomyMod", "1.0.7")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class EconomyMod : BaseUnityPlugin
{
private static class EconomyModPatches
{
public static class ModConfig
{
public static ConfigEntry<float> EventProbability { get; private set; }
public static ConfigEntry<float> NextExecutionMin { get; private set; }
public static ConfigEntry<float> NextExecutionMax { get; private set; }
public static void LoadConfig(ConfigFile config)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
EventProbability = config.Bind<float>("General", "Event Probability", 1f, new ConfigDescription("Probability (0.0 to 1.0) of the event occurring.", (AcceptableValueBase)null, Array.Empty<object>()));
NextExecutionMin = config.Bind<float>("Timing", "Next Execution Minimum", 70f, new ConfigDescription("Minimum time (in seconds) before the next execution.", (AcceptableValueBase)null, Array.Empty<object>()));
NextExecutionMax = config.Bind<float>("Timing", "Next Execution Maximum", 300f, new ConfigDescription("Maximum time (in seconds) before the next execution.", (AcceptableValueBase)null, Array.Empty<object>()));
}
public static float GetNextExecutionTime()
{
return Random.Range(NextExecutionMin.Value, NextExecutionMax.Value);
}
}
[HarmonyPatch(typeof(StartOfRound), "StartGame")]
public static class StartOfRound_StartGame_Patch
{
[CompilerGenerated]
private sealed class <<Postfix>g__Event|0_0>d : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <<Postfix>g__Event|0_0>d(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
hasInitialized = true;
eventProbability = ModConfig.EventProbability.Value;
<>2__current = (object)new WaitForSeconds(nextExecution);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (ProbabilityHelper.Attempt(eventProbability))
{
quotaMultiplier = 1f;
daysToDeadlineExtension = 0;
GenerateEconomicEvent();
LastExecutionTime = DateTime.UtcNow;
}
nextExecution = Generator.RandomNumber(ModConfig.NextExecutionMin.Value, ModConfig.NextExecutionMax.Value);
hasInitialized = false;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPostfix]
private static void Postfix(ref StartOfRound __instance)
{
if (LNetworkUtils.IsHostOrServer)
{
RefreshPlayerList(__instance);
if (!hasInitialized)
{
((MonoBehaviour)__instance).StartCoroutine(Event());
}
}
[IteratorStateMachine(typeof(<<Postfix>g__Event|0_0>d))]
static IEnumerator Event()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <<Postfix>g__Event|0_0>d(0);
}
}
}
public class EconomicEvent
{
public string message;
public float multiplier;
public int daysExtension;
public bool isRare;
public bool isGood;
public int quotaChange;
public Func<bool> condition;
public EconomicEvent(string message, float multiplier, int daysExtension, bool isGood, int quotaChange, Func<bool> condition = null, bool isRare = false)
{
this.message = message;
this.multiplier = multiplier;
this.daysExtension = daysExtension;
this.isRare = isRare;
this.isGood = isGood;
this.quotaChange = quotaChange;
this.condition = condition;
}
public bool IsConditionMet()
{
if (condition == null)
{
return true;
}
return condition();
}
}
[CompilerGenerated]
private sealed class <PlayEvent>d__12 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public EconomicEvent economicEvent;
private TimeOfDay <timeOfDayInstance>5__1;
private int <newProfitQuota>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayEvent>d__12(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<timeOfDayInstance>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
HUDManager.Instance.DisplayTip(economicEvent.isGood ? "¡Enhorabuena!" : "¡Malas noticias!", hudMessage.RemoveDiacritics(), !economicEvent.isGood, false, "LC_Tip1");
ShowMessageInChat((economicEvent.isGood ? "¡Enhorabuena!" : "¡Malas noticias!") + "\n" + hudMessage);
<timeOfDayInstance>5__1 = TimeOfDay.Instance;
<newProfitQuota>5__2 = Mathf.RoundToInt((float)<timeOfDayInstance>5__1.profitQuota * quotaMultiplier);
<timeOfDayInstance>5__1.profitQuota = <newProfitQuota>5__2;
TimeOfDay obj = <timeOfDayInstance>5__1;
obj.timeUntilDeadline += (float)(int)(<timeOfDayInstance>5__1.totalTime * (float)daysToDeadlineExtension);
if (economicEvent.quotaChange < 0)
{
TimeOfDay obj2 = <timeOfDayInstance>5__1;
obj2.quotaFulfilled += ((<timeOfDayInstance>5__1.quotaFulfilled >= Mathf.Abs(economicEvent.quotaChange)) ? economicEvent.quotaChange : (<timeOfDayInstance>5__1.quotaFulfilled * -1));
}
else
{
TimeOfDay obj3 = <timeOfDayInstance>5__1;
obj3.quotaFulfilled += economicEvent.quotaChange;
}
if (economicEvent.multiplier != 1f)
{
<>2__current = (object)new WaitForSeconds(10f);
<>1__state = 1;
return true;
}
<timeOfDayInstance>5__1.UpdateProfitQuotaCurrentTime();
break;
}
case 1:
<>1__state = -1;
HUDManager.Instance.DisplayNewDeadline(0);
break;
}
Logger.LogInfo((object)"Reseteando cuota y días al inicio de la partida");
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <_ShowHUDMessage>d__15 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <_ShowHUDMessage>d__15(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(10f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
HUDManager.Instance.DisplayStatusEffect("Test");
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static float quotaMultiplier = 1f;
public static int daysToDeadlineExtension = 0;
private static string hudMessage;
private static List<string> eventLog = new List<string>();
private static bool hasInitialized = false;
private static PlayerControllerB[] playersList;
private static DateTime LastExecutionTime = new DateTime(0L);
private static float nextExecution = Generator.RandomNumber(ModConfig.NextExecutionMin.Value, ModConfig.NextExecutionMax.Value);
private static float eventProbability = ModConfig.EventProbability.Value;
public static void EconomicEventReceiveFromServer(EconomicEvent arg1)
{
((MonoBehaviour)StartOfRound.Instance).StartCoroutine(PlayEvent(arg1));
}
[IteratorStateMachine(typeof(<PlayEvent>d__12))]
private static IEnumerator PlayEvent(EconomicEvent economicEvent)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayEvent>d__12(0)
{
economicEvent = economicEvent
};
}
public static void ShowMessageInChat(string message)
{
HUDManager.Instance.AddTextToChatOnServer(message, -1);
}
private static void DisplayGlobalNotification(string displayText)
{
HUDManager instance = HUDManager.Instance;
instance.globalNotificationAnimator.SetTrigger("TriggerNotif");
((TMP_Text)instance.globalNotificationText).text = displayText;
instance.UIAudio.PlayOneShot(instance.globalNotificationSFX);
}
[IteratorStateMachine(typeof(<_ShowHUDMessage>d__15))]
private static IEnumerator _ShowHUDMessage()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <_ShowHUDMessage>d__15(0);
}
public static string getRandomPlayerName()
{
return playersList[Random.Range(0, playersList.Length - 1)].playerUsername;
}
public static PlayerControllerB getRandomPlayer()
{
return playersList[Random.Range(0, playersList.Length - 1)];
}
private static void RefreshPlayerList(StartOfRound __instance)
{
playersList = __instance.ClientPlayerList.Select((KeyValuePair<ulong, int> x) => __instance.allPlayerScripts[x.Value]).ToArray();
Logger.LogInfo((object)("Random player: " + getRandomPlayer().playerUsername));
}
public static void GenerateEconomicEvent()
{
float num = quotaMultiplier;
int num2 = daysToDeadlineExtension;
quotaMultiplier = 1f;
daysToDeadlineExtension = 0;
TimeOfDay timeOfDayInstance = TimeOfDay.Instance;
int daysUntilDeadline = (int)(timeOfDayInstance.timeUntilDeadline / timeOfDayInstance.totalTime);
GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>();
GrabbableObject[] objectsInShipRoom = source.Where((GrabbableObject obj) => obj.isInShipRoom).ToArray();
PlayerControllerB randomPlayer = getRandomPlayer();
PlayerControllerB randomLowHealthPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.health <= 20));
PlayerControllerB randomTypingChatPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.isTypingChat));
PlayerControllerB randomDrowningDeadPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (int)x.causeOfDeath == 9));
PlayerControllerB randomInTerminalPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.inTerminalMenu));
PlayerControllerB randomDeadPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.isPlayerDead));
PlayerControllerB randomSprintingPlayer = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.isSprinting));
PlayerControllerB val = ((IEnumerable<PlayerControllerB>)playersList).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.isPlayerAlone));
List<EconomicEvent> list = new List<EconomicEvent>
{
new EconomicEvent("La demanda de chatarra ha aumentado. ¡Prepárense para el multón!", 1.5f, 0, isGood: false, 0),
new EconomicEvent("La demanda de chatarra ha disminuido. Hoy los jefes se despertaron con buena pata.", 0.7f, 0, isGood: true, Generator.RandomNumber(10, 15), null, isRare: true),
new EconomicEvent("Tus jefes están de buen humor. ¡Milagro! Disfruten este breve momento de paz y oren.", 0.9f, 2, isGood: true, 3),
new EconomicEvent(getRandomPlayerName() + " ha realizado un trabajo a puerta cerrada con el jefe de la compañía.", 1f, 0, isGood: true, Generator.RandomNumber(5, 15)),
new EconomicEvent("Tus jefes están de mal humor. ¡Corran por sus vidas! Y trabajen el doble, que viva la explotación y el capitalismo.", 1.2f, -1, isGood: false, 0, () => daysUntilDeadline >= 3),
new EconomicEvent("Un comprador especial con gustos peculiares apareció. ¡A vender!", Generator.RandomNumber(1.1f, 1.5f), 0, isGood: true, Generator.RandomNumber(35, 80)),
new EconomicEvent("Problemas técnicos. La máquina de chatarra está en huelga... contra nosotros.", 1.1f, 0, isGood: false, 0),
new EconomicEvent("Inflación. Hasta el aire que respiramos es más caro. ¡Y la cuota también!", 1.3f, 0, isGood: false, 0),
new EconomicEvent("Deflación. Los precios bajan, pero no se confíen.", 0.8f, 0, isGood: true, 0),
new EconomicEvent("Fusión de empresas. ¡Alguien vendió el alma al diablo!.", 2f, 0, isGood: false, 0, () => daysUntilDeadline >= 3, isRare: true),
new EconomicEvent("Huelga de trabajadores. ¡¿Huelga, acaso somos los unicos que trabajamos en esta empresa?!.", 1f, -1, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Bono de productividad. Un aplauso para el que no se durmió en el trabajo. Tomen algo extra.", 1f, 0, isGood: true, Generator.RandomNumber(7, 15), null, isRare: true),
new EconomicEvent("Inspección sorpresa. ¡¿Quién dejó esto así?! Multa por vivir en un basurero.", 1f, 0, isGood: false, Generator.RandomNumber(-15, -5), () => objectsInShipRoom.Length > 12 && timeOfDayInstance.quotaFulfilled >= 15),
new EconomicEvent("Mercado saturado. Los precios de la chatarra cayeron... ¡¿Nos vamos a declarar en bancarrota?!", 1.5f, 0, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Nuevo competidor. Esa nueva compañía de chatarra nos está quitando el negocio. ¡¿Qué vamos a hacer?!", 1f, -1, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Subvención gubernamental. ¡El tío Sam nos echa una mano!.", 0.9f, 2, isGood: true, Generator.RandomNumber(7, 15), () => daysUntilDeadline <= 2 && timeOfDayInstance.quotaFulfilled < timeOfDayInstance.profitQuota.PercentageOf(50m)),
new EconomicEvent("Avería de maquinaria. La máquina dijo 'no' hoy, pero te damos más tiempo para que te recuperes del susto.", 1f, 1, isGood: false, 0),
new EconomicEvent("Demanda sin precedentes. ¡La chatarra es el nuevo oro!", 1.55f, 0, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Cambios regulatorios. Parece que alguien no leyó la letra pequeña... ¡Prepárense para las consecuencias!", 1.25f, 0, isGood: false, -45, () => daysUntilDeadline >= 2, isRare: true),
new EconomicEvent("Desastre natural. La Madre Naturaleza nos odia. Cuota más alta y menos tiempo. ¡Buena suerte con eso!", 1.45f, -1, isGood: false, -80, () => daysUntilDeadline >= 3, isRare: true),
new EconomicEvent("Inversión extranjera. ¡Al parecer alguien decidió lavar dinero con nuestra compañía!.", 0.75f, 0, isGood: true, 50, () => daysUntilDeadline <= 3 && timeOfDayInstance.quotaFulfilled < timeOfDayInstance.profitQuota.PercentageOf(70m), isRare: true),
new EconomicEvent("Reorganización interna. Tu cuota se reduce temporalmente. ¡No se acostumbren!", 0.85f, 0, isGood: true, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Robo de material. ¡¿Dónde están nuestros ahorros?!... Y tenemos menos tiempo, genial.", 1f, -1, isGood: false, -90, () => daysUntilDeadline >= 2, isRare: true),
new EconomicEvent("Premio a la eficiencia. Sigan así y tal vez les demos una palmadita en la espalda...", 1f, 0, isGood: true, Generator.RandomNumber(2, 15), () => daysUntilDeadline >= 2, isRare: true),
new EconomicEvent("Auditoría fiscal. Alguien olvidó declarar sus ganancias. ¡A pagar el pato!", 1f, 0, isGood: false, -65, () => daysUntilDeadline >= 2 && timeOfDayInstance.quotaFulfilled >= 65, isRare: true),
new EconomicEvent("Uno de los pasajeros ha evadido impuestos y el gobierno no pudo saber cuál de todos era por lo que ha decidido multar a toda la nave.", 1f, 0, isGood: false, -75, () => daysUntilDeadline >= 2 && timeOfDayInstance.quotaFulfilled >= 75, isRare: true),
new EconomicEvent(getRandomPlayerName() + " no se ha bajado correctamente de la nave y ha roto la escalera, habrá que pagar reparación.", 1f, 0, isGood: false, -75, () => daysUntilDeadline >= 2 && timeOfDayInstance.quotaFulfilled >= 75, isRare: true),
new EconomicEvent("¡La competencia ha lanzado una campaña de desprestigio! Tu reputación (y tus ganancias) se ven afectadas.", 1.4f, 0, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("Se rumorea que un coleccionista excéntrico está buscando chatarra rara. ¡Precios altos si encuentras algo interesante!", 0.75f, 0, isGood: true, 0, () => daysUntilDeadline >= 2, isRare: true),
new EconomicEvent("Un error contable inesperado a tu favor...", 1f, 0, isGood: true, Generator.RandomNumber(2, 45), () => daysUntilDeadline <= 3, isRare: true),
new EconomicEvent("La galaxia entera está celebrando un festival de reciclaje. ¡La demanda ha aumentado!", 1.2f, 1, isGood: false, 0, () => daysUntilDeadline >= 1),
new EconomicEvent("Has encontrado unas facturas que no habias entregado en un rincón remoto de la nave. ¡Es tu día de suerte!", 0.85f, 0, isGood: true, 0, () => daysUntilDeadline <= 2, isRare: true)
};
list.AddRange(new EconomicEvent[7]
{
new EconomicEvent("Mientras todos estaban distraídos " + randomPlayer?.playerUsername + " robo unos tornillos a una familia de ratoncitos que vivían en la fabrica.", 1f, 0, isGood: true, Generator.RandomNumber(5, 15), () => randomPlayer.isInsideFactory),
new EconomicEvent($"{randomLowHealthPlayer?.playerUsername} fue diagnosticado con cancer tipo {Random.Range(3, 5)}. Hemos pagado el seguro.", 1f, 0, isGood: true, Generator.RandomNumber(-25, -8), delegate
{
int result3;
if ((Object)(object)randomLowHealthPlayer != (Object)null)
{
PlayerControllerB obj4 = randomLowHealthPlayer;
result3 = ((obj4 != null && obj4.health < 20) ? 1 : 0);
}
else
{
result3 = 0;
}
return (byte)result3 != 0;
}),
new EconomicEvent(randomLowHealthPlayer?.playerUsername + " ha perdido mucha sangre. Hemos tenido que pagar una transfusión.", 1f, 0, isGood: true, Generator.RandomNumber(-25, -8), delegate
{
int result2;
if ((Object)(object)randomLowHealthPlayer != (Object)null)
{
PlayerControllerB obj3 = randomLowHealthPlayer;
result2 = ((obj3 != null && obj3.health < 20) ? 1 : 0);
}
else
{
result2 = 0;
}
return (byte)result2 != 0;
}),
new EconomicEvent(randomLowHealthPlayer?.playerUsername + " es el mejor guerrero de dios. La compañía le da un bono por su gran labor.", 1f, 0, isGood: true, Generator.RandomNumber(5, 15), () => (Object)(object)randomLowHealthPlayer != (Object)null),
new EconomicEvent("Le hemos cobrado impuestos " + randomTypingChatPlayer?.playerUsername + " por utilizar el chat. Hoy en día ya nada es gratis.", 1f, 0, isGood: true, Generator.RandomNumber(-15, -5), () => (Object)(object)randomTypingChatPlayer != (Object)null),
new EconomicEvent("Ha llegado a los oídos del jefe que " + randomDrowningDeadPlayer?.playerUsername + " se le ocurrió vivir como un pececito y no le salió bien. Os han multado.", 1f, 0, isGood: true, Generator.RandomNumber(-25, -10), () => (Object)(object)randomDrowningDeadPlayer != (Object)null),
new EconomicEvent(randomInTerminalPlayer?.playerUsername + " ha usado mas electricidad en la Terminal que en su casa jugando este juego. ¡Hora de pagar la luz!", 1f, 0, isGood: true, Generator.RandomNumber(-25, -10), () => (Object)(object)randomInTerminalPlayer != (Object)null)
});
list.AddRange(new EconomicEvent[12]
{
new EconomicEvent("Advertencia de Saneamiento. ¡La nave está asquerosamente sucia! Multa inmediata por riesgo biológico.", 1.1f, 0, isGood: false, Generator.RandomNumber(-20, -10), () => objectsInShipRoom.Length > 20),
new EconomicEvent("¡Inspección sorpresa de la Junta de Limpieza Intergaláctica! Has pasado raspando. Pequeño bono por esfuerzo.", 0.9f, 0, isGood: true, Generator.RandomNumber(5, 10), () => objectsInShipRoom.Length <= 5),
new EconomicEvent("La unidad de control de plagas detectó una infestación. Han fumigado y nos dan más tiempo para que te recuperes del olor.", 1f, 1, isGood: false, Generator.RandomNumber(-10, -5), null, isRare: true),
new EconomicEvent("Venta de 'Chatarra Histórica'. Un coleccionista compró un objeto de la nave que consideró 'antiguo y auténtico'.", 1f, 0, isGood: true, Generator.RandomNumber(40, 60), () => objectsInShipRoom.Length >= 1, isRare: true),
new EconomicEvent("Fallo en el sistema de soporte vital por acumulación de polvo. ¡Paga la reparación!", 1f, 0, isGood: false, Generator.RandomNumber(-35, -20), () => daysUntilDeadline >= 2 && objectsInShipRoom.Length > 15),
new EconomicEvent("Condiciones climáticas ideales en el planeta. Los equipos de recolección están más motivados. ¡Multiplicador extra!", 0.85f, 0, isGood: true, 0),
new EconomicEvent("Tormenta de radiación solar. Los equipos se dañan y los envíos se retrasan. La cuota aumenta por la urgencia.", 1.4f, -1, isGood: false, 0, () => daysUntilDeadline >= 2),
new EconomicEvent("El gobierno local aprobó una exención fiscal para recolectores de chatarra en esta órbita. ¡Aprovéchala!", 0.75f, 0, isGood: true, 0, null, isRare: true),
new EconomicEvent("Has excedido el 75% de la cuota con dos días de sobra. ¡Bono por gestión eficiente!", 0.9f, 0, isGood: true, Generator.RandomNumber(30, 50), () => daysUntilDeadline >= 2 && timeOfDayInstance.quotaFulfilled >= timeOfDayInstance.profitQuota.PercentageOf(75m)),
new EconomicEvent("¡Acumulación de stock! Tienes demasiada chatarra sin vender. Se aplica una penalización por almacenamiento.", 1.3f, 0, isGood: false, 0, () => objectsInShipRoom.Length > 30 && daysUntilDeadline <= 1),
new EconomicEvent("Pánico en el mercado: tu cuota es demasiado baja. Los inversores exigen un esfuerzo extra inmediato.", 1.5f, -1, isGood: false, 0, () => daysUntilDeadline >= 2 && timeOfDayInstance.quotaFulfilled < timeOfDayInstance.profitQuota.PercentageOf(50m)),
new EconomicEvent("Oferta de 'Último Minuto': Un comprador privado ofrece un precio fijo, pero solo por una pequeña cantidad de chatarra.", 1f, 0, isGood: true, Generator.RandomNumber(5, 15), () => daysUntilDeadline <= 1)
});
list.AddRange(new EconomicEvent[5]
{
new EconomicEvent("¡" + randomDeadPlayer?.playerUsername + " ha dejado un testamento! Se acordo de todos sus compañeros y le dejo un tornillo a cada uno.", 1f, 0, isGood: true, Generator.RandomNumber(5, 10), () => (Object)(object)randomDeadPlayer != (Object)null && timeOfDayInstance.quotaFulfilled < timeOfDayInstance.profitQuota.PercentageOf(50m)),
new EconomicEvent(randomLowHealthPlayer?.playerUsername + " se lesionó intentando hacer una maniobra de parkour y tuvimos que pagar el seguro.", 1f, 0, isGood: false, Generator.RandomNumber(-30, -15), delegate
{
int result;
if ((Object)(object)randomLowHealthPlayer != (Object)null)
{
PlayerControllerB obj2 = randomLowHealthPlayer;
result = ((obj2 != null && obj2.health <= 50) ? 1 : 0);
}
else
{
result = 0;
}
return (byte)result != 0;
}),
new EconomicEvent("El jefe vio a " + randomSprintingPlayer?.playerUsername + " correr. Creyó que era entusiasmo laboral. ¡Bono por 'iniciativa'!", 1f, 0, isGood: true, Generator.RandomNumber(7, 18), () => (Object)(object)randomSprintingPlayer != (Object)null),
new EconomicEvent("¡" + randomPlayer?.playerUsername + " ha sido atrapado in fraganti usando el terminal para pagar la suscripción de una pagina de alienígenas sexys en tanga! Gracias a dios no era tan cara.", 1f, 0, isGood: false, Generator.RandomNumber(-12, -7), () => (Object)(object)randomInTerminalPlayer != (Object)null),
new EconomicEvent("Por su 'actitud cuestionable' en el último planeta, " + randomPlayer?.playerUsername + " ha sido penalizado por dañar la imagen corporativa.", 1f, 0, isGood: false, Generator.RandomNumber(-30, -15), () => (Object)(object)randomPlayer != (Object)null)
});
bool selectRareEvent = Random.value < 0.1f;
List<EconomicEvent> list2 = list.Where((EconomicEvent e) => e.IsConditionMet() && e.isRare == selectRareEvent).ToList();
if (list2.Count == 0)
{
Logger.LogInfo((object)$"No se encontraron eventos que coincidieran con las condiciones. isRare: {selectRareEvent}");
return;
}
EconomicEvent economicEvent = list2[Random.Range(0, list2.Count)];
quotaMultiplier = Mathf.Clamp(quotaMultiplier * economicEvent.multiplier, 0.1f, 5f);
daysToDeadlineExtension += economicEvent.daysExtension;
daysToDeadlineExtension = Mathf.Clamp(daysToDeadlineExtension, -7, 7);
string text = economicEvent.message;
if (economicEvent.multiplier != 1f)
{
float num3 = (quotaMultiplier / num - 1f) * 100f;
string text2 = num3.ToString("F0", CultureInfo.InvariantCulture);
text = text + " Cuota " + ((num3 > 0f) ? "+" : "") + text2 + "%.";
}
if (economicEvent.daysExtension != 0)
{
text += string.Format(" Plazo: {0}{1} {2}", (economicEvent.daysExtension > 0) ? "+" : "", economicEvent.daysExtension, (Mathf.Abs(economicEvent.daysExtension) != 1) ? "días." : "día.");
}
if (economicEvent.quotaChange != 0)
{
text += string.Format(" Se {0} ${1} a tu cuenta.", (economicEvent.quotaChange > 0) ? "añadieron" : "restaron", economicEvent.quotaChange);
}
hudMessage = text;
eventLog.Add($"Evento: {economicEvent.message} - Multiplicador: {quotaMultiplier}, Días extra: {daysToDeadlineExtension}, Cambio de Quota: {economicEvent.quotaChange}");
Logger.LogInfo((object)("Evento: " + text));
EconomyMod.economicEvent.SendClients(economicEvent);
}
}
public const string modGUID = "com.raalplay.lethalcompanyeconomy";
public const string modName = "EconomyMod";
public const string modVersion = "1.0.7";
private readonly Harmony harmony = new Harmony("com.raalplay.lethalcompanyeconomy");
internal static ManualLogSource Logger;
private static LNetworkMessage<EconomyModPatches.EconomicEvent> economicEvent;
internal static EconomyMod Instance { get; private set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin EconomyMod se ha cargado correctamente!");
EconomyModPatches.ModConfig.LoadConfig(((BaseUnityPlugin)this).Config);
Logger.LogInfo((object)"Configuraciones cargadas correctamente!");
LNetworkUtils.OnNetworkStart += delegate
{
economicEvent = LNetworkMessage<EconomyModPatches.EconomicEvent>.Connect("economicEvent", (Action<EconomyModPatches.EconomicEvent, ulong>)null, (Action<EconomyModPatches.EconomicEvent>)null, (Action<EconomyModPatches.EconomicEvent, ulong>)null);
economicEvent.OnClientReceived += EconomyModPatches.EconomicEventReceiveFromServer;
Logger.LogInfo((object)"LethalNetworkAPI ha iniciado correctamente.");
};
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)this);
}
else
{
if ((Object)(object)((Component)Instance).gameObject != (Object)null)
{
Object.Destroy((Object)(object)((Component)Instance).gameObject);
}
else
{
Object.Destroy((Object)(object)Instance);
}
Instance = this;
}
try
{
harmony.PatchAll(typeof(EconomyModPatches.StartOfRound_StartGame_Patch));
Logger.LogInfo((object)"Parches de Harmony aplicados.");
}
catch (Exception ex)
{
Logger.LogError((object)("Error al aplicar parches de Harmony: " + ex.Message));
}
}
}
public static class StringExtensions
{
public static string RemoveDiacritics(this string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
string text2 = text.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new StringBuilder();
string text3 = text2;
foreach (char c in text3)
{
UnicodeCategory unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}
}
public static class Generator
{
private static readonly Random random = new Random();
public static int RandomNumber(int minValue, int maxValue)
{
if (minValue >= maxValue)
{
throw new ArgumentException("minValue debe ser menor que maxValue");
}
return random.Next(minValue, maxValue + 1);
}
public static float RandomNumber(float minValue, float maxValue)
{
if (minValue >= maxValue)
{
throw new ArgumentException("minValue debe ser menor que maxValue");
}
double num = random.NextDouble();
float num2 = (float)(num * (double)(maxValue - minValue) + (double)minValue);
return (float)Math.Round(num2, 2);
}
public static int WeightedRandomNumber(int min, int max, int mode)
{
if (min >= max || mode < min || mode > max)
{
throw new ArgumentException("Invalid arguments");
}
double num = random.NextDouble();
double a = ((!(num < (double)(mode - min) / (double)(max - min))) ? ((double)max - Math.Sqrt((1.0 - num) * (double)(max - mode) * (double)(max - min))) : ((double)min + Math.Sqrt(num * (double)(mode - min) * (double)(max - min))));
return (int)Math.Round(a);
}
public static float WeightedRandomNumber(float min, float max, float mode)
{
if (min >= max || mode < min || mode > max)
{
throw new ArgumentException("Invalid arguments");
}
double num = random.NextDouble();
double num2 = ((!(num < (double)(mode - min) / (double)(max - min))) ? ((double)max - Math.Sqrt((1.0 - num) * (double)(max - mode) * (double)(max - min))) : ((double)min + Math.Sqrt(num * (double)(mode - min) * (double)(max - min))));
return (float)num2;
}
}
public static class NumericExtensions
{
public static T PercentageOf<T>(this T value, decimal percentage) where T : struct, IComparable, IFormattable, IConvertible
{
decimal num = Convert.ToDecimal(value);
decimal num2 = num * (percentage / 100m);
return (T)Convert.ChangeType(num2, typeof(T));
}
}
public static class ProbabilityHelper
{
public static bool Attempt(float probability)
{
if ((double)probability < 0.0 || (double)probability > 1.0)
{
throw new ArgumentOutOfRangeException("probability", "Probability must be between 0.0 and 1.0.");
}
Random random = new Random();
double num = random.NextDouble();
return num < (double)probability;
}
}