diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomGoggles.cs b/EXILED/Exiled.CustomItems/API/Features/CustomGoggles.cs
new file mode 100644
index 0000000000..769f5ad936
--- /dev/null
+++ b/EXILED/Exiled.CustomItems/API/Features/CustomGoggles.cs
@@ -0,0 +1,215 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.CustomItems.API.Features
+{
+ using EventArgs;
+ using Exiled.API.Enums;
+ using Exiled.API.Features;
+ using Exiled.API.Features.Items;
+ using Exiled.Events.EventArgs.Player;
+ using Exiled.Events.EventArgs.Scp1344;
+
+ using InventorySystem.Items.Usables.Scp1344;
+
+ using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.Wearables;
+
+ ///
+ /// The Custom Goggles base class.
+ ///
+ public abstract class CustomGoggles : CustomItem
+ {
+ ///
+ /// Gets or sets the to use for these goggles.
+ /// This is locked to .
+ ///
+ public override ItemType Type
+ {
+ get => ItemType.SCP1344;
+ set => base.Type = ItemType.SCP1344;
+ }
+
+ ///
+ /// Gets or sets the duration, in seconds, that the item has been worn.
+ ///
+ public virtual float WearingTime { get; set; } = Scp1344Item.ActivationTime;
+
+ ///
+ /// Gets or sets the time, in seconds, required to remove the item.
+ ///
+ public virtual float RemovingTime { get; set; } = Scp1344Item.DeactivationTime;
+
+ ///
+ /// Gets or sets a value indicating whether the default SCP-1344 effect should be removed when wearing the goggles.
+ ///
+ public virtual bool Remove1344Effect { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether the glasses can be safely removed without bad effects.
+ ///
+ public virtual bool CanBeRemoveSafely { get; set; } = true;
+
+ ///
+ protected override void SubscribeEvents()
+ {
+ Exiled.Events.Handlers.Player.UsingItem += OnInternalUsingItem;
+ Exiled.Events.Handlers.Player.ItemRemoved += OnInternalItemRemoved;
+ Exiled.Events.Handlers.Scp1344.Deactivating += OnInternalDeactivating;
+ Exiled.Events.Handlers.Scp1344.ChangedStatus += OnInternalChangedStatus;
+ Exiled.Events.Handlers.Scp1344.ChangingStatus += OnInternalChangingStatus;
+ base.SubscribeEvents();
+ }
+
+ ///
+ protected override void UnsubscribeEvents()
+ {
+ Exiled.Events.Handlers.Player.UsingItem -= OnInternalUsingItem;
+ Exiled.Events.Handlers.Player.ItemRemoved -= OnInternalItemRemoved;
+ Exiled.Events.Handlers.Scp1344.Deactivating -= OnInternalDeactivating;
+ Exiled.Events.Handlers.Scp1344.ChangedStatus -= OnInternalChangedStatus;
+ Exiled.Events.Handlers.Scp1344.ChangingStatus -= OnInternalChangingStatus;
+ base.UnsubscribeEvents();
+ }
+
+ ///
+ protected override void OnOwnerChangingRole(OwnerChangingRoleEventArgs ev)
+ {
+ if (!ev.IsAllowed)
+ return;
+
+ if (Item.Get(ev.Item) is not Scp1344 { IsWorn: true } scp1344)
+ return;
+
+ InternalRemove(ev.Player, scp1344);
+ }
+
+ ///
+ /// Called when the player equips the goggles.
+ ///
+ /// The player who equipped the goggles.
+ /// The item being worn.
+ protected virtual void OnWornGoggles(Player player, Scp1344 goggles)
+ {
+ }
+
+ ///
+ /// Called when the player removes the goggles.
+ ///
+ /// The player who removed the goggles.
+ /// The item being removed.
+ protected virtual void OnRemovedGoggles(Player player, Scp1344 goggles)
+ {
+ }
+
+ private void OnInternalUsingItem(UsingItemEventArgs ev)
+ {
+ if (!ev.IsAllowed)
+ return;
+
+ if (ev.Item.Type != ItemType.SCP1344)
+ return;
+
+ foreach (Item item in ev.Player.Items)
+ {
+ if (item.Type != ItemType.SCP1344)
+ continue;
+
+ if (item is not Scp1344 { IsWorn: true })
+ continue;
+
+ ev.IsAllowed = false;
+ break;
+ }
+ }
+
+ private void OnInternalDeactivating(DeactivatingEventArgs ev)
+ {
+ if (!ev.IsAllowed)
+ return;
+
+ if (!Check(ev.Item))
+ return;
+
+ if (!CanBeRemoveSafely)
+ return;
+
+ ev.NewStatus = Scp1344Status.Idle;
+ ev.IsAllowed = false;
+ }
+
+ private void OnInternalChangedStatus(ChangedStatusEventArgs ev)
+ {
+ if (!Check(ev.Item))
+ return;
+
+ switch (ev.Scp1344Status)
+ {
+ case Scp1344Status.Deactivating:
+ ev.Scp1344.Base._useTime = Scp1344Item.DeactivationTime - RemovingTime;
+ break;
+
+ case Scp1344Status.Activating:
+ ev.Scp1344.Base._useTime = Scp1344Item.ActivationTime - WearingTime;
+ break;
+
+ case Scp1344Status.Active:
+ InternalEquip(ev.Player, ev.Scp1344);
+ break;
+ }
+ }
+
+ private void InternalEquip(Player player, Scp1344 goggles)
+ {
+ if (Remove1344Effect)
+ {
+ player.DisableEffect(EffectType.Scp1344);
+ player.ReferenceHub.EnableWearables(WearableElements.Scp1344Goggles);
+ }
+
+ OnWornGoggles(player, goggles);
+ }
+
+ private void InternalRemove(Player player, Scp1344 goggles)
+ {
+ if (!Remove1344Effect)
+ player.DisableEffect(EffectType.Scp1344);
+
+ if (CanBeRemoveSafely)
+ {
+ player.DisableEffect(EffectType.Blinded);
+ player.ReferenceHub?.DisableWearables(WearableElements.Scp1344Goggles);
+ }
+
+ OnRemovedGoggles(player, goggles);
+ }
+
+ private void OnInternalItemRemoved(ItemRemovedEventArgs ev)
+ {
+ if (!Check(ev.Item))
+ return;
+
+ if (ev.Item is not Scp1344 { IsWorn: true } scp1344)
+ return;
+
+ InternalRemove(ev.Player, scp1344);
+ }
+
+ private void OnInternalChangingStatus(ChangingStatusEventArgs ev)
+ {
+ if (!ev.IsAllowed)
+ return;
+
+ if (!Check(ev.Item))
+ return;
+
+ if (ev.Scp1344StatusOld != Scp1344Status.Deactivating || ev.Scp1344StatusNew != Scp1344Status.Idle)
+ return;
+
+ InternalRemove(ev.Player, ev.Scp1344);
+ }
+ }
+}
diff --git a/EXILED/Exiled.Events/EventArgs/Scp1344/DeactivatingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp1344/DeactivatingEventArgs.cs
index 96bcbc211e..8ff103fa53 100644
--- a/EXILED/Exiled.Events/EventArgs/Scp1344/DeactivatingEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Scp1344/DeactivatingEventArgs.cs
@@ -7,9 +7,12 @@
namespace Exiled.Events.EventArgs.Scp1344
{
+ using Exiled.API.Features;
using Exiled.API.Features.Items;
using Exiled.Events.EventArgs.Interfaces;
+ using InventorySystem.Items.Usables.Scp1344;
+
///
/// Contains all information before deactivating.
///
@@ -36,13 +39,18 @@ public DeactivatingEventArgs(Item item, bool isAllowed = true)
///
/// Gets the player in owner of the item.
///
- public Exiled.API.Features.Player Player { get; }
+ public Player Player { get; }
///
/// Gets Scp1344 item.
///
public Scp1344 Scp1344 { get; }
+ ///
+ /// Gets or sets the status of the SCP-1344 after the deactivation process.
+ ///
+ public Scp1344Status NewStatus { get; set; } = Scp1344Status.Active;
+
///
public bool IsAllowed { get; set; }
}
diff --git a/EXILED/Exiled.Events/Patches/Events/Scp1344/Deactivating.cs b/EXILED/Exiled.Events/Patches/Events/Scp1344/Deactivating.cs
index 9cf35fe606..ca0bbe8e35 100644
--- a/EXILED/Exiled.Events/Patches/Events/Scp1344/Deactivating.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Scp1344/Deactivating.cs
@@ -12,11 +12,16 @@ namespace Exiled.Events.Patches.Events.Scp1344
using Exiled.API.Features.Items;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Scp1344;
+
using HarmonyLib;
+
using InventorySystem.Items.Usables.Scp1344;
using InventorySystem.Items.Usables.Scp244;
+
using UnityEngine;
+ using static PlayerList;
+
///
/// Patches .
/// Adds the event,
@@ -34,39 +39,48 @@ private static bool Prefix(ref Scp1344Item __instance)
if (__instance._useTime == 0)
{
TryingDeactivatingEventArgs ev = new(Item.Get(__instance));
- Exiled.Events.Handlers.Scp1344.OnTryingDeactivating(ev);
+ Handlers.Scp1344.OnTryingDeactivating(ev);
if (!ev.IsAllowed)
{
- return StopDeactivation(__instance);
+ return StopDeactivation(__instance, Scp1344Status.Active);
}
}
- if (__instance._useTime + Time.deltaTime >= 5.1f)
+ if (__instance._useTime + Time.deltaTime >= Scp1344Item.DeactivationTime)
{
DeactivatingEventArgs deactivating = new(Item.Get(__instance));
- Exiled.Events.Handlers.Scp1344.OnDeactivating(deactivating);
+ Handlers.Scp1344.OnDeactivating(deactivating);
if (!deactivating.IsAllowed)
{
- return StopDeactivation(__instance);
+ return StopDeactivation(__instance, deactivating.NewStatus);
}
__instance.ActivateFinalEffects();
__instance.ServerDropItem(__instance);
DeactivatedEventArgs ev = new(Item.Get(__instance));
- Exiled.Events.Handlers.Scp1344.OnDeactivated(ev);
+ Handlers.Scp1344.OnDeactivated(ev);
return false;
}
return true;
}
- private static bool StopDeactivation(Scp1344Item instance)
+ private static bool StopDeactivation(Scp1344Item instance, Scp1344Status newStatus)
{
- instance.Status = Scp1344Status.Active;
- instance.ServerSetStatus(Scp1344Status.Active);
+ instance.Status = newStatus;
+ instance.ServerSetStatus(newStatus);
+
+ if (newStatus == Scp1344Status.Idle)
+ {
+ instance._useTime = 0f;
+ instance._savedIntensity = 0;
+ instance._cancelationTime = 0f;
+ instance.OwnerInventory?.ServerSelectItem(0);
+ }
+
return false;
}
}