2022-02-06 23:32:32 +11:00
using System.Linq ;
2023-07-08 14:08:32 +10:00
using System.Numerics ;
2022-02-06 23:32:32 +11:00
using Content.Server.Administration.Logs ;
using Content.Server.Decals ;
2022-05-08 01:51:33 -07:00
using Content.Server.Nutrition.EntitySystems ;
2022-02-06 23:32:32 +11:00
using Content.Server.Popups ;
using Content.Shared.Crayon ;
using Content.Shared.Database ;
using Content.Shared.Decals ;
using Content.Shared.Interaction ;
2022-03-13 01:33:23 +13:00
using Content.Shared.Interaction.Events ;
2022-02-06 23:32:32 +11:00
using Robust.Server.GameObjects ;
using Robust.Shared.Audio ;
using Robust.Shared.GameStates ;
using Robust.Shared.Prototypes ;
2023-07-08 09:02:17 -07:00
using Robust.Shared.Random ;
2022-02-06 23:32:32 +11:00
namespace Content.Server.Crayon ;
2022-05-09 07:16:43 +02:00
public sealed class CrayonSystem : SharedCrayonSystem
2022-02-06 23:32:32 +11:00
{
2022-05-28 23:41:17 -07:00
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2023-07-08 09:02:17 -07:00
[Dependency] private readonly IPrototypeManager _prototypeManager = default ! ;
2022-02-06 23:32:32 +11:00
[Dependency] private readonly DecalSystem _decals = default ! ;
[Dependency] private readonly PopupSystem _popup = default ! ;
2023-02-26 07:55:44 -05:00
[Dependency] private readonly SharedAudioSystem _audio = default ! ;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default ! ;
2022-02-06 23:32:32 +11:00
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < CrayonComponent , ComponentInit > ( OnCrayonInit ) ;
SubscribeLocalEvent < CrayonComponent , CrayonSelectMessage > ( OnCrayonBoundUI ) ;
2022-04-28 05:23:45 -07:00
SubscribeLocalEvent < CrayonComponent , CrayonColorMessage > ( OnCrayonBoundUIColor ) ;
2023-07-08 09:02:17 -07:00
SubscribeLocalEvent < CrayonComponent , UseInHandEvent > ( OnCrayonUse , before : new [ ] { typeof ( FoodSystem ) } ) ;
SubscribeLocalEvent < CrayonComponent , AfterInteractEvent > ( OnCrayonAfterInteract , after : new [ ] { typeof ( FoodSystem ) } ) ;
2022-02-06 23:32:32 +11:00
SubscribeLocalEvent < CrayonComponent , DroppedEvent > ( OnCrayonDropped ) ;
SubscribeLocalEvent < CrayonComponent , ComponentGetState > ( OnCrayonGetState ) ;
}
private static void OnCrayonGetState ( EntityUid uid , CrayonComponent component , ref ComponentGetState args )
{
2022-05-09 07:16:43 +02:00
args . State = new CrayonComponentState ( component . Color , component . SelectedState , component . Charges , component . Capacity ) ;
2022-02-06 23:32:32 +11:00
}
private void OnCrayonAfterInteract ( EntityUid uid , CrayonComponent component , AfterInteractEvent args )
{
if ( args . Handled | | ! args . CanReach )
return ;
if ( component . Charges < = 0 )
{
2022-03-27 01:09:48 -07:00
if ( component . DeleteEmpty )
UseUpCrayon ( uid , args . User ) ;
else
2022-12-19 10:41:47 +13:00
_popup . PopupEntity ( Loc . GetString ( "crayon-interact-not-enough-left-text" ) , uid , args . User ) ;
2022-03-27 01:09:48 -07:00
2022-02-06 23:32:32 +11:00
args . Handled = true ;
return ;
}
if ( ! args . ClickLocation . IsValid ( EntityManager ) )
{
2022-12-19 10:41:47 +13:00
_popup . PopupEntity ( Loc . GetString ( "crayon-interact-invalid-location" ) , uid , args . User ) ;
2022-02-06 23:32:32 +11:00
args . Handled = true ;
return ;
}
2023-07-08 09:02:17 -07:00
if ( ! _decals . TryAddDecal ( component . SelectedState , args . ClickLocation . Offset ( new Vector2 ( - 0.5f , - 0.5f ) ) , out _ , component . Color , cleanable : true ) )
2022-02-06 23:32:32 +11:00
return ;
if ( component . UseSound ! = null )
2023-07-08 09:02:17 -07:00
_audio . PlayPvs ( component . UseSound , uid , AudioParams . Default . WithVariation ( 0.125f ) ) ;
2022-02-06 23:32:32 +11:00
// Decrease "Ammo"
component . Charges - - ;
Dirty ( component ) ;
2022-05-28 23:41:17 -07:00
_adminLogger . Add ( LogType . CrayonDraw , LogImpact . Low , $"{EntityManager.ToPrettyString(args.User):user} drew a {component.Color:color} {component.SelectedState}" ) ;
2022-02-06 23:32:32 +11:00
args . Handled = true ;
2022-03-27 01:09:48 -07:00
if ( component . DeleteEmpty & & component . Charges < = 0 )
UseUpCrayon ( uid , args . User ) ;
2022-02-06 23:32:32 +11:00
}
private void OnCrayonUse ( EntityUid uid , CrayonComponent component , UseInHandEvent args )
{
// Open crayon window if neccessary.
if ( args . Handled )
return ;
2023-02-26 07:55:44 -05:00
if ( ! TryComp < ActorComponent > ( args . User , out var actor ) | |
component . UserInterface = = null )
{
return ;
}
2022-02-06 23:32:32 +11:00
2023-02-26 07:55:44 -05:00
_uiSystem . ToggleUi ( component . UserInterface , actor . PlayerSession ) ;
2022-02-06 23:32:32 +11:00
2023-02-26 07:55:44 -05:00
if ( component . UserInterface ? . SubscribedSessions . Contains ( actor . PlayerSession ) = = true )
2022-02-06 23:32:32 +11:00
{
// Tell the user interface the selected stuff
2023-07-08 09:02:17 -07:00
UserInterfaceSystem . SetUiState ( component . UserInterface , new CrayonBoundUserInterfaceState ( component . SelectedState , component . SelectableColor , component . Color ) ) ;
2022-02-06 23:32:32 +11:00
}
args . Handled = true ;
}
private void OnCrayonBoundUI ( EntityUid uid , CrayonComponent component , CrayonSelectMessage args )
{
// Check if the selected state is valid
if ( ! _prototypeManager . TryIndex < DecalPrototype > ( args . State , out var prototype ) | | ! prototype . Tags . Contains ( "crayon" ) ) return ;
component . SelectedState = args . State ;
2022-04-28 05:23:45 -07:00
2022-02-06 23:32:32 +11:00
Dirty ( component ) ;
}
2022-04-28 05:23:45 -07:00
private void OnCrayonBoundUIColor ( EntityUid uid , CrayonComponent component , CrayonColorMessage args )
{
// you still need to ensure that the given color is a valid color
2022-05-09 07:16:43 +02:00
if ( component . SelectableColor & & args . Color ! = component . Color )
2022-04-28 05:23:45 -07:00
{
2022-05-09 07:16:43 +02:00
component . Color = args . Color ;
2022-04-28 05:23:45 -07:00
Dirty ( component ) ;
}
}
2022-02-06 23:32:32 +11:00
private void OnCrayonInit ( EntityUid uid , CrayonComponent component , ComponentInit args )
{
component . Charges = component . Capacity ;
// Get the first one from the catalog and set it as default
var decal = _prototypeManager . EnumeratePrototypes < DecalPrototype > ( ) . FirstOrDefault ( x = > x . Tags . Contains ( "crayon" ) ) ;
component . SelectedState = decal ? . ID ? ? string . Empty ;
Dirty ( component ) ;
}
private void OnCrayonDropped ( EntityUid uid , CrayonComponent component , DroppedEvent args )
{
2022-03-13 21:47:28 +13:00
if ( TryComp < ActorComponent > ( args . User , out var actor ) )
2023-02-26 07:55:44 -05:00
_uiSystem . TryClose ( uid , SharedCrayonComponent . CrayonUiKey . Key , actor . PlayerSession ) ;
2022-02-06 23:32:32 +11:00
}
2022-03-27 01:09:48 -07:00
private void UseUpCrayon ( EntityUid uid , EntityUid user )
{
2022-12-19 10:41:47 +13:00
_popup . PopupEntity ( Loc . GetString ( "crayon-interact-used-up-text" , ( "owner" , uid ) ) , user , user ) ;
2022-03-27 01:09:48 -07:00
EntityManager . QueueDeleteEntity ( uid ) ;
}
2022-02-06 23:32:32 +11:00
}