diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs index 645cef8195..87ec860cb6 100644 --- a/Content.Client/IgnoredComponents.cs +++ b/Content.Client/IgnoredComponents.cs @@ -28,6 +28,7 @@ "Wrench", "Crowbar", "MeleeWeapon", + "MeleeChemicalInjector", "Dice", "Construction", "Door", diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeChemicalInjectorComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeChemicalInjectorComponent.cs new file mode 100644 index 0000000000..93770f40a1 --- /dev/null +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeChemicalInjectorComponent.cs @@ -0,0 +1,71 @@ +using Content.Server.GameObjects.Components.Body.Circulatory; +using Content.Server.GameObjects.Components.Chemistry; +using Content.Shared.Chemistry; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Content.Server.GameObjects.Components.Weapon.Melee +{ + [RegisterComponent] + public class MeleeChemicalInjectorComponent : Component + { + public override string Name => "MeleeChemicalInjector"; + + [ViewVariables(VVAccess.ReadWrite)] + public ReagentUnit TransferAmount { get; set; } + + [ViewVariables(VVAccess.ReadWrite)] + public float TransferEfficiency { get => _transferEfficiency; set => _transferEfficiency = Math.Clamp(value, 0, 1); } + private float _transferEfficiency; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + serializer.DataField(this, x => x.TransferAmount, "transferAmount", ReagentUnit.New(1)); + serializer.DataField(ref _transferEfficiency, "transferEfficiency", 1f); + } + + public override void HandleMessage(ComponentMessage message, IComponent component) + { + base.HandleMessage(message, component); + switch (message) + { + case MeleeHitMessage meleeHit: + InjectEntities(meleeHit.HitEntities); + break; + } + } + + private void InjectEntities(List hitEntities) + { + if (!Owner.TryGetComponent(out var solutionContainer)) + return; + + var hitBloodstreams = new List(); + foreach (var entity in hitEntities) + { + if (entity.TryGetComponent(out var bloodstream)) + hitBloodstreams.Add(bloodstream); + } + + if (!hitBloodstreams.Any()) + return; + + var removedSolution = solutionContainer.Solution.SplitSolution(TransferAmount * hitBloodstreams.Count); + var removedVol = removedSolution.TotalVolume; + var solutionToInject = removedSolution.SplitSolution(removedVol * TransferEfficiency); + var volPerBloodstream = solutionToInject.TotalVolume * (1 / hitBloodstreams.Count); + + foreach (var bloodstream in hitBloodstreams) + { + var individualInjection = solutionToInject.SplitSolution(volPerBloodstream); + bloodstream.TryTransferSolution(individualInjection); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index cd9e7c0edb..7630debec0 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -83,7 +83,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee var curTime = _gameTiming.CurTime; - if(curTime < _cooldownEnd) + if (curTime < _cooldownEnd) return true; var location = eventArgs.User.Transform.Coordinates; @@ -95,7 +95,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee var audioSystem = EntitySystem.Get(); if (entities.Count != 0) { - audioSystem.PlayFromEntity( _hitSound, entities.First()); + audioSystem.PlayFromEntity(_hitSound, entities.First()); } else { @@ -114,8 +114,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee hitEntities.Add(entity); } } + SendMessage(new MeleeHitMessage(hitEntities)); - if(!OnHitEntities(hitEntities, eventArgs)) return false; + if (!OnHitEntities(hitEntities, eventArgs)) return false; if (Arc != null) { @@ -141,7 +142,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee var curTime = _gameTiming.CurTime; - if(curTime < _cooldownEnd || !eventArgs.Target.IsValid()) + if (curTime < _cooldownEnd || !eventArgs.Target.IsValid()) return true; var target = eventArgs.TargetEntity; @@ -152,7 +153,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee var audioSystem = EntitySystem.Get(); if (target != null) { - audioSystem.PlayFromEntity( _hitSound, target); + audioSystem.PlayFromEntity(_hitSound, target); } else { @@ -164,8 +165,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee { damageComponent.ChangeDamage(DamageType, Damage, false, Owner); } + SendMessage(new MeleeHitMessage(new List { target })); - var targets = new[] {target}; + var targets = new[] { target }; if (!OnHitEntities(targets, eventArgs)) return false; @@ -211,4 +213,14 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee return resSet; } } + + public class MeleeHitMessage : ComponentMessage + { + public readonly List HitEntities; + + public MeleeHitMessage(List hitEntities) + { + HitEntities = hitEntities; + } + } } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 2d28bc0889..f4b358ccb2 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity name: spear parent: BaseItem id: Spear @@ -7,22 +7,23 @@ - type: Sprite sprite: Objects/Weapons/Melee/spear.rsi state: spear - - type: MeleeWeapon range: 1.5 arcwidth: 0 arc: spear - - type: Item size: 24 sprite: Objects/Weapons/Melee/spear.rsi prefix: inhand - - type: Construction graph: spear node: spear - - type: ItemCooldown + - type: MeleeChemicalInjector + - type: SolutionContainer + maxVol: 5 + caps: AddTo, RemoveFrom + - type: Pourable - type: MeleeWeaponAnimation id: spear