diff --git a/Content.Server/_Forge/SoulContractSystem/SoulContractSystem.cs b/Content.Server/_Forge/SoulContractSystem/SoulContractSystem.cs new file mode 100644 index 000000000000..c298c4e3d04a --- /dev/null +++ b/Content.Server/_Forge/SoulContractSystem/SoulContractSystem.cs @@ -0,0 +1,68 @@ +using Content.Server._NF.Bank; +using Content.Server.Store.Components; +using Content.Shared._Forge.SoulContract; +using Content.Shared.Body.Systems; +using Content.Shared.DoAfter; +using Content.Shared.Gibbing.Systems; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Storage; +using static Content.Server.Power.Pow3r.PowerState; + +namespace Content.Server._Forge.SoulContractSystem +{ + public sealed class SoulContractSystem : EntitySystem + { + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly BankSystem _bank = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly SharedBodySystem _bodySystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnDoAfter); + } + + private void OnUseInHand(Entity entity, ref UseInHandEvent args) + { + var (uid, soulContract) = entity; + + var user = args.User; + + var doAfterArgs = new DoAfterArgs(EntityManager, + user, + soulContract.UseTime, + new SoulContractDoAfterEvent(), + eventTarget: uid) + { + BreakOnHandChange = false, + BreakOnMove = true, + BreakOnDamage = true, + MovementThreshold = 0.01f, + DistanceThreshold = 5, + NeedHand = true + }; + + _doAfterSystem.TryStartDoAfter(doAfterArgs); + } + + private void OnDoAfter(Entity entity, ref SoulContractDoAfterEvent args) + { + if (args.Cancelled) + return; + + Del(entity.Owner); + args.Handled = _bank.TryBankDeposit(args.Args.User, entity.Comp.Reward, true) && TryGib(entity, args.Args.User); + } + + private bool TryGib(Entity entity, EntityUid user) + { + var gibHashSet = _bodySystem.GibBody(user); + + return gibHashSet.Count > 0; + } + } +} diff --git a/Content.Server/_NF/Bank/BankSystem.cs b/Content.Server/_NF/Bank/BankSystem.cs index 6746b9de6f21..f8489051e33b 100644 --- a/Content.Server/_NF/Bank/BankSystem.cs +++ b/Content.Server/_NF/Bank/BankSystem.cs @@ -8,6 +8,8 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared._NF.Bank.Events; using Content.Shared.GameTicking; +using Robust.Shared.Network; +using System.Linq; namespace Content.Server._NF.Bank; @@ -102,7 +104,7 @@ public bool TryBankWithdraw(EntityUid mobUid, int amount) /// The UID that the bank account is connected to, typically the player controlled mob /// The amount of spesos to remove from the bank account /// true if the transaction was successful, false if it was not - public bool TryBankDeposit(EntityUid mobUid, int amount) + public bool TryBankDeposit(EntityUid mobUid, int amount, bool sendToRandomCharacter = false) { if (amount <= 0) { @@ -127,8 +129,21 @@ public bool TryBankDeposit(EntityUid mobUid, int amount) _log.Info($"TryBankDeposit: {mobUid} has no cached prefs"); return false; } + // Forge-SoulContract + // Forge-SoulContract-start + var profile = prefs.SelectedCharacter as HumanoidCharacterProfile; - if (prefs.SelectedCharacter is not HumanoidCharacterProfile profile) + if (sendToRandomCharacter) + { + Random rnd = new Random(); + int randomInt = rnd.Next(prefs.Characters.Count); + var randomProfile = (HumanoidCharacterProfile)prefs.Characters.ToList()[randomInt].Value; + + profile = randomProfile; + } + + if (profile is null) + // Forge-SoulContract-end { _log.Info($"TryBankDeposit: {mobUid} has the wrong prefs type"); return false; diff --git a/Content.Shared/_Forge/SoulContract/SoulContractComponent.cs b/Content.Shared/_Forge/SoulContract/SoulContractComponent.cs new file mode 100644 index 000000000000..34e30934d636 --- /dev/null +++ b/Content.Shared/_Forge/SoulContract/SoulContractComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Content.Shared._Forge.SoulContract +{ + [RegisterComponent] + public sealed partial class SoulContractComponent: Component + { + [DataField] + public int Reward; + + [DataField] + public TimeSpan UseTime = TimeSpan.FromSeconds(5); + } + + [Serializable, NetSerializable] + public sealed partial class SoulContractDoAfterEvent : SimpleDoAfterEvent + { + } +} diff --git a/Content.Shared/_Forge/SoulContract/SoulContractDoAfterEvent.cs b/Content.Shared/_Forge/SoulContract/SoulContractDoAfterEvent.cs new file mode 100644 index 000000000000..b87ea3e2c519 --- /dev/null +++ b/Content.Shared/_Forge/SoulContract/SoulContractDoAfterEvent.cs @@ -0,0 +1,15 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Content.Server._Forge.SoulContractSystem +{ + [Serializable, NetSerializable] + public sealed partial class SoulContractDoAfterEvent: SimpleDoAfterEvent + { + } +} diff --git a/Resources/Prototypes/_Forge/SoulContract/soul_contract.yml b/Resources/Prototypes/_Forge/SoulContract/soul_contract.yml new file mode 100644 index 000000000000..506d1c79fcf2 --- /dev/null +++ b/Resources/Prototypes/_Forge/SoulContract/soul_contract.yml @@ -0,0 +1,11 @@ +- type: entity + name: soul contract + parent: BaseItem + id: SoulContract + description: На станции, даже ваша душа имеет цену + components: + - type: Sprite + sprite: Objects/Fun/Bikehorn.rsi + state: icon + - type: SoulContract + reward: 100000