refactor
This commit is contained in:
@@ -3,46 +3,43 @@ using LabApi.Features;
|
||||
using LabApi.Features.Console;
|
||||
using LabApi.Loader;
|
||||
|
||||
namespace GamblingCoin
|
||||
namespace GamblingCoin;
|
||||
|
||||
public class Plugin : LabApi.Loader.Features.Plugins.Plugin
|
||||
{
|
||||
public class Plugin : LabApi.Loader.Features.Plugins.Plugin
|
||||
public static Plugin Singleton;
|
||||
private GamblingCoinEventHandler _eventHandler;
|
||||
public GamblingCoinChancesConfig ConfigChances;
|
||||
|
||||
public GamblingCoinGameplayConfig ConfigGameplay;
|
||||
public GamblingCoinMessages ConfigMessages;
|
||||
public override string Name => "GamblingCoin";
|
||||
public override string Author => "Code002Lover";
|
||||
public override Version Version { get; } = new(1, 0, 0);
|
||||
public override string Description => "Gamble your life away";
|
||||
public override Version RequiredApiVersion { get; } = new(LabApiProperties.CompiledVersion);
|
||||
|
||||
public override void LoadConfigs()
|
||||
{
|
||||
public override string Name => "GamblingCoin";
|
||||
public override string Author => "Code002Lover";
|
||||
public override Version Version { get; } = new(1, 0, 0);
|
||||
public override string Description => "Gamble your life away";
|
||||
public override Version RequiredApiVersion { get; } = new (LabApiProperties.CompiledVersion);
|
||||
|
||||
public GamblingCoinGameplayConfig ConfigGameplay;
|
||||
public GamblingCoinMessages ConfigMessages;
|
||||
public GamblingCoinChancesConfig ConfigChances;
|
||||
base.LoadConfigs();
|
||||
|
||||
public override void LoadConfigs()
|
||||
{
|
||||
base.LoadConfigs();
|
||||
ConfigGameplay = this.LoadConfig<GamblingCoinGameplayConfig>("gameplay.yml");
|
||||
ConfigMessages = this.LoadConfig<GamblingCoinMessages>("messages.yml");
|
||||
ConfigChances = this.LoadConfig<GamblingCoinChancesConfig>("chances.yml");
|
||||
}
|
||||
|
||||
ConfigGameplay = this.LoadConfig< GamblingCoinGameplayConfig > ("gameplay.yml");
|
||||
ConfigMessages = this.LoadConfig< GamblingCoinMessages > ("messages.yml");
|
||||
ConfigChances = this.LoadConfig< GamblingCoinChancesConfig > ("chances.yml");
|
||||
}
|
||||
|
||||
|
||||
public static Plugin Singleton;
|
||||
private GamblingCoinEventHandler _eventHandler;
|
||||
|
||||
public override void Enable()
|
||||
public override void Enable()
|
||||
{
|
||||
Logger.Debug("starting...");
|
||||
Singleton = this;
|
||||
_eventHandler = new GamblingCoinEventHandler();
|
||||
PlayerEvents.FlippedCoin += _eventHandler.OnFlippedCoin;
|
||||
}
|
||||
Logger.Debug("starting...");
|
||||
Singleton = this;
|
||||
_eventHandler = new GamblingCoinEventHandler();
|
||||
PlayerEvents.FlippedCoin += _eventHandler.OnFlippedCoin;
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
Logger.Debug("unloading...");
|
||||
Singleton = null;
|
||||
PlayerEvents.FlippedCoin -= _eventHandler.OnFlippedCoin;
|
||||
}
|
||||
public override void Disable()
|
||||
{
|
||||
Logger.Debug("unloading...");
|
||||
Singleton = null;
|
||||
PlayerEvents.FlippedCoin -= _eventHandler.OnFlippedCoin;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<Optimize>true</Optimize>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<Optimize>true</Optimize>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<Optimize>true</Optimize>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<Optimize>true</Optimize>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mirror">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\Mirror.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mirror">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\Mirror.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>..\..\.local\share\Steam\steamapps\common\SCP Secret Laboratory Dedicated Server\SCPSL_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Northwood.LabAPI" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Northwood.LabAPI" Version="1.0.2"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
+176
-170
@@ -1,184 +1,190 @@
|
||||
using CustomPlayerEffects;
|
||||
|
||||
namespace GamblingCoin
|
||||
namespace GamblingCoin;
|
||||
|
||||
public class GamblingCoinChancesConfig
|
||||
{
|
||||
|
||||
public class GamblingCoinChancesConfig
|
||||
public int NukeChance { get; set; } = 10;
|
||||
public int SpawnWaveChance { get; set; } = 150;
|
||||
public int CommonItemChance { get; set; } = 600;
|
||||
public int UncommonItemChance { get; set; } = 400;
|
||||
public int RareItemChance { get; set; } = 250;
|
||||
public int EpicItemChance { get; set; } = 100;
|
||||
public int LegendaryItemChance { get; set; } = 30;
|
||||
public int RandomTeleportChance { get; set; } = 200;
|
||||
public int StealItemChance { get; set; } = 100;
|
||||
public int ExplosionChance { get; set; } = 40;
|
||||
public int AntiMicroChance { get; set; } = 10;
|
||||
public int GrenadeChance { get; set; } = 50;
|
||||
public int PocketDimensionChance { get; set; } = 30;
|
||||
public int SwitchInventoryChance { get; set; } = 150;
|
||||
public int PositiveEffectChance { get; set; } = 300;
|
||||
public int NegativeEffectChance { get; set; } = 350;
|
||||
public int AdvancedPositiveEffectChance { get; set; } = 150;
|
||||
public int AdvancedNegativeEffectChance { get; set; } = 250;
|
||||
public int RemoveCoinChance { get; set; } = 300;
|
||||
}
|
||||
|
||||
public class GamblingCoinMessages
|
||||
{
|
||||
public string SpawnWaveMessage { get; set; } = "Did someone just enter the Site...?";
|
||||
public string ItemSpawnMessage { get; set; } = "*plop*";
|
||||
public string UncommonItemSpawnMessage { get; set; } = "*bump*";
|
||||
public string RareItemSpawnMessage { get; set; } = "*badunk*";
|
||||
public string EpicItemSpawnMessage { get; set; } = "*katong*";
|
||||
public string LegendaryItemSpawnMessage { get; set; } = "*sounds of monetary loss*";
|
||||
public string RandomTeleportMessage { get; set; } = "Where did you go?";
|
||||
public string StealItemMessage { get; set; } = "Be careful, the coin is slippery!";
|
||||
public string ExplosionMessage { get; set; } = "How did you even die '-'";
|
||||
public string AntiMicroMessage { get; set; } = "Where did all the micros go...";
|
||||
public string GrenadeMessage { get; set; } = "Watch out!";
|
||||
public string PocketDimensionMessage { get; set; } = "I hear he likes to see people suffer...";
|
||||
public string PositiveEffectMessage { get; set; } = "You feel slightly better";
|
||||
public string AdvancedPositiveEffectMessage { get; set; } = "You feel better";
|
||||
public string NegativeEffectMessage { get; set; } = "You feel worse";
|
||||
public string AdvancedNegativeEffectMessage { get; set; } = "You feel like you could die any second";
|
||||
public string SwitchInventoryMessage { get; set; } = "Whoops... looks like something happened to your items!";
|
||||
}
|
||||
|
||||
public class GamblingCoinGameplayConfig
|
||||
{
|
||||
public float WarheadTimeIncrease { get; set; } = 20f;
|
||||
public ushort BroadcastDuration { get; set; } = 3;
|
||||
public float TeleportHeightOffset { get; set; } = 1f;
|
||||
public int MaxMicrosToRemove { get; set; } = 8;
|
||||
|
||||
public ItemPoolConfig Items { get; set; } = new();
|
||||
public EffectConfig Effects { get; set; } = new();
|
||||
}
|
||||
|
||||
public class ItemPoolConfig
|
||||
{
|
||||
public ItemType[] CommonItems { get; set; } =
|
||||
{
|
||||
public int NukeChance { get; set; } = 10;
|
||||
public int SpawnWaveChance { get; set; } = 150;
|
||||
public int CommonItemChance { get; set; } = 600;
|
||||
public int UncommonItemChance { get; set; } = 400;
|
||||
public int RareItemChance { get; set; } = 250;
|
||||
public int EpicItemChance { get; set; } = 100;
|
||||
public int LegendaryItemChance { get; set; } = 30;
|
||||
public int RandomTeleportChance { get; set; } = 200;
|
||||
public int StealItemChance { get; set; } = 100;
|
||||
public int ExplosionChance { get; set; } = 40;
|
||||
public int AntiMicroChance { get; set; } = 10;
|
||||
public int GrenadeChance { get; set; } = 50;
|
||||
public int PocketDimensionChance { get; set; } = 30;
|
||||
public int SwitchInventoryChance { get; set; } = 150;
|
||||
public int PositiveEffectChance { get; set; } = 300;
|
||||
public int NegativeEffectChance { get; set; } = 350;
|
||||
public int AdvancedPositiveEffectChance { get; set; } = 150;
|
||||
public int AdvancedNegativeEffectChance { get; set; } = 250;
|
||||
public int RemoveCoinChance { get; set; } = 300;
|
||||
}
|
||||
|
||||
public class GamblingCoinMessages
|
||||
ItemType.KeycardJanitor,
|
||||
ItemType.KeycardScientist,
|
||||
ItemType.Medkit,
|
||||
ItemType.Painkillers,
|
||||
ItemType.Radio,
|
||||
ItemType.Flashlight
|
||||
};
|
||||
|
||||
public ItemType[] UncommonItems { get; set; } =
|
||||
{
|
||||
public string SpawnWaveMessage { get; set; } = "Did someone just enter the Site...?";
|
||||
public string ItemSpawnMessage { get; set; } = "*plop*";
|
||||
public string UncommonItemSpawnMessage { get; set; } = "*bump*";
|
||||
public string RareItemSpawnMessage { get; set; } = "*badunk*";
|
||||
public string EpicItemSpawnMessage { get; set; } = "*katong*";
|
||||
public string LegendaryItemSpawnMessage { get; set; } = "*sounds of monetary loss*";
|
||||
public string RandomTeleportMessage { get; set; } = "Where did you go?";
|
||||
public string StealItemMessage { get; set; } = "Be careful, the coin is slippery!";
|
||||
public string ExplosionMessage { get; set; } = "How did you even die '-'";
|
||||
public string AntiMicroMessage { get; set; } = "Where did all the micros go...";
|
||||
public string GrenadeMessage { get; set; } = "Watch out!";
|
||||
public string PocketDimensionMessage { get; set; } = "I hear he likes to see people suffer...";
|
||||
public string PositiveEffectMessage { get; set; } = "You feel slightly better";
|
||||
public string AdvancedPositiveEffectMessage { get; set; } = "You feel better";
|
||||
public string NegativeEffectMessage { get; set; } = "You feel worse";
|
||||
public string AdvancedNegativeEffectMessage { get; set; } = "You feel like you could die any second";
|
||||
public string SwitchInventoryMessage { get; set; } = "Whoops... looks like something happened to your items!";
|
||||
}
|
||||
ItemType.KeycardZoneManager,
|
||||
ItemType.KeycardGuard,
|
||||
ItemType.KeycardResearchCoordinator,
|
||||
ItemType.Adrenaline,
|
||||
ItemType.ArmorLight,
|
||||
ItemType.GrenadeFlash
|
||||
};
|
||||
|
||||
public class GamblingCoinGameplayConfig
|
||||
public ItemType[] RareItems { get; set; } =
|
||||
{
|
||||
public float WarheadTimeIncrease { get; set; } = 20f;
|
||||
public ushort BroadcastDuration { get; set; } = 3;
|
||||
public float TeleportHeightOffset { get; set; } = 1f;
|
||||
public int MaxMicrosToRemove { get; set; } = 8;
|
||||
|
||||
public ItemPoolConfig Items { get; set; } = new();
|
||||
public EffectConfig Effects { get; set; } = new();
|
||||
}
|
||||
|
||||
public class ItemPoolConfig
|
||||
ItemType.KeycardMTFPrivate,
|
||||
ItemType.KeycardContainmentEngineer,
|
||||
ItemType.KeycardMTFOperative,
|
||||
ItemType.ArmorCombat,
|
||||
ItemType.ArmorHeavy,
|
||||
ItemType.SCP330,
|
||||
ItemType.Lantern,
|
||||
ItemType.GrenadeHE
|
||||
};
|
||||
|
||||
public ItemType[] EpicItems { get; set; } =
|
||||
{
|
||||
public ItemType[] CommonItems { get; set; } = {
|
||||
ItemType.KeycardJanitor,
|
||||
ItemType.KeycardScientist,
|
||||
ItemType.Medkit,
|
||||
ItemType.Painkillers,
|
||||
ItemType.Radio,
|
||||
ItemType.Flashlight
|
||||
};
|
||||
ItemType.KeycardFacilityManager,
|
||||
ItemType.KeycardChaosInsurgency,
|
||||
ItemType.KeycardMTFCaptain,
|
||||
ItemType.SCP500
|
||||
};
|
||||
|
||||
public ItemType[] UncommonItems { get; set; } = {
|
||||
ItemType.KeycardZoneManager,
|
||||
ItemType.KeycardGuard,
|
||||
ItemType.KeycardResearchCoordinator,
|
||||
ItemType.Adrenaline,
|
||||
ItemType.ArmorLight,
|
||||
ItemType.GrenadeFlash
|
||||
};
|
||||
|
||||
public ItemType[] RareItems { get; set; } = {
|
||||
ItemType.KeycardMTFPrivate,
|
||||
ItemType.KeycardContainmentEngineer,
|
||||
ItemType.KeycardMTFOperative,
|
||||
ItemType.ArmorCombat,
|
||||
ItemType.ArmorHeavy,
|
||||
ItemType.SCP330,
|
||||
ItemType.Lantern,
|
||||
ItemType.GrenadeHE
|
||||
};
|
||||
|
||||
public ItemType[] EpicItems { get; set; } = {
|
||||
ItemType.KeycardFacilityManager,
|
||||
ItemType.KeycardChaosInsurgency,
|
||||
ItemType.KeycardMTFCaptain,
|
||||
ItemType.SCP500
|
||||
};
|
||||
|
||||
public ItemType[] LegendaryItems { get; set; } = {
|
||||
ItemType.KeycardO5,
|
||||
ItemType.MicroHID,
|
||||
ItemType.Jailbird,
|
||||
ItemType.GunCom45,
|
||||
ItemType.Coin
|
||||
};
|
||||
}
|
||||
|
||||
public class EffectConfig
|
||||
public ItemType[] LegendaryItems { get; set; } =
|
||||
{
|
||||
public AdvancedEffectSettings AdvancedPositive { get; set; } = new()
|
||||
ItemType.KeycardO5,
|
||||
ItemType.MicroHID,
|
||||
ItemType.Jailbird,
|
||||
ItemType.GunCom45,
|
||||
ItemType.Coin
|
||||
};
|
||||
}
|
||||
|
||||
public class EffectConfig
|
||||
{
|
||||
public AdvancedEffectSettings AdvancedPositive { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(Invisible), nameof(DamageReduction), nameof(MovementBoost) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
Effects = new[] { nameof(Invisible), nameof(DamageReduction), nameof(MovementBoost) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(Invisible), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(DamageReduction), new EffectSettings(100, 8f, false) },
|
||||
{ nameof(MovementBoost), new EffectSettings(40, 2f, false) }
|
||||
}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings Positive { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(Invigorated), nameof(RainbowTaste), nameof(Vitality), nameof(BodyshotReduction) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(Invigorated), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(RainbowTaste), new EffectSettings(2, 10f, true) },
|
||||
{ nameof(Vitality), new EffectSettings(1, 10f, true) },
|
||||
{ nameof(BodyshotReduction), new EffectSettings(4, 5f, true) }
|
||||
}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings Negative { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(Asphyxiated), nameof(AmnesiaVision), nameof(Bleeding), nameof(Blurred),
|
||||
nameof(Concussed), nameof(Deafened), nameof(Disabled) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(Asphyxiated), new EffectSettings(1, 10f, true) },
|
||||
{ nameof(AmnesiaVision), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Bleeding), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Blurred), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Concussed), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Deafened), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Disabled), new EffectSettings(1, 5f, true) }
|
||||
}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings AdvancedNegative { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(InsufficientLighting), nameof(AmnesiaVision), nameof(Burned) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(InsufficientLighting), new EffectSettings(1, 30f, true) },
|
||||
{ nameof(AmnesiaVision), new EffectSettings(3, 30f, true) },
|
||||
{ nameof(Burned), new EffectSettings(3, 60f, true) },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public class AdvancedEffectSettings
|
||||
{
|
||||
public string[] Effects { get; set; }
|
||||
public Dictionary<string, EffectSettings> Settings { get; set; }
|
||||
|
||||
public AdvancedEffectSettings(){}
|
||||
}
|
||||
|
||||
public class EffectSettings
|
||||
{
|
||||
public byte Intensity { get; set; }
|
||||
public float Duration { get; set; }
|
||||
public bool AddDuration { get; set; }
|
||||
|
||||
public EffectSettings(byte intensity, float duration, bool addDuration)
|
||||
{
|
||||
Intensity = intensity;
|
||||
Duration = duration;
|
||||
AddDuration = addDuration;
|
||||
{ nameof(Invisible), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(DamageReduction), new EffectSettings(100, 8f, false) },
|
||||
{ nameof(MovementBoost), new EffectSettings(40, 2f, false) }
|
||||
}
|
||||
|
||||
public EffectSettings(){}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings Positive { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(Invigorated), nameof(RainbowTaste), nameof(Vitality), nameof(BodyshotReduction) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(Invigorated), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(RainbowTaste), new EffectSettings(2, 10f, true) },
|
||||
{ nameof(Vitality), new EffectSettings(1, 10f, true) },
|
||||
{ nameof(BodyshotReduction), new EffectSettings(4, 5f, true) }
|
||||
}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings Negative { get; set; } = new()
|
||||
{
|
||||
Effects = new[]
|
||||
{
|
||||
nameof(Asphyxiated), nameof(AmnesiaVision), nameof(Bleeding), nameof(Blurred),
|
||||
nameof(Concussed), nameof(Deafened), nameof(Disabled)
|
||||
},
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(Asphyxiated), new EffectSettings(1, 10f, true) },
|
||||
{ nameof(AmnesiaVision), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Bleeding), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Blurred), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Concussed), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Deafened), new EffectSettings(1, 5f, true) },
|
||||
{ nameof(Disabled), new EffectSettings(1, 5f, true) }
|
||||
}
|
||||
};
|
||||
|
||||
public AdvancedEffectSettings AdvancedNegative { get; set; } = new()
|
||||
{
|
||||
Effects = new[] { nameof(InsufficientLighting), nameof(AmnesiaVision), nameof(Burned) },
|
||||
Settings = new Dictionary<string, EffectSettings>
|
||||
{
|
||||
{ nameof(InsufficientLighting), new EffectSettings(1, 30f, true) },
|
||||
{ nameof(AmnesiaVision), new EffectSettings(3, 30f, true) },
|
||||
{ nameof(Burned), new EffectSettings(3, 60f, true) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public class AdvancedEffectSettings
|
||||
{
|
||||
public string[] Effects { get; set; }
|
||||
public Dictionary<string, EffectSettings> Settings { get; set; }
|
||||
}
|
||||
|
||||
public class EffectSettings
|
||||
{
|
||||
public EffectSettings(byte intensity, float duration, bool addDuration)
|
||||
{
|
||||
Intensity = intensity;
|
||||
Duration = duration;
|
||||
AddDuration = addDuration;
|
||||
}
|
||||
|
||||
public EffectSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public byte Intensity { get; set; }
|
||||
public float Duration { get; set; }
|
||||
public bool AddDuration { get; set; }
|
||||
}
|
||||
@@ -1,240 +1,227 @@
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using CustomPlayerEffects;
|
||||
using InventorySystem.Items;
|
||||
using LabApi.Events.Arguments.PlayerEvents;
|
||||
using LabApi.Features.Wrappers;
|
||||
using MapGeneration;
|
||||
using Mirror;
|
||||
using PlayerRoles;
|
||||
using Respawning.Waves;
|
||||
using Utils;
|
||||
using Logger = LabApi.Features.Console.Logger;
|
||||
using Respawning;
|
||||
using UnityEngine;
|
||||
using MicroHIDItem = InventorySystem.Items.MicroHID.MicroHIDItem;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace GamblingCoin
|
||||
namespace GamblingCoin;
|
||||
|
||||
public class GamblingCoinEventHandler
|
||||
{
|
||||
public class GamblingCoinEventHandler
|
||||
private readonly WeightedRandomExecutor<PlayerFlippedCoinEventArgs> _executor;
|
||||
|
||||
public GamblingCoinEventHandler()
|
||||
{
|
||||
private readonly WeightedRandomExecutor<PlayerFlippedCoinEventArgs> _executor;
|
||||
var configMessages = Plugin.Singleton.ConfigMessages;
|
||||
var configGameplay = Plugin.Singleton.ConfigGameplay;
|
||||
var configChances = Plugin.Singleton.ConfigChances;
|
||||
|
||||
public GamblingCoinEventHandler()
|
||||
{
|
||||
var configMessages = Plugin.Singleton.ConfigMessages;
|
||||
var configGameplay = Plugin.Singleton.ConfigGameplay;
|
||||
var configChances = Plugin.Singleton.ConfigChances;
|
||||
_executor = new WeightedRandomExecutor<PlayerFlippedCoinEventArgs>();
|
||||
|
||||
_executor = new WeightedRandomExecutor<PlayerFlippedCoinEventArgs>();
|
||||
|
||||
_executor
|
||||
.AddAction(_ =>
|
||||
{
|
||||
Warhead.DetonationTime += configGameplay.WarheadTimeIncrease;
|
||||
Warhead.Start(suppressSubtitles: true);
|
||||
}, configChances.NukeChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.SpawnWaveMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
if(GetPlayers().Any(player=>player.Role == RoleTypeId.Spectator)) {
|
||||
Respawning.WaveManager.InitiateRespawn(Respawning.WaveManager.Waves[Random.Range(0, Respawning.WaveManager.Waves.Count)]);
|
||||
}
|
||||
}, configChances.SpawnWaveChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.ItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.CommonItems);
|
||||
}, configChances.CommonItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.UncommonItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.UncommonItems);
|
||||
}, configChances.UncommonItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.RareItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.RareItems);
|
||||
}, configChances.RareItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.EpicItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.EpicItems);
|
||||
}, configChances.EpicItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.LegendaryItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
var player = x.Player;
|
||||
var items = configGameplay.Items.LegendaryItems;
|
||||
|
||||
var itemIndex = Random.Range(0, items.Length);
|
||||
var item = items[itemIndex];
|
||||
|
||||
var pickup = Pickup.Create(item, player.Position + new UnityEngine.Vector3(0,1,0));
|
||||
if (pickup == null) return;
|
||||
|
||||
if (item is ItemType.MicroHID)
|
||||
{
|
||||
var host = Player.List.First(player1 => player1.IsHost);
|
||||
var micro = host.AddItem(pickup)!.Base;
|
||||
|
||||
var microItem = (MicroHIDItem)micro;
|
||||
microItem.EnergyManager.ServerSetEnergy(microItem.ItemId.SerialNumber, 100);
|
||||
|
||||
var newPickup = host.DropItem(micro);
|
||||
newPickup.Position = player.Position + new UnityEngine.Vector3(0, 1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pickup.Spawn();
|
||||
}, configChances.LegendaryItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.RandomTeleportMessage, configGameplay.BroadcastDuration);
|
||||
var randomRoom = Map.GetRandomRoom();
|
||||
if(randomRoom == null) return;
|
||||
|
||||
var isInOtherZone = randomRoom is { Zone: FacilityZone.Other };
|
||||
var isDetonated = Warhead.IsDetonated;
|
||||
var isDecontaminating = Decontamination.IsDecontaminating;
|
||||
|
||||
var isInDetonatedZone = isDetonated && randomRoom.Zone is FacilityZone.HeavyContainment
|
||||
or FacilityZone.LightContainment or FacilityZone.Entrance;
|
||||
var isInDecontaminatedZone = isDecontaminating && randomRoom.Zone is FacilityZone.LightContainment;
|
||||
while (isInOtherZone || isInDetonatedZone || isInDecontaminatedZone)
|
||||
{
|
||||
randomRoom = Map.GetRandomRoom();
|
||||
if(randomRoom == null) return;
|
||||
|
||||
isInOtherZone = randomRoom is { Zone: FacilityZone.Other };
|
||||
isInDetonatedZone = isDetonated && randomRoom.Zone is FacilityZone.HeavyContainment
|
||||
or FacilityZone.LightContainment or FacilityZone.Entrance;
|
||||
isInDecontaminatedZone = isDecontaminating && randomRoom.Zone is FacilityZone.LightContainment;
|
||||
}
|
||||
|
||||
var newPos = randomRoom.Position;
|
||||
|
||||
x.Player.Position = newPos + new UnityEngine.Vector3(0, configGameplay.TeleportHeightOffset, 0);;
|
||||
}, configChances.RandomTeleportChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.StealItemMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
if (x.Player.CurrentItem != null) x.Player.DropItem(x.Player.CurrentItem);
|
||||
}, configChances.StealItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.ExplosionMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
x.Player.ClearInventory();
|
||||
|
||||
TimedGrenadeProjectile.SpawnActive(x.Player.Position, ItemType.GrenadeHE, x.Player);
|
||||
}, configChances.ExplosionChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AntiMicroMessage, configGameplay.BroadcastDuration);
|
||||
GetPlayers().ForEach(p => { p.RemoveItem(ItemType.MicroHID, configGameplay.MaxMicrosToRemove); });
|
||||
//TODO: remove *all* micros
|
||||
}, configChances.AntiMicroChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.GrenadeMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
TimedGrenadeProjectile.SpawnActive(x.Player.Position, ItemType.GrenadeHE, x.Player, 2);
|
||||
}, configChances.GrenadeChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.PocketDimensionMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
PocketDimension.ForceInside(x.Player);
|
||||
},
|
||||
configChances.PocketDimensionChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AdvancedPositiveEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.AdvancedPositive);
|
||||
}, configChances.AdvancedPositiveEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.PositiveEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.Positive);
|
||||
}, configChances.PositiveEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.NegativeEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.Negative);
|
||||
}, configChances.NegativeEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AdvancedNegativeEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.AdvancedNegative);
|
||||
}, configChances.AdvancedNegativeEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
var players = GetPlayers();
|
||||
|
||||
var randomPlayer = players[Random.Range(0,GetPlayers().Length)];
|
||||
|
||||
while(randomPlayer.RoleBase.Team is Team.Dead or Team.SCPs) randomPlayer = players[Random.Range(0,GetPlayers().Length)];
|
||||
|
||||
x.Player.SendBroadcast(configMessages.SwitchInventoryMessage, configGameplay.BroadcastDuration);
|
||||
randomPlayer.SendBroadcast(configMessages.SwitchInventoryMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
var randomPlayerItems = new List<Item>();
|
||||
randomPlayer.Items.CopyTo(randomPlayerItems);
|
||||
var items = x.Player.Items;
|
||||
|
||||
randomPlayer.ClearInventory();
|
||||
foreach (var itemBase in items)
|
||||
{
|
||||
randomPlayer.AddItem(itemBase.Type);
|
||||
}
|
||||
|
||||
x.Player.ClearInventory();
|
||||
foreach (var randomPlayerItem in randomPlayerItems)
|
||||
{
|
||||
x.Player.AddItem(randomPlayerItem.Type);
|
||||
}
|
||||
}, configChances.SwitchInventoryChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.CurrentItem?.DropItem().Destroy();
|
||||
}, configChances.RemoveCoinChance);
|
||||
|
||||
return;
|
||||
|
||||
void ApplyRandomEffect(Player player, AdvancedEffectSettings settings)
|
||||
_executor
|
||||
.AddAction(_ =>
|
||||
{
|
||||
var effectChosen = settings.Effects[Random.Range(0, settings.Effects.Length)];
|
||||
var effectSettings = settings.Settings[effectChosen];
|
||||
|
||||
player.ReferenceHub.playerEffectsController.ChangeState(effectChosen, effectSettings.Intensity, effectSettings.Duration, effectSettings.AddDuration);
|
||||
}
|
||||
|
||||
void SpawnItemAtPlayer(Player player, ItemType item)
|
||||
Warhead.DetonationTime += configGameplay.WarheadTimeIncrease;
|
||||
Warhead.Start(suppressSubtitles: true);
|
||||
}, configChances.NukeChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
var pickup = Pickup.Create(item, player.Position + new UnityEngine.Vector3(0,1,0));
|
||||
if (pickup == null) return;
|
||||
|
||||
pickup.Spawn();
|
||||
}
|
||||
x.Player.SendBroadcast(configMessages.SpawnWaveMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
void SpawnRandomItemAtPlayer(Player player, ItemType[] items)
|
||||
if (GetPlayers().Any(player => player.Role == RoleTypeId.Spectator))
|
||||
WaveManager.InitiateRespawn(WaveManager.Waves[Random.Range(0, WaveManager.Waves.Count)]);
|
||||
}, configChances.SpawnWaveChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.ItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.CommonItems);
|
||||
}, configChances.CommonItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.UncommonItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.UncommonItems);
|
||||
}, configChances.UncommonItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.RareItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.RareItems);
|
||||
}, configChances.RareItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.EpicItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
SpawnRandomItemAtPlayer(x.Player, configGameplay.Items.EpicItems);
|
||||
}, configChances.EpicItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.LegendaryItemSpawnMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
var player = x.Player;
|
||||
var items = configGameplay.Items.LegendaryItems;
|
||||
|
||||
var itemIndex = Random.Range(0, items.Length);
|
||||
SpawnItemAtPlayer(player, items[itemIndex]);
|
||||
}
|
||||
var item = items[itemIndex];
|
||||
|
||||
Player[] GetPlayers()
|
||||
var pickup = Pickup.Create(item, player.Position + new Vector3(0, 1, 0));
|
||||
if (pickup == null) return;
|
||||
|
||||
if (item is ItemType.MicroHID)
|
||||
{
|
||||
var host = Player.List.First(player1 => player1.IsHost);
|
||||
var micro = host.AddItem(pickup)!.Base;
|
||||
|
||||
var microItem = (MicroHIDItem)micro;
|
||||
microItem.EnergyManager.ServerSetEnergy(microItem.ItemId.SerialNumber, 100);
|
||||
|
||||
var newPickup = host.DropItem(micro);
|
||||
newPickup.Position = player.Position + new Vector3(0, 1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pickup.Spawn();
|
||||
}, configChances.LegendaryItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
return Player.ReadyList.ToArray();
|
||||
}
|
||||
x.Player.SendBroadcast(configMessages.RandomTeleportMessage, configGameplay.BroadcastDuration);
|
||||
var randomRoom = Map.GetRandomRoom();
|
||||
if (randomRoom == null) return;
|
||||
|
||||
var isInOtherZone = randomRoom is { Zone: FacilityZone.Other };
|
||||
var isDetonated = Warhead.IsDetonated;
|
||||
var isDecontaminating = Decontamination.IsDecontaminating;
|
||||
|
||||
var isInDetonatedZone = isDetonated && randomRoom.Zone is FacilityZone.HeavyContainment
|
||||
or FacilityZone.LightContainment or FacilityZone.Entrance;
|
||||
var isInDecontaminatedZone = isDecontaminating && randomRoom.Zone is FacilityZone.LightContainment;
|
||||
while (isInOtherZone || isInDetonatedZone || isInDecontaminatedZone)
|
||||
{
|
||||
randomRoom = Map.GetRandomRoom();
|
||||
if (randomRoom == null) return;
|
||||
|
||||
isInOtherZone = randomRoom is { Zone: FacilityZone.Other };
|
||||
isInDetonatedZone = isDetonated && randomRoom.Zone is FacilityZone.HeavyContainment
|
||||
or FacilityZone.LightContainment or FacilityZone.Entrance;
|
||||
isInDecontaminatedZone = isDecontaminating && randomRoom.Zone is FacilityZone.LightContainment;
|
||||
}
|
||||
|
||||
var newPos = randomRoom.Position;
|
||||
|
||||
x.Player.Position = newPos + new Vector3(0, configGameplay.TeleportHeightOffset, 0);
|
||||
;
|
||||
}, configChances.RandomTeleportChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.StealItemMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
if (x.Player.CurrentItem != null) x.Player.DropItem(x.Player.CurrentItem);
|
||||
}, configChances.StealItemChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.ExplosionMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
x.Player.ClearInventory();
|
||||
|
||||
TimedGrenadeProjectile.SpawnActive(x.Player.Position, ItemType.GrenadeHE, x.Player);
|
||||
}, configChances.ExplosionChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AntiMicroMessage, configGameplay.BroadcastDuration);
|
||||
GetPlayers().ForEach(p => { p.RemoveItem(ItemType.MicroHID, configGameplay.MaxMicrosToRemove); });
|
||||
//TODO: remove *all* micros
|
||||
}, configChances.AntiMicroChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.GrenadeMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
TimedGrenadeProjectile.SpawnActive(x.Player.Position, ItemType.GrenadeHE, x.Player, 2);
|
||||
}, configChances.GrenadeChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.PocketDimensionMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
PocketDimension.ForceInside(x.Player);
|
||||
},
|
||||
configChances.PocketDimensionChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AdvancedPositiveEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.AdvancedPositive);
|
||||
}, configChances.AdvancedPositiveEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.PositiveEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.Positive);
|
||||
}, configChances.PositiveEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.NegativeEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.Negative);
|
||||
}, configChances.NegativeEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
x.Player.SendBroadcast(configMessages.AdvancedNegativeEffectMessage, configGameplay.BroadcastDuration);
|
||||
ApplyRandomEffect(x.Player, configGameplay.Effects.AdvancedNegative);
|
||||
}, configChances.AdvancedNegativeEffectChance)
|
||||
.AddAction(x =>
|
||||
{
|
||||
var players = GetPlayers();
|
||||
|
||||
var randomPlayer = players[Random.Range(0, GetPlayers().Length)];
|
||||
|
||||
while (randomPlayer.RoleBase.Team is Team.Dead or Team.SCPs)
|
||||
randomPlayer = players[Random.Range(0, GetPlayers().Length)];
|
||||
|
||||
x.Player.SendBroadcast(configMessages.SwitchInventoryMessage, configGameplay.BroadcastDuration);
|
||||
randomPlayer.SendBroadcast(configMessages.SwitchInventoryMessage, configGameplay.BroadcastDuration);
|
||||
|
||||
var randomPlayerItems = new List<Item>();
|
||||
randomPlayer.Items.CopyTo(randomPlayerItems);
|
||||
var items = x.Player.Items;
|
||||
|
||||
randomPlayer.ClearInventory();
|
||||
foreach (var itemBase in items) randomPlayer.AddItem(itemBase.Type);
|
||||
|
||||
x.Player.ClearInventory();
|
||||
foreach (var randomPlayerItem in randomPlayerItems) x.Player.AddItem(randomPlayerItem.Type);
|
||||
}, configChances.SwitchInventoryChance)
|
||||
.AddAction(x => { x.Player.CurrentItem?.DropItem().Destroy(); }, configChances.RemoveCoinChance);
|
||||
|
||||
return;
|
||||
|
||||
void ApplyRandomEffect(Player player, AdvancedEffectSettings settings)
|
||||
{
|
||||
var effectChosen = settings.Effects[Random.Range(0, settings.Effects.Length)];
|
||||
var effectSettings = settings.Settings[effectChosen];
|
||||
|
||||
player.ReferenceHub.playerEffectsController.ChangeState(effectChosen, effectSettings.Intensity,
|
||||
effectSettings.Duration, effectSettings.AddDuration);
|
||||
}
|
||||
|
||||
public void OnFlippedCoin(PlayerFlippedCoinEventArgs ev)
|
||||
void SpawnItemAtPlayer(Player player, ItemType item)
|
||||
{
|
||||
_executor.Execute(ev);
|
||||
var pickup = Pickup.Create(item, player.Position + new Vector3(0, 1, 0));
|
||||
if (pickup == null) return;
|
||||
|
||||
pickup.Spawn();
|
||||
}
|
||||
|
||||
void SpawnRandomItemAtPlayer(Player player, ItemType[] items)
|
||||
{
|
||||
var itemIndex = Random.Range(0, items.Length);
|
||||
SpawnItemAtPlayer(player, items[itemIndex]);
|
||||
}
|
||||
|
||||
Player[] GetPlayers()
|
||||
{
|
||||
return Player.ReadyList.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnFlippedCoin(PlayerFlippedCoinEventArgs ev)
|
||||
{
|
||||
_executor.Execute(ev);
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,12 @@ namespace GamblingCoin;
|
||||
|
||||
public class WeightedRandomExecutor<TEvent>
|
||||
{
|
||||
private class WeightedAction
|
||||
{
|
||||
public Action<TEvent> Action { get; }
|
||||
public double Weight { get; }
|
||||
|
||||
public WeightedAction(Action<TEvent> action, double weight)
|
||||
{
|
||||
if (weight <= 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(weight),
|
||||
"Weight must be positive."
|
||||
);
|
||||
|
||||
Action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
Weight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<WeightedAction> _actions = new();
|
||||
private readonly Random _random = new();
|
||||
private double _totalWeight;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a function to be potentially executed, along with its weight.
|
||||
/// Adds a function to be potentially executed, along with its weight.
|
||||
/// </summary>
|
||||
/// <param name="action">The function to add. It must accept an argument of type TEvent.</param>
|
||||
/// <param name="weight">The positive weight for this function. Higher weights mean higher probability.</param>
|
||||
@@ -34,31 +16,27 @@ public class WeightedRandomExecutor<TEvent>
|
||||
var weightedAction = new WeightedAction(action, weight);
|
||||
_actions.Add(weightedAction);
|
||||
_totalWeight += weight;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes one of the added functions randomly based on their weights.
|
||||
/// The chosen function will be called with the provided 'ev' argument.
|
||||
/// Executes one of the added functions randomly based on their weights.
|
||||
/// The chosen function will be called with the provided 'ev' argument.
|
||||
/// </summary>
|
||||
/// <param name="ev">The event argument to pass to the chosen function.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown if no actions have been added.</exception>
|
||||
public void Execute(TEvent ev)
|
||||
{
|
||||
if (_actions.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"No actions have been added to execute."
|
||||
);
|
||||
}
|
||||
|
||||
if (_totalWeight <= 0) // Should not happen if AddAction validates weight > 0
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Total weight is zero or negative, cannot execute."
|
||||
);
|
||||
}
|
||||
|
||||
var randomNumber = _random.NextDouble() * _totalWeight;
|
||||
double cumulativeWeight = 0;
|
||||
@@ -74,9 +52,24 @@ public class WeightedRandomExecutor<TEvent>
|
||||
// Fallback in case of floating point inaccuracies,
|
||||
// or if somehow randomNumber was exactly _totalWeight (NextDouble is < 1.0)
|
||||
// This should ideally pick the last item if all weights were summed up.
|
||||
if (_actions.Any())
|
||||
if (_actions.Any()) _actions.Last().Action(ev);
|
||||
}
|
||||
|
||||
private class WeightedAction
|
||||
{
|
||||
public WeightedAction(Action<TEvent> action, double weight)
|
||||
{
|
||||
_actions.Last().Action(ev);
|
||||
if (weight <= 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(weight),
|
||||
"Weight must be positive."
|
||||
);
|
||||
|
||||
Action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
Weight = weight;
|
||||
}
|
||||
|
||||
public Action<TEvent> Action { get; }
|
||||
public double Weight { get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user