Compare commits

..

4 Commits

Author SHA1 Message Date
Renovate Bot
2e97996f8f Update dependency csharpier to 1.0.3 2025-07-12 21:14:29 +00:00
HoherGeist
2f483ca113 refactor + lessen stamina usage 2025-07-12 23:02:07 +02:00
HoherGeist
a8063216cc Changes by code002lover 2025-07-12 22:53:13 +02:00
HoherGeist
14e32bc921 +Blood Fueled Added 2025-07-12 22:40:11 +02:00
4 changed files with 149 additions and 8 deletions

View File

@ -0,0 +1,66 @@
using LabApi.Features.Wrappers;
using PlayerRoles.FirstPersonControl;
using Logger = LabApi.Features.Console.Logger;
using Random = System.Random;
namespace CustomClasses;
public class DisableStaminaRegenEffect : CustomPlayerEffect, IStaminaModifier
{
public bool StaminaModifierActive => IsEnabled;
public float StaminaUsageMultiplier => 1;
public float StaminaRegenMultiplier => 0;
public bool SprintingDisabled => false;
public override EffectClassification Classification => EffectClassification.Negative;
}
public class BloodFueledStaminaEffect : CustomPlayerEffect, IStaminaModifier
{
public bool StaminaModifierActive => IsEnabled;
public float StaminaUsageMultiplier => 0.1f;
public float StaminaRegenMultiplier => 1;
public bool SprintingDisabled => false;
public override EffectClassification Classification => EffectClassification.Negative;
}
public class BloodFueledManager
{
private readonly CustomClasses _plugin;
public static bool IsBloodFueled(Player player) => player.CustomInfo.Contains("Blood Fueled");
public BloodFueledManager(CustomClasses plugin)
{
_plugin = plugin;
}
}
public class BloodFueledHandler : CustomClassHandler
{
public override void HandleSpawn(Player player, CustomClassConfig config, Random random)
{
player.SendBroadcast("You are the <color=#6e2e99>Blood Fueled</color>!", CustomClasses.BroadcastDuration);
const string customInfo = "<color=#A0A0A0>Blood Fueled</color>";
if (!Player.ValidateCustomInfo(customInfo, out var reason))
{
Logger.Error($"Invalid custom info for Blood Fueled: {reason}");
}
else
{
player.CustomInfo = customInfo;
player.InfoArea |= PlayerInfoArea.CustomInfo;
}
player.MaxHumeShield = 0;
player.HumeShield = 0;
player.MaxHealth = 3500;
player.Health = 3500;
player.EnableEffect<DisableStaminaRegenEffect>(1, float.PositiveInfinity);
}
}

View File

@ -38,33 +38,41 @@ public sealed class CustomClasses : Plugin
/// <inheritdoc/>
public override string Name => "CustomClasses";
/// <inheritdoc/>
public override string Author => "Code002Lover";
/// <inheritdoc/>
public override Version Version { get; } = new(1, 0, 0);
/// <inheritdoc/>
public override string Description => "Adds custom classes to the game";
/// <inheritdoc/>
public override Version RequiredApiVersion { get; } = new(LabApiProperties.CompiledVersion);
public const ushort BroadcastDuration = 10;
/// <summary>
/// Configuration for the Janitor class.
/// </summary>
public JanitorConfig JanitorConfig { get; private set; } = new();
/// <summary>
/// Configuration for the Research Subject class.
/// </summary>
public ResearchSubjectConfig ResearchSubjectConfig { get; private set; } = new();
/// <summary>
/// Configuration for the Head Guard class.
/// </summary>
public HeadGuardConfig HeadGuardConfig { get; private set; } = new();
/// <summary>
/// Configuration for the Medic class.
/// </summary>
public MedicConfig MedicConfig { get; private set; } = new();
/// <summary>
/// Configuration for the Gambler class.
/// </summary>
@ -74,7 +82,7 @@ public sealed class CustomClasses : Plugin
/// Configuration for the ShadowStepper class.
/// </summary>
public ShadowStepperConfig ShadowStepperConfig { get; private set; } = new();
public MtfDemolitionistConfig MtfDemolitionistConfig { get; private set; } = new();
public ScoutConfig ScoutConfig { get; private set; } = new();
public ExplosiveMasterConfig ExplosiveMasterConfig { get; private set; } = new();
@ -82,6 +90,7 @@ public sealed class CustomClasses : Plugin
public SerpentsHandConfig SerpentsHandConfig { get; private set; } = new();
public NegromancerConfig NegromancerConfig { get; private set; } = new();
public NegromancerShadowConfig NegromancerShadowConfig { get; private set; } = new();
public BloodFueledConfig BloodFueledConfig { get; private set; } = new();
internal readonly Dictionary<Player, Hint> Hints = new();
@ -104,9 +113,11 @@ public sealed class CustomClasses : Plugin
// Then decode using standard base64
var decodedBytes = Convert.FromBase64String(standardized);
var decodedMessage = System.Text.Encoding.UTF8.GetString(decodedBytes);
Logger.Info(decodedMessage);
CustomPlayerEffect.Initialize();
PlayerEvents.Spawned += OnPlayerSpawned;
ServerEvents.RoundEnded += OnRoundEnded;
Scp914Events.ProcessingPickup += OnScp914ProcessingPickup;
@ -269,16 +280,17 @@ public sealed class CustomClasses : Plugin
private void OnPlayerSpawned(PlayerSpawnedEventArgs ev)
{
ev.Player.CustomInfo = "";
if (ClassManager.TryHandleSpawn(ev.Player, JanitorConfig, typeof(JanitorConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, ResearchSubjectConfig, typeof(ResearchSubjectConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, HeadGuardConfig, typeof(HeadGuardConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, MedicConfig, typeof(MedicConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, GamblerConfig, typeof(GamblerConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, ShadowStepperConfig, typeof(ShadowStepperConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, MtfDemolitionistConfig, typeof(MtfDemolitionistConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, MtfDemolitionistConfig, typeof(MtfDemolitionistConfig), null))
return;
if (ClassManager.TryHandleSpawn(ev.Player, ExplosiveMasterConfig, typeof(ExplosiveMasterConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, FlashMasterConfig, typeof(FlashMasterConfig), null)) return;
if (ClassManager.TryHandleSpawn(ev.Player, BloodFueledConfig, typeof(BloodFueledConfig), null)) return;
}
private static void OnScp914ProcessingPickup(Scp914ProcessingPickupEventArgs ev)
@ -338,6 +350,7 @@ public class CustomClassManager
RegisterHandler<SerpentsHandConfig>(new SerpentsHandHandler(), new SerpentsHandState());
RegisterHandler<NegromancerConfig>(new NegromancerHandler());
RegisterHandler<NegromancerShadowConfig>(new NegromancerShadowHandler());
RegisterHandler<BloodFueledConfig>(new BloodFueledHandler());
}
public SpawnState GetSpawnState(Type configType)
@ -959,6 +972,14 @@ public sealed class NegromancerShadowConfig : CustomClassConfig
public override ItemType[] Items { get; set; } = [];
}
public sealed class BloodFueledConfig : CustomClassConfig
{
public override double ChancePerPlayer { get; set; } = 1.0;
public override int MaxSpawns { get; set; } = int.MaxValue;
public override RoleTypeId RequiredRole { get; set; } = RoleTypeId.Scp939;
public override ItemType[] Items { get; set; } = [];
}
/// <summary>
/// Tracks the spawn state for a custom class.
/// </summary>
@ -970,4 +991,4 @@ public record SpawnState
{
Spawns = 0;
}
}
}

View File

@ -0,0 +1,53 @@
using CustomPlayerEffects;
using LabApi.Features.Wrappers;
using Mirror;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = LabApi.Features.Console.Logger;
namespace CustomClasses;
public abstract class CustomPlayerEffect : StatusEffectBase
{
private static bool _isLoaded;
public Player Owner { get; private set; } = null!;
protected override void Start()
{
Owner = Player.Get(Hub);
base.Start();
}
public override string ToString() => $"{GetType().Name}: Owner ({Owner}) - Intensity ({Intensity}) - Duration {Duration}";
internal static void Initialize()
{
SceneManager.sceneLoaded += (_, _) =>
{
if (_isLoaded)
return;
_isLoaded = true;
Type[] toLoad =
[
typeof(DisableStaminaRegenEffect),
typeof(BloodFueledStaminaEffect)
];
var playerEffects = NetworkManager.singleton.playerPrefab.GetComponent<ReferenceHub>().playerEffectsController.effectsGameObject.transform;
foreach (var type in toLoad)
{
if (!typeof(StatusEffectBase).IsAssignableFrom(type))
{
Logger.Error($"[CustomPlayerEffect.Initialize] {type.FullName} is not a valid StatusEffectBase and thus could not be registered!");
return;
}
// register effect into prefab
new GameObject(type.Name, type).transform.parent = playerEffects;
}
};
}
}

View File

@ -67,6 +67,7 @@ public class SetCClassCommand : ICommand
SerpentsHandManager.PreSpawn(player);
}),
"negromancer" => manager.ForceSpawn(player, customClasses.NegromancerConfig, typeof(NegromancerConfig), null),
"bloodfueled" => manager.ForceSpawn(player, customClasses.BloodFueledConfig, typeof(BloodFueledConfig), null),
_ => false
};