using Content.Shared._EstacaoPirata.Cards.Deck; using Content.Shared._EstacaoPirata.Cards.Hand; using Content.Shared._EstacaoPirata.Cards.Stack; using Content.Shared.Examine; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Verbs; using Robust.Shared.Containers; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared._EstacaoPirata.Cards.Card; /// /// This handles... /// public sealed class CardSystem : EntitySystem { [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly CardStackSystem _cardStack = default!; [Dependency] private readonly CardDeckSystem _cardDeck = default!; [Dependency] private readonly CardHandSystem _cardHand = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly SharedHandsSystem _hands = default!; /// public override void Initialize() { SubscribeLocalEvent>(AddTurnOnVerb); SubscribeLocalEvent>(OnActivationVerb); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnUse); SubscribeLocalEvent(OnActivate); } private void OnExamined(EntityUid uid, CardComponent component, ExaminedEvent args) { if (args.IsInDetailsRange && !component.Flipped) { args.PushMarkup(Loc.GetString("card-examined", ("target", Loc.GetString(component.Name)))); } } private void AddTurnOnVerb(EntityUid uid, CardComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; args.Verbs.Add(new AlternativeVerb() { Act = () => FlipCard(uid, component), Text = Loc.GetString("cards-verb-flip"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")), Priority = 1 }); if (args.Using == null || args.Using == args.Target) return; if (TryComp(args.Using, out var usingStack)) { args.Verbs.Add(new AlternativeVerb() { Act = () => JoinCards(args.User, args.Target, component, (EntityUid)args.Using, usingStack), Text = Loc.GetString("card-verb-join"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")), Priority = 2 }); } else if (TryComp(args.Using, out var usingCard)) { var pickup = _hands.IsHolding(args.User, args.Target); args.Verbs.Add(new AlternativeVerb() { Act = () => _cardHand.TrySetupHandOfCards(args.User, args.Target, component, args.Using.Value, usingCard, pickup), Text = Loc.GetString("card-verb-join"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")), Priority = 2 }); } } private void OnUse(EntityUid uid, CardComponent comp, UseInHandEvent args) { if (args.Handled) return; FlipCard(uid, comp); args.Handled = true; } /// /// Server-Side only method to flip card. This starts CardFlipUpdatedEvent event /// /// /// private void FlipCard(EntityUid uid, CardComponent component) { if (_net.IsClient) return; component.Flipped = !component.Flipped; Dirty(uid, component); RaiseNetworkEvent(new CardFlipUpdatedEvent(GetNetEntity(uid))); } private void JoinCards(EntityUid user, EntityUid first, CardComponent firstComp, EntityUid second, CardStackComponent secondStack) { if (_net.IsClient) return; bool pickup = _hands.IsHolding(user, first); EntityUid cardStack; bool? flip = null; if (HasComp(second)) { cardStack = SpawnInSameParent(_cardDeck.CardDeckBaseName, first); } else if (HasComp(second)) { cardStack = SpawnInSameParent(_cardHand.CardHandBaseName, first); if(TryComp(cardStack, out var stackHand)) stackHand.Flipped = firstComp.Flipped; flip = firstComp.Flipped; } else return; if (!TryComp(cardStack, out CardStackComponent? stack)) return; if (!_cardStack.TryInsertCard(cardStack, first, stack)) return; _cardStack.TransferNLastCardFromStacks(user, secondStack.Cards.Count, second, secondStack, cardStack, stack); if (flip != null) _cardStack.FlipAllCards(cardStack, stack, flip); //??? if(pickup) _hands.TryPickupAnyHand(user, cardStack); } // Frontier: tries to spawn an entity with the same parent as another given entity. // Useful when spawning decks/hands in a backpack, for example. private EntityUid SpawnInSameParent(EntProtoId prototype, EntityUid uid) { if (_container.IsEntityOrParentInContainer(uid) && _container.TryGetOuterContainer(uid, Transform(uid), out var container)) { return SpawnInContainerOrDrop(prototype, container.Owner, container.ID); } return Spawn(prototype, Transform(uid).Coordinates); } // Frontier: hacky misuse of the activation verb, but allows us a separate way to draw cards without needing additional buttons and event fiddling private void OnActivationVerb(EntityUid uid, CardComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; if (args.Using == args.Target) return; if (HasComp(uid)) return; if (args.Using == null) { args.Verbs.Add(new ActivationVerb() { Act = () => _hands.TryPickupAnyHand(args.User, args.Target), Text = Loc.GetString("cards-verb-draw"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")), Priority = 16 }); } else if (TryComp(args.Using, out var cardStack)) { args.Verbs.Add(new ActivationVerb() { Act = () => _cardStack.InsertCardOnStack(args.User, args.Using.Value, cardStack, args.Target), Text = Loc.GetString("cards-verb-draw"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")), Priority = 16 }); } else if (TryComp(args.Using, out var card)) { args.Verbs.Add(new ActivationVerb() { Act = () => _cardHand.TrySetupHandOfCards(args.User, args.Using.Value, card, args.Target, component, true), Text = Loc.GetString("cards-verb-draw"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")), Priority = 16 }); } } // End Frontier private void OnActivate(EntityUid uid, CardComponent component, ActivateInWorldEvent args) { if (!args.Complex || args.Handled) return; if (!TryComp(args.User, out var hands)) return; // Card stacks are handled differently if (HasComp(args.Target)) return; var activeItem = _hands.GetActiveItem((args.User, hands)); if (activeItem == null) { _hands.TryPickupAnyHand(args.User, args.Target); } else if (TryComp(activeItem, out var cardStack)) { _cardStack.InsertCardOnStack(args.User, activeItem.Value, cardStack, args.Target); } else if (TryComp(activeItem, out var card)) { _cardHand.TrySetupHandOfCards(args.User, activeItem.Value, card, args.Target, component, true); } } }