2024-06-03 14:40:03 -07:00
using Content.Server.Administration.Logs ;
2022-12-24 18:59:49 -06:00
using Content.Server.Hands.Systems ;
using Content.Shared.Database ;
2022-12-20 16:34:34 -06:00
using Content.Shared.Examine ;
using Content.Shared.Interaction.Events ;
using Content.Shared.Item ;
2024-06-03 14:40:03 -07:00
using Content.Shared.Whitelist ;
2023-11-27 22:12:34 +11:00
using Robust.Server.Audio ;
2022-12-20 16:34:34 -06:00
using Robust.Shared.Map.Components ;
using Robust.Shared.Physics.Components ;
using Robust.Shared.Prototypes ;
using Robust.Shared.Random ;
namespace Content.Server.Holiday.Christmas ;
/// <summary>
/// This handles granting players their gift.
/// </summary>
public sealed class RandomGiftSystem : EntitySystem
{
[Dependency] private readonly AudioSystem _audio = default ! ;
[Dependency] private readonly HandsSystem _hands = default ! ;
[Dependency] private readonly IPrototypeManager _prototype = default ! ;
[Dependency] private readonly IRobustRandom _random = default ! ;
2022-12-24 18:59:49 -06:00
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2024-06-03 14:40:03 -07:00
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default ! ;
2025-02-18 13:27:30 +01:00
[Dependency] private readonly SharedTransformSystem _transform = default ! ;
2022-12-20 16:34:34 -06:00
private readonly List < string > _possibleGiftsSafe = new ( ) ;
private readonly List < string > _possibleGiftsUnsafe = new ( ) ;
/// <inheritdoc/>
public override void Initialize ( )
{
2023-12-22 09:13:45 -05:00
SubscribeLocalEvent < PrototypesReloadedEventArgs > ( OnPrototypesReloaded ) ;
2022-12-20 16:34:34 -06:00
SubscribeLocalEvent < RandomGiftComponent , MapInitEvent > ( OnGiftMapInit ) ;
SubscribeLocalEvent < RandomGiftComponent , UseInHandEvent > ( OnUseInHand ) ;
SubscribeLocalEvent < RandomGiftComponent , ExaminedEvent > ( OnExamined ) ;
BuildIndex ( ) ;
}
private void OnExamined ( EntityUid uid , RandomGiftComponent component , ExaminedEvent args )
{
2024-06-03 14:40:03 -07:00
if ( _whitelistSystem . IsWhitelistFail ( component . ContentsViewers , args . Examiner ) | | component . SelectedEntity is null )
2022-12-20 16:34:34 -06:00
return ;
var name = _prototype . Index < EntityPrototype > ( component . SelectedEntity ) . Name ;
2024-01-05 23:53:13 -07:00
args . PushText ( Loc . GetString ( "gift-packin-contains" , ( "name" , name ) ) ) ;
2022-12-20 16:34:34 -06:00
}
private void OnUseInHand ( EntityUid uid , RandomGiftComponent component , UseInHandEvent args )
{
if ( args . Handled )
return ;
if ( component . SelectedEntity is null )
return ;
var coords = Transform ( args . User ) . Coordinates ;
var handsEnt = Spawn ( component . SelectedEntity , coords ) ;
2023-10-19 12:34:31 -07:00
_adminLogger . Add ( LogType . EntitySpawn , LogImpact . Low , $"{ToPrettyString(args.User)} used {ToPrettyString(uid)} which spawned {ToPrettyString(handsEnt)}" ) ;
2022-12-20 16:34:34 -06:00
if ( component . Wrapper is not null )
Spawn ( component . Wrapper , coords ) ;
_audio . PlayPvs ( component . Sound , args . User ) ;
2025-02-18 13:27:30 +01:00
// Don't delete the entity in the event bus, so we queue it for deletion.
// We need the free hand for the new item, so we send it to nullspace.
_transform . DetachEntity ( uid , Transform ( uid ) ) ;
QueueDel ( uid ) ;
2022-12-20 16:34:34 -06:00
_hands . PickupOrDrop ( args . User , handsEnt ) ;
2025-02-18 13:27:30 +01:00
args . Handled = true ;
2022-12-20 16:34:34 -06:00
}
private void OnGiftMapInit ( EntityUid uid , RandomGiftComponent component , MapInitEvent args )
{
if ( component . InsaneMode )
component . SelectedEntity = _random . Pick ( _possibleGiftsUnsafe ) ;
else
component . SelectedEntity = _random . Pick ( _possibleGiftsSafe ) ;
}
private void OnPrototypesReloaded ( PrototypesReloadedEventArgs obj )
{
2023-12-22 09:13:45 -05:00
if ( obj . WasModified < EntityPrototype > ( ) )
BuildIndex ( ) ;
2022-12-20 16:34:34 -06:00
}
private void BuildIndex ( )
{
_possibleGiftsSafe . Clear ( ) ;
_possibleGiftsUnsafe . Clear ( ) ;
2025-05-20 15:08:55 +10:00
var itemCompName = Factory . GetComponentName < ItemComponent > ( ) ;
var mapGridCompName = Factory . GetComponentName < MapGridComponent > ( ) ;
var physicsCompName = Factory . GetComponentName < PhysicsComponent > ( ) ;
2022-12-20 16:34:34 -06:00
2024-12-13 22:20:00 +03:00
if ( ! _prototype . TryIndex < EntityCategoryPrototype > ( "ForkFiltered" , out var indexedFilter ) )
return ;
2022-12-20 16:34:34 -06:00
foreach ( var proto in _prototype . EnumeratePrototypes < EntityPrototype > ( ) )
{
2024-07-16 07:29:31 -07:00
if ( proto . Abstract | | proto . HideSpawnMenu | | proto . Components . ContainsKey ( mapGridCompName ) | | ! proto . Components . ContainsKey ( physicsCompName ) )
2022-12-20 16:34:34 -06:00
continue ;
2024-12-13 22:20:00 +03:00
//CP14 Only cp14 items
if ( ! proto . Categories . Contains ( indexedFilter ) )
continue ;
//CP14 end
2024-12-16 00:38:29 +03:00
_possibleGiftsUnsafe . Add ( proto . ID ) ;
if ( ! proto . Components . ContainsKey ( itemCompName ) )
continue ;
2022-12-20 16:34:34 -06:00
_possibleGiftsSafe . Add ( proto . ID ) ;
}
}
}