diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 5c575d7f76..399c51a61a 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -115,6 +115,7 @@ namespace Content.Client.Entry "SurgeryTool", "EmitSoundOnThrow", "Flash", + "Telecrystal", "TrashSpawner", "RCD", "RCDDeconstructWhitelist", diff --git a/Content.Server/Entry/EntryPoint.cs b/Content.Server/Entry/EntryPoint.cs index 2927f9298f..dfc51731c4 100644 --- a/Content.Server/Entry/EntryPoint.cs +++ b/Content.Server/Entry/EntryPoint.cs @@ -11,7 +11,6 @@ using Content.Server.GameTicking; using Content.Server.Holiday.Interfaces; using Content.Server.IoC; using Content.Server.NodeContainer.NodeGroups; -using Content.Server.PDA.Managers; using Content.Server.Preferences.Managers; using Content.Server.Sandbox; using Content.Server.Speech; @@ -87,7 +86,6 @@ namespace Content.Server.Entry IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); - IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); diff --git a/Content.Server/GameTicking/Presets/PresetSuspicion.cs b/Content.Server/GameTicking/Presets/PresetSuspicion.cs index 80186871ac..59f3e7d1db 100644 --- a/Content.Server/GameTicking/Presets/PresetSuspicion.cs +++ b/Content.Server/GameTicking/Presets/PresetSuspicion.cs @@ -3,13 +3,12 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules; using Content.Server.Inventory.Components; using Content.Server.Items; -using Content.Server.PDA.Managers; using Content.Server.Players; using Content.Server.Suspicion; using Content.Server.Suspicion.Roles; using Content.Server.Traitor.Uplink; +using Content.Server.Traitor.Uplink.Account; using Content.Server.Traitor.Uplink.Components; -using Content.Server.Traitor.Uplink.Systems; using Content.Shared.CCVar; using Content.Shared.Inventory; using Content.Shared.Roles; @@ -34,7 +33,6 @@ namespace Content.Server.GameTicking.Presets [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] protected readonly IEntityManager EntityManager = default!; - [Dependency] private readonly IUplinkManager _uplinkManager = default!; public int MinPlayers { get; set; } public int MinTraitors { get; set; } @@ -117,8 +115,9 @@ namespace Content.Server.GameTicking.Presets // creadth: we need to create uplink for the antag. // PDA should be in place already, so we just need to // initiate uplink account. - var uplinkAccount = new UplinkAccount(mind.OwnedEntity!.Uid, TraitorStartingBalance); - _uplinkManager.AddNewAccount(uplinkAccount); + var uplinkAccount = new UplinkAccount(TraitorStartingBalance, mind.OwnedEntity!.Uid); + var accounts = EntityManager.EntitySysManager.GetEntitySystem(); + accounts.AddNewAccount(uplinkAccount); // try to place uplink if (!EntityManager.EntitySysManager.GetEntitySystem() diff --git a/Content.Server/GameTicking/Presets/PresetTraitor.cs b/Content.Server/GameTicking/Presets/PresetTraitor.cs index b135f0a94b..96267cbbcd 100644 --- a/Content.Server/GameTicking/Presets/PresetTraitor.cs +++ b/Content.Server/GameTicking/Presets/PresetTraitor.cs @@ -7,12 +7,11 @@ using Content.Server.Inventory.Components; using Content.Server.Items; using Content.Server.Objectives.Interfaces; using Content.Server.PDA; -using Content.Server.PDA.Managers; using Content.Server.Players; using Content.Server.Traitor; using Content.Server.Traitor.Uplink; +using Content.Server.Traitor.Uplink.Account; using Content.Server.Traitor.Uplink.Components; -using Content.Server.Traitor.Uplink.Systems; using Content.Shared.CCVar; using Content.Shared.Dataset; using Content.Shared.Inventory; @@ -38,7 +37,6 @@ namespace Content.Server.GameTicking.Presets [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] protected readonly IEntityManager EntityManager = default!; - [Dependency] private readonly IUplinkManager _uplinkManager = default!; public override string ModeTitle => Loc.GetString("traitor-title"); @@ -124,8 +122,9 @@ namespace Content.Server.GameTicking.Presets // initiate uplink account. DebugTools.AssertNotNull(mind.OwnedEntity); - var uplinkAccount = new UplinkAccount(mind.OwnedEntity!.Uid, StartingBalance); - _uplinkManager.AddNewAccount(uplinkAccount); + var uplinkAccount = new UplinkAccount(StartingBalance, mind.OwnedEntity!.Uid); + var accounts = EntityManager.EntitySysManager.GetEntitySystem(); + accounts.AddNewAccount(uplinkAccount); if (!EntityManager.EntitySysManager.GetEntitySystem() .AddUplink(mind.OwnedEntity, uplinkAccount)) diff --git a/Content.Server/GameTicking/Presets/PresetTraitorDeathMatch.cs b/Content.Server/GameTicking/Presets/PresetTraitorDeathMatch.cs index 07236033f8..c15ce05ab4 100644 --- a/Content.Server/GameTicking/Presets/PresetTraitorDeathMatch.cs +++ b/Content.Server/GameTicking/Presets/PresetTraitorDeathMatch.cs @@ -27,10 +27,9 @@ using Robust.Shared.Map; using Robust.Shared.Random; using Content.Server.Traitor.Uplink.Components; using Content.Shared.Traitor.Uplink; -using Content.Server.PDA.Managers; using Content.Server.Traitor.Uplink; -using Content.Server.Traitor.Uplink.Systems; using Content.Shared.Damage.Prototypes; +using Content.Server.Traitor.Uplink.Account; namespace Content.Server.GameTicking.Presets { @@ -43,7 +42,6 @@ namespace Content.Server.GameTicking.Presets [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IUplinkManager _uplinkManager = default!; public string PDAPrototypeName => "CaptainPDA"; public string BeltPrototypeName => "ClothingBeltJanitorFilled"; @@ -106,8 +104,10 @@ namespace Content.Server.GameTicking.Presets inventory.Equip(EquipmentSlotDefines.Slots.BACKPACK, newTmp.GetComponent()); // Like normal traitors, they need access to a traitor account. - var uplinkAccount = new UplinkAccount(mind.OwnedEntity.Uid, startingBalance); - _uplinkManager.AddNewAccount(uplinkAccount); + var uplinkAccount = new UplinkAccount(startingBalance, mind.OwnedEntity.Uid); + var accounts = _entityManager.EntitySysManager.GetEntitySystem(); + accounts.AddNewAccount(uplinkAccount); + _entityManager.EntitySysManager.GetEntitySystem() .AddUplink(mind.OwnedEntity, uplinkAccount, newPDA); diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index b14b399ced..b8df84bb02 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -16,7 +16,6 @@ using Content.Server.MoMMI; using Content.Server.NodeContainer.NodeGroups; using Content.Server.Objectives; using Content.Server.Objectives.Interfaces; -using Content.Server.PDA.Managers; using Content.Server.Preferences.Managers; using Content.Server.Sandbox; using Content.Server.Speech; @@ -42,7 +41,6 @@ namespace Content.Server.IoC IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); - IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Content.Server/PDA/PDASystem.cs b/Content.Server/PDA/PDASystem.cs index 499d682d6a..fd0dd4a8df 100644 --- a/Content.Server/PDA/PDASystem.cs +++ b/Content.Server/PDA/PDASystem.cs @@ -4,7 +4,6 @@ using Content.Server.Light.EntitySystems; using Content.Server.Light.Events; using Content.Server.Traitor.Uplink; using Content.Server.Traitor.Uplink.Components; -using Content.Server.Traitor.Uplink.Systems; using Content.Server.UserInterface; using Content.Shared.Containers.ItemSlots; using Content.Shared.Interaction; diff --git a/Content.Server/Traitor/Uplink/Account/UplinkAccountEvents.cs b/Content.Server/Traitor/Uplink/Account/UplinkAccountEvents.cs new file mode 100644 index 0000000000..f70fe809cd --- /dev/null +++ b/Content.Server/Traitor/Uplink/Account/UplinkAccountEvents.cs @@ -0,0 +1,31 @@ +using Content.Shared.Traitor.Uplink; +using Robust.Shared.GameObjects; + +namespace Content.Server.Traitor.Uplink.Account +{ + /// + /// Invokes when one of the UplinkAccounts changed its TC balance + /// + public class UplinkAccountBalanceChanged : EntityEventArgs + { + public readonly UplinkAccount Account; + + /// + /// Difference between NewBalance - OldBalance + /// + public readonly int Difference; + + public readonly int NewBalance; + public readonly int OldBalance; + + public UplinkAccountBalanceChanged(UplinkAccount account, int difference) + { + Account = account; + Difference = difference; + + NewBalance = account.Balance; + OldBalance = account.Balance - difference; + + } + } +} diff --git a/Content.Server/Traitor/Uplink/Account/UplinkAccountsSystem.cs b/Content.Server/Traitor/Uplink/Account/UplinkAccountsSystem.cs new file mode 100644 index 0000000000..4e451985f0 --- /dev/null +++ b/Content.Server/Traitor/Uplink/Account/UplinkAccountsSystem.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Content.Server.Mind.Components; +using Content.Shared.Traitor.Uplink; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Server.Traitor.Uplink.Account +{ + /// + /// Manage all registred uplink accounts and their balance + /// + public class UplinkAccountsSystem : EntitySystem + { + [Dependency] + private readonly UplinkListingSytem _listingSystem = default!; + + private readonly HashSet _accounts = new(); + + public bool AddNewAccount(UplinkAccount acc) + { + return _accounts.Add(acc); + } + + + /// + /// Add TC to uplinks account balance + /// + public bool AddToBalance(UplinkAccount account, int toAdd) + { + account.Balance += toAdd; + + RaiseLocalEvent(new UplinkAccountBalanceChanged(account, toAdd)); + return true; + } + + /// + /// Charge TC from uplinks account balance + /// + public bool RemoveFromBalance(UplinkAccount account, int price) + { + if (account.Balance - price < 0) + return false; + + account.Balance -= price; + + RaiseLocalEvent(new UplinkAccountBalanceChanged(account, -price)); + return true; + } + + /// + /// Force-set TC uplinks account balance to a new value + /// + public bool SetBalance(UplinkAccount account, int newBalance) + { + if (newBalance < 0) + return false; + + var dif = newBalance - account.Balance; + account.Balance = newBalance; + RaiseLocalEvent(new UplinkAccountBalanceChanged(account, dif)); + return true; + + } + + public bool TryPurchaseItem(UplinkAccount acc, string itemId, EntityCoordinates spawnCoords, [NotNullWhen(true)] out IEntity? purchasedItem) + { + purchasedItem = null; + + if (!_listingSystem.TryGetListing(itemId, out var listing)) + { + return false; + } + + if (acc.Balance < listing.Price) + { + return false; + } + + if (!RemoveFromBalance(acc, listing.Price)) + { + return false; + } + + purchasedItem = EntityManager.SpawnEntity(listing.ItemId, spawnCoords); + return true; + } + } +} diff --git a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs index 9af877e03b..104354d4aa 100644 --- a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs +++ b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs @@ -1,7 +1,5 @@ using Content.Server.Administration; -using Content.Server.PDA.Managers; -using Content.Server.Traitor.Uplink.Components; -using Content.Server.Traitor.Uplink.Systems; +using Content.Server.Traitor.Uplink.Account; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Traitor.Uplink; @@ -70,16 +68,9 @@ namespace Content.Server.Traitor.Uplink.Commands var tcCount = configManager.GetCVar(CCVars.TraitorStartingBalance); // Get account - var uplinkManager = IoCManager.Resolve(); - if (!uplinkManager.TryGetAccount(user.Uid, out UplinkAccount? uplinkAccount)) - { - uplinkAccount = new UplinkAccount(user.Uid, tcCount); - if (!uplinkManager.AddNewAccount(uplinkAccount)) - { - shell.WriteLine(Loc.GetString("Can't create new uplink account")); - return; - } - } + var uplinkAccount = new UplinkAccount(tcCount, user.Uid); + var accounts = entityManager.EntitySysManager.GetEntitySystem(); + accounts.AddNewAccount(uplinkAccount); // Finally add uplink if (!entityManager.EntitySysManager.GetEntitySystem() diff --git a/Content.Server/Traitor/Uplink/Managers/IUplinkManager.cs b/Content.Server/Traitor/Uplink/Managers/IUplinkManager.cs deleted file mode 100644 index ac3f75c932..0000000000 --- a/Content.Server/Traitor/Uplink/Managers/IUplinkManager.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Content.Shared.PDA; -using Content.Shared.Traitor.Uplink; -using Robust.Shared.GameObjects; -using Robust.Shared.Map; - -namespace Content.Server.PDA.Managers -{ - public interface IUplinkManager - { - public IReadOnlyDictionary FetchListings { get; } - - void Initialize(); - - public bool AddNewAccount(UplinkAccount acc); - - public bool ChangeBalance(UplinkAccount acc, int amt); - - public bool TryGetAccount(EntityUid owner, out UplinkAccount? acc); - - public bool TryPurchaseItem( - UplinkAccount? acc, - string itemId, - EntityCoordinates spawnCoords, - [NotNullWhen(true)] out IEntity? purchasedItem); - - } -} diff --git a/Content.Server/Traitor/Uplink/Managers/UplinkManager.cs b/Content.Server/Traitor/Uplink/Managers/UplinkManager.cs deleted file mode 100644 index 6ca7fc1b5a..0000000000 --- a/Content.Server/Traitor/Uplink/Managers/UplinkManager.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Content.Server.Mind.Components; -using Content.Shared.PDA; -using Content.Shared.Traitor.Uplink; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Prototypes; -using System.Linq; - -namespace Content.Server.PDA.Managers -{ - public class UplinkManager : IUplinkManager - { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; - - private readonly Dictionary _accounts = new(); - private readonly Dictionary _listings = new(); - - public IReadOnlyDictionary FetchListings => _listings; - - public void Initialize() - { - foreach (var item in _prototypeManager.EnumeratePrototypes()) - { - var newListing = new UplinkListingData(item.ListingName, item.ItemId, item.Price, item.Category, - item.Description); - - RegisterUplinkListing(newListing); - } - } - - private void RegisterUplinkListing(UplinkListingData listing) - { - if (!ContainsListing(listing)) - { - _listings.Add(listing.ItemId, listing); - } - } - - private bool ContainsListing(UplinkListingData listing) - { - return _listings.ContainsKey(listing.ItemId); - } - - public bool AddNewAccount(UplinkAccount acc) - { - var entity = _entityManager.GetEntity(acc.AccountHolder); - - if (entity.TryGetComponent(out MindComponent? mindComponent) && !mindComponent.HasMind) - { - return false; - } - - if (_accounts.ContainsKey(acc.AccountHolder)) - { - return false; - } - - _accounts.Add(acc.AccountHolder, acc); - return true; - } - - public bool TryGetAccount(EntityUid owner, out UplinkAccount? acc) - { - return _accounts.TryGetValue(owner, out acc); - } - - public bool ChangeBalance(UplinkAccount acc, int amt) - { - var account = _accounts.GetValueOrDefault(acc.AccountHolder); - - if (account == null) - { - return false; - } - - if (account.Balance + amt < 0) - { - return false; - } - - account.ModifyAccountBalance(account.Balance + amt); - - return true; - } - - public bool TryPurchaseItem(UplinkAccount? acc, string itemId, EntityCoordinates spawnCoords, [NotNullWhen(true)] out IEntity? purchasedItem) - { - purchasedItem = null; - if (acc == null) - { - return false; - } - - if (!_listings.TryGetValue(itemId, out var listing)) - { - return false; - } - - if (acc.Balance < listing.Price) - { - return false; - } - - if (!ChangeBalance(acc, -listing.Price)) - { - return false; - } - - purchasedItem = _entityManager.SpawnEntity(listing.ItemId, spawnCoords); - return true; - } - } -} diff --git a/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalComponent.cs b/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalComponent.cs new file mode 100644 index 0000000000..ec0e3befe6 --- /dev/null +++ b/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameObjects; + +namespace Content.Server.Traitor.Uplink.Telecrystal +{ + [RegisterComponent] + public class TelecrystalComponent : Component + { + public override string Name => "Telecrystal"; + } +} diff --git a/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalSystem.cs b/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalSystem.cs new file mode 100644 index 0000000000..64071fa6b6 --- /dev/null +++ b/Content.Server/Traitor/Uplink/Telecrystal/TelecrystalSystem.cs @@ -0,0 +1,55 @@ +using Content.Server.Traitor.Uplink.Account; +using Content.Server.Traitor.Uplink.Components; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Stacks; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using System; + +namespace Content.Server.Traitor.Uplink.Telecrystal +{ + public class TelecrystalSystem : EntitySystem + { + [Dependency] + private readonly UplinkAccountsSystem _accounts = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAfterInteract); + } + + private void OnAfterInteract(EntityUid uid, TelecrystalComponent component, AfterInteractEvent args) + { + if (args.Handled) + return; + + if (args.Target == null || !EntityManager.TryGetComponent(args.Target.Uid, out UplinkComponent? uplink)) + return; + + // TODO: when uplink will have some auth logic (like PDA ringtone code) + // check if uplink open before adding TC + // No metagaming by using this on every PDA around just to see if it gets used up. + + var acc = uplink.UplinkAccount; + if (acc == null) + return; + + EntityManager.TryGetComponent(uid, out SharedStackComponent? stack); + + var tcCount = stack != null ? stack.Count : 1; + if (!_accounts.AddToBalance(acc, tcCount)) + return; + + EntityManager.DeleteEntity(uid); + + var msg = Loc.GetString("telecrystal-component-sucs-inserted", + ("source", args.Used), ("target", args.Target)); + args.User.PopupMessage(args.User, msg); + + args.Handled = true; + } + } +} diff --git a/Content.Server/Traitor/Uplink/UplinkListingSytem.cs b/Content.Server/Traitor/Uplink/UplinkListingSytem.cs new file mode 100644 index 0000000000..2c81693eea --- /dev/null +++ b/Content.Server/Traitor/Uplink/UplinkListingSytem.cs @@ -0,0 +1,56 @@ +using Content.Shared.PDA; +using Content.Shared.Traitor.Uplink; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Content.Server.Traitor.Uplink +{ + /// + /// Contains and controls all items in traitors uplink shop + /// + public class UplinkListingSytem : EntitySystem + { + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + private readonly Dictionary _listings = new(); + + public override void Initialize() + { + base.Initialize(); + + foreach (var item in _prototypeManager.EnumeratePrototypes()) + { + var newListing = new UplinkListingData(item.ListingName, item.ItemId, + item.Price, item.Category, item.Description); + + RegisterUplinkListing(newListing); + } + } + + private void RegisterUplinkListing(UplinkListingData listing) + { + if (!ContainsListing(listing)) + { + _listings.Add(listing.ItemId, listing); + } + } + + public bool ContainsListing(UplinkListingData listing) + { + return _listings.ContainsKey(listing.ItemId); + } + + public bool TryGetListing(string itemID, [NotNullWhen(true)] out UplinkListingData? data) + { + return _listings.TryGetValue(itemID, out data); + } + + public IReadOnlyDictionary GetListings() + { + return _listings; + } + } +} diff --git a/Content.Server/Traitor/Uplink/UplinkSystem.cs b/Content.Server/Traitor/Uplink/UplinkSystem.cs index 370a58d9a4..c0e028cc2a 100644 --- a/Content.Server/Traitor/Uplink/UplinkSystem.cs +++ b/Content.Server/Traitor/Uplink/UplinkSystem.cs @@ -2,7 +2,7 @@ using Content.Server.Hands.Components; using Content.Server.Inventory.Components; using Content.Server.Items; using Content.Server.PDA; -using Content.Server.PDA.Managers; +using Content.Server.Traitor.Uplink.Account; using Content.Server.Traitor.Uplink.Components; using Content.Server.UserInterface; using Content.Shared.Traitor.Uplink; @@ -16,11 +16,14 @@ using Robust.Shared.Player; using System; using System.Linq; -namespace Content.Server.Traitor.Uplink.Systems +namespace Content.Server.Traitor.Uplink { public class UplinkSystem : EntitySystem { - [Dependency] private readonly IUplinkManager _uplinkManager = default!; + [Dependency] + private readonly UplinkAccountsSystem _accounts = default!; + [Dependency] + private readonly UplinkListingSytem _listing = default!; public override void Initialize() { @@ -28,6 +31,10 @@ namespace Content.Server.Traitor.Uplink.Systems SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnBuy); + SubscribeLocalEvent(OnRequestUpdateUI); + + SubscribeLocalEvent(OnBalanceChangedBroadcast); } public void SetAccount(UplinkComponent component, UplinkAccount account) @@ -39,19 +46,10 @@ namespace Content.Server.Traitor.Uplink.Systems } component.UplinkAccount = account; - component.UplinkAccount.BalanceChanged += (acc) => - { - UpdateUserInterface(component); - }; - } private void OnInit(EntityUid uid, UplinkComponent component, ComponentInit args) { - var ui = component.Owner.GetUIOrNull(UplinkUiKey.Key); - if (ui != null) - ui.OnReceiveMessage += (msg) => OnUIMessage(component, msg); - RaiseLocalEvent(uid, new UplinkInitEvent(component)); } @@ -60,6 +58,49 @@ namespace Content.Server.Traitor.Uplink.Systems RaiseLocalEvent(uid, new UplinkRemovedEvent()); } + private void OnBalanceChangedBroadcast(UplinkAccountBalanceChanged ev) + { + foreach (var uplink in EntityManager.EntityQuery()) + { + if (uplink.UplinkAccount == ev.Account) + { + UpdateUserInterface(uplink); + } + } + } + + private void OnRequestUpdateUI(EntityUid uid, UplinkComponent uplink, UplinkRequestUpdateInterfaceMessage args) + { + UpdateUserInterface(uplink); + } + + private void OnBuy(EntityUid uid, UplinkComponent uplink, UplinkBuyListingMessage message) + { + var player = message.Session.AttachedEntity; + if (player == null) return; + if (uplink.UplinkAccount == null) return; + + if (!_accounts.TryPurchaseItem(uplink.UplinkAccount, message.ItemId, + player.Transform.Coordinates, out var entity)) + { + SoundSystem.Play(Filter.SinglePlayer(message.Session), uplink.InsufficientFundsSound.GetSound(), + uplink.Owner, AudioParams.Default); + RaiseNetworkEvent(new UplinkInsufficientFundsMessage(), message.Session.ConnectedClient); + return; + } + + if (player.TryGetComponent(out HandsComponent? hands) && + entity.TryGetComponent(out ItemComponent? item)) + { + hands.PutInHandOrDrop(item); + } + + SoundSystem.Play(Filter.SinglePlayer(message.Session), uplink.BuySuccessSound.GetSound(), + uplink.Owner, AudioParams.Default.WithVolume(-2f)); + + RaiseNetworkEvent(new UplinkBuySuccessMessage(), message.Session.ConnectedClient); + } + public void ToggleUplinkUI(UplinkComponent component, IPlayerSession session) { var ui = component.Owner.GetUIOrNull(UplinkUiKey.Key); @@ -68,50 +109,13 @@ namespace Content.Server.Traitor.Uplink.Systems UpdateUserInterface(component); } - private void OnUIMessage(UplinkComponent uplink, ServerBoundUserInterfaceMessage message) - { - switch (message.Message) - { - case UplinkRequestUpdateInterfaceMessage _: - UpdateUserInterface(uplink); - break; - case UplinkBuyListingMessage buyMsg: - { - var player = message.Session.AttachedEntity; - if (player == null) break; - - if (!_uplinkManager.TryPurchaseItem(uplink.UplinkAccount, buyMsg.ItemId, - player.Transform.Coordinates, out var entity)) - { - SoundSystem.Play(Filter.SinglePlayer(message.Session), uplink.InsufficientFundsSound.GetSound(), - uplink.Owner, AudioParams.Default); - RaiseNetworkEvent(new UplinkInsufficientFundsMessage(), message.Session.ConnectedClient); - break; - } - - if (player.TryGetComponent(out HandsComponent? hands) && - entity.TryGetComponent(out ItemComponent? item)) - { - hands.PutInHandOrDrop(item); - } - - SoundSystem.Play(Filter.SinglePlayer(message.Session), uplink.BuySuccessSound.GetSound(), - uplink.Owner, AudioParams.Default.WithVolume(-2f)); - - RaiseNetworkEvent(new UplinkBuySuccessMessage(), message.Session.ConnectedClient); - break; - } - - } - } - private void UpdateUserInterface(UplinkComponent component) { var ui = component.Owner.GetUIOrNull(UplinkUiKey.Key); if (ui == null) return; - var listings = _uplinkManager.FetchListings.Values.ToArray(); + var listings = _listing.GetListings().Values.ToArray(); var acc = component.UplinkAccount; UplinkAccountData accData; diff --git a/Content.Server/TraitorDeathMatch/Components/TraitorDeathMatchRedemptionComponent.cs b/Content.Server/TraitorDeathMatch/Components/TraitorDeathMatchRedemptionComponent.cs index ccba9cd317..42ec6f3b24 100644 --- a/Content.Server/TraitorDeathMatch/Components/TraitorDeathMatchRedemptionComponent.cs +++ b/Content.Server/TraitorDeathMatch/Components/TraitorDeathMatchRedemptionComponent.cs @@ -2,11 +2,13 @@ using System.Threading.Tasks; using Content.Server.Inventory.Components; using Content.Server.Mind.Components; using Content.Server.PDA; +using Content.Server.Traitor.Uplink.Account; using Content.Server.Traitor.Uplink.Components; using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Popups; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; using Robust.Shared.Localization; namespace Content.Server.TraitorDeathMatch.Components @@ -104,9 +106,10 @@ namespace Content.Server.TraitorDeathMatch.Components } // 4 is the per-PDA bonus amount. + var accounts = Owner.EntityManager.EntitySysManager.GetEntitySystem(); var transferAmount = victimAccount.Balance + 4; - victimAccount.ModifyAccountBalance(0); - userAccount.ModifyAccountBalance(userAccount.Balance + transferAmount); + accounts.SetBalance(victimAccount, 0); + accounts.AddToBalance(userAccount, transferAmount); victimUplink.Owner.Delete(); diff --git a/Content.Shared/Traitor/Uplink/UplinkAccount.cs b/Content.Shared/Traitor/Uplink/UplinkAccount.cs index a4dddd836a..5d37820d38 100644 --- a/Content.Shared/Traitor/Uplink/UplinkAccount.cs +++ b/Content.Shared/Traitor/Uplink/UplinkAccount.cs @@ -1,32 +1,16 @@ using Robust.Shared.GameObjects; -using Robust.Shared.ViewVariables; -using System; namespace Content.Shared.Traitor.Uplink { public class UplinkAccount { - public event Action? BalanceChanged; - public EntityUid AccountHolder; - private int _balance; - [ViewVariables] - public int Balance => _balance; + public readonly EntityUid? AccountHolder; + public int Balance; - public UplinkAccount(EntityUid uid, int startingBalance) + public UplinkAccount(int startingBalance, EntityUid? accountHolder = null) { - AccountHolder = uid; - _balance = startingBalance; - } - - public bool ModifyAccountBalance(int newBalance) - { - if (newBalance < 0) - { - return false; - } - _balance = newBalance; - BalanceChanged?.Invoke(this); - return true; + AccountHolder = accountHolder; + Balance = startingBalance; } } } diff --git a/Content.Shared/Traitor/Uplink/UplinkListingData.cs b/Content.Shared/Traitor/Uplink/UplinkListingData.cs index 828a3750d1..5fa160125e 100644 --- a/Content.Shared/Traitor/Uplink/UplinkListingData.cs +++ b/Content.Shared/Traitor/Uplink/UplinkListingData.cs @@ -8,11 +8,11 @@ namespace Content.Shared.Traitor.Uplink [Serializable, NetSerializable] public class UplinkListingData : ComponentState, IEquatable { - public string ItemId; - public int Price; - public UplinkCategory Category; - public string Description; - public string ListingName; + public readonly string ItemId; + public readonly int Price; + public readonly UplinkCategory Category; + public readonly string Description; + public readonly string ListingName; public UplinkListingData(string listingName, string itemId, int price, UplinkCategory category, diff --git a/Resources/Locale/en-US/traitor/uplink/telecrystal-component.ftl b/Resources/Locale/en-US/traitor/uplink/telecrystal-component.ftl new file mode 100644 index 0000000000..2ee710d7b7 --- /dev/null +++ b/Resources/Locale/en-US/traitor/uplink/telecrystal-component.ftl @@ -0,0 +1 @@ +telecrystal-component-sucs-inserted = You slot {$source} into the {$target}. \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 8f93a109d3..5a16248905 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -217,11 +217,33 @@ itemId: lanternextrabright price: 2 -#- type: uplinkListing -# id: UplinkTelecrystal -# category: Misc -# itemId: Telecrystal -# price: 1 +- type: uplinkListing + id: UplinkTelecrystal + category: Misc + itemId: Telecrystal1 + price: 1 + listingName: telecrystal [1] + +- type: uplinkListing + id: UplinkTelecrystal5 + category: Misc + itemId: Telecrystal5 + price: 5 + listingName: telecrystal [5] + +- type: uplinkListing + id: UplinkTelecrystal10 + category: Misc + itemId: Telecrystal10 + price: 10 + listingName: telecrystal [10] + +- type: uplinkListing + id: UplinkTelecrystal20 + category: Misc + itemId: Telecrystal + price: 20 + listingName: telecrystal [20] # Pointless diff --git a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml new file mode 100644 index 0000000000..1738695b6f --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml @@ -0,0 +1,42 @@ +- type: entity + name: telecrystal + parent: BaseItem + id: Telecrystal + suffix: Twenty + description: It seems to be pulsing with suspiciously enticing energies. + components: + - type: Sprite + sprite: Objects/Specific/Syndicate/telecrystal.rsi + netsync: false + state: telecrystal + - type: Item + sprite: Objects/Specific/Syndicate/telecrystal.rsi + - type: Stack + count: 20 + max: 20 + stackType: Telecrystal + - type: Telecrystal + +- type: entity + parent: Telecrystal + id: Telecrystal1 + suffix: Single + components: + - type: Stack + count: 1 + +- type: entity + parent: Telecrystal + id: Telecrystal5 + suffix: Five + components: + - type: Stack + count: 5 + +- type: entity + parent: Telecrystal + id: Telecrystal10 + suffix: Ten + components: + - type: Stack + count: 10 diff --git a/Resources/Prototypes/Stacks/Materials/crystals.yml b/Resources/Prototypes/Stacks/Materials/crystals.yml new file mode 100644 index 0000000000..28f4ed70ca --- /dev/null +++ b/Resources/Prototypes/Stacks/Materials/crystals.yml @@ -0,0 +1,5 @@ +- type: stack + id: Telecrystal + name: telecrystal + icon: Objects/Specific/Syndicate/telecrystal.rsi + spawn: Telecrystal1 diff --git a/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-left.png new file mode 100644 index 0000000000..a7ef2bbf4d Binary files /dev/null and b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-right.png b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-right.png new file mode 100644 index 0000000000..0c1ae48d02 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/meta.json b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/meta.json new file mode 100644 index 0000000000..0ec31e402a --- /dev/null +++ b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/f8f4aeda930fcd0805ca4cc76d9bc9412a5b3428", + "states": [ + { + "name": "telecrystal" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/telecrystal.png b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/telecrystal.png new file mode 100644 index 0000000000..cf7be5b549 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Syndicate/telecrystal.rsi/telecrystal.png differ