Skip to content

Commit

Permalink
[Port] Snatchprod / Хваталка (#65)
Browse files Browse the repository at this point in the history
* add: snatcherprod

* fix

* Update StunbatonSystem.cs
  • Loading branch information
Spatison authored Sep 27, 2024
1 parent f3dd435 commit ceea215
Show file tree
Hide file tree
Showing 24 changed files with 380 additions and 78 deletions.
69 changes: 59 additions & 10 deletions Content.Server/Stunnable/Systems/StunbatonSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Power.Events;
Expand All @@ -9,7 +10,9 @@
using Content.Shared.Item.ItemToggle;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Popups;
using Content.Shared.PowerCell.Components;
using Content.Shared.Stunnable;
using Robust.Shared.Containers;

namespace Content.Server.Stunnable.Systems
{
Expand All @@ -20,6 +23,7 @@ public sealed class StunbatonSystem : SharedStunbatonSystem
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly SharedItemToggleSystem _itemToggle = default!;
[Dependency] private readonly SharedContainerSystem _containers = default!; // WD EDIT

public override void Initialize()
{
Expand All @@ -31,15 +35,17 @@ public override void Initialize()
SubscribeLocalEvent<StunbatonComponent, ItemToggleActivateAttemptEvent>(TryTurnOn);
SubscribeLocalEvent<StunbatonComponent, ItemToggledEvent>(ToggleDone);
SubscribeLocalEvent<StunbatonComponent, ChargeChangedEvent>(OnChargeChanged);
SubscribeLocalEvent<StunbatonComponent, PowerCellChangedEvent>(OnPowerCellChanged); // WD EDIT
}

private void OnStaminaHitAttempt(Entity<StunbatonComponent> entity, ref StaminaDamageOnHitAttemptEvent args)
{
if (!_itemToggle.IsActivated(entity.Owner) ||
!TryComp<BatteryComponent>(entity.Owner, out var battery) || !_battery.TryUseCharge(entity.Owner, entity.Comp.EnergyPerUse, battery))
{
// WD EDIT START
if (!_itemToggle.IsActivated(entity.Owner)
|| !TryGetBatteryComponent(entity, out var battery, out var batteryUid)
|| !_battery.TryUseCharge(batteryUid.Value, entity.Comp.EnergyPerUse, battery))
args.Cancelled = true;
}
// WD EDIT END
}

private void OnExamined(Entity<StunbatonComponent> entity, ref ExaminedEvent args)
Expand All @@ -49,7 +55,7 @@ private void OnExamined(Entity<StunbatonComponent> entity, ref ExaminedEvent arg
: Loc.GetString("comp-stunbaton-examined-off");
args.PushMarkup(onMsg);

if (TryComp<BatteryComponent>(entity.Owner, out var battery))
if (TryGetBatteryComponent(entity, out var battery, out _)) // WD EDIT
{
var count = (int) (battery.CurrentCharge / entity.Comp.EnergyPerUse);
args.PushMarkup(Loc.GetString("melee-battery-examine", ("color", "yellow"), ("count", count)));
Expand All @@ -63,15 +69,22 @@ private void ToggleDone(Entity<StunbatonComponent> entity, ref ItemToggledEvent

private void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
{
if (!TryComp<BatteryComponent>(entity, out var battery) || battery.CurrentCharge < entity.Comp.EnergyPerUse)
// WD EDIT START
if (!TryGetBatteryComponent(entity, out var battery, out _)
|| battery.CurrentCharge < entity.Comp.EnergyPerUse)
{

args.Cancelled = true;

if (args.User != null)
{
_popup.PopupEntity(Loc.GetString("stunbaton-component-low-charge"), (EntityUid) args.User, (EntityUid) args.User);
_popup.PopupEntity(Loc.GetString("stunbaton-component-low-charge"), (EntityUid) args.User,
(EntityUid) args.User);
}

return;
}
// WD EDIT END

if (TryComp<RiggableComponent>(entity, out var rig) && rig.IsRigged)
{
Expand Down Expand Up @@ -102,11 +115,47 @@ private void SendPowerPulse(EntityUid target, EntityUid? user, EntityUid used)

private void OnChargeChanged(Entity<StunbatonComponent> entity, ref ChargeChangedEvent args)
{
if (TryComp<BatteryComponent>(entity.Owner, out var battery) &&
battery.CurrentCharge < entity.Comp.EnergyPerUse)
{
CheckCharge(entity); // WD EDIT
}

// WD EDIT START
private void OnPowerCellChanged(Entity<StunbatonComponent> entity, ref PowerCellChangedEvent args)
{
CheckCharge(entity);
}

private void CheckCharge(Entity<StunbatonComponent> entity)
{
if (!TryGetBatteryComponent(entity, out var battery, out _)
|| battery.CurrentCharge < entity.Comp.EnergyPerUse)
_itemToggle.TryDeactivate(entity.Owner, predicted: false);
}

private bool TryGetBatteryComponent(EntityUid uid, [NotNullWhen(true)] out BatteryComponent? battery,
[NotNullWhen(true)] out EntityUid? batteryUid)
{
if (TryComp(uid, out battery))
{
batteryUid = uid;
return true;
}

if (!_containers.TryGetContainer(uid, "cell_slot", out var container)
|| container is not ContainerSlot slot)
{
battery = null;
batteryUid = null;
return false;
}

batteryUid = slot.ContainedEntity;

if (batteryUid != null)
return TryComp(batteryUid, out battery);

battery = null;
return false;
}
// WD EDIT END
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Server._White.Melee.Snatch;

[RegisterComponent]
public sealed partial class SnatchOnMeleeHitComponent : Component;
40 changes: 40 additions & 0 deletions Content.Server/_White/Melee/Snatch/SnatchOnMeleeHitSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Linq;
using Content.Server.Hands.Systems;
using Content.Server.Item;
using Content.Shared.Hands.Components;
using Content.Shared.Weapons.Melee.Events;

namespace Content.Server._White.Melee.Snatch;

public sealed class SnatchOnMeleeHitSystem : EntitySystem
{
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly ItemToggleSystem _itemToggle = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SnatchOnMeleeHitComponent, MeleeHitEvent>(OnHit);
}

private void OnHit(EntityUid uid, SnatchOnMeleeHitComponent component, MeleeHitEvent args)
{
if (!_itemToggle.IsActivated(uid) || args.HitEntities.Count == 0)
return;

var entity = args.HitEntities.First();

if (entity == uid || !TryComp(entity, out HandsComponent? hands))
return;

foreach (var heldEntity in _hands.EnumerateHeld(entity, hands))
{
if (!_hands.TryDrop(entity, heldEntity, null, false, false, hands))
continue;

_hands.PickupOrDrop(args.User, heldEntity, false);
break;
}
}
}
7 changes: 4 additions & 3 deletions Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
startBreakoutSound:
path: /Audio/Items/Handcuffs/rope_takeoff.ogg
uncuffEasierWhenLarge: true
- type: Construction
graph: makeshifthandcuffs
node: cuffscable
- type: Construction # WD EDIT
deconstructionTarget: cuffs
graph: StunprodGraph
node: cuffs
- type: Item
inhandVisuals:
left:
Expand Down
87 changes: 68 additions & 19 deletions Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
- type: entity
name: stun prod
parent: BaseItem
id: Stunprod
description: A stun prod for illegal incapacitation.
id: StunprodBase # WD EDIT
abstract: true
noSpawn: true
components:
- type: Sprite
sprite: Objects/Weapons/Melee/stunprod.rsi
layers:
- state: stunprod_off
map: [ "enum.ToggleVisuals.Layer" ]
- type: ItemToggle
soundActivate:
collection: sparks
Expand Down Expand Up @@ -48,29 +44,82 @@
- type: StaminaDamageOnCollide
damage: 22
sound: /Audio/Weapons/egloves.ogg
- type: Battery
maxCharge: 360
startingCharge: 360
- type: UseDelay
- type: Item
heldPrefix: off
size: Normal
shape: # WD EDIT
- 0,0,2,0
- type: DisarmMalus
malus: 0.225
- type: Appearance
- type: StaticPrice
price: 100
# WD EDIT START
- type: PowerCellSlot
cellSlotId: cell_slot
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
- type: ContainerContainer
containers:
cell_slot: !type:ContainerSlot {}

- type: entity
name: stun prod
parent: StunprodBase
id: Stunprod
description: A stun prod for illegal incapacitation.
components:
- type: Sprite
sprite: Objects/Weapons/Melee/stunprod.rsi
layers:
- state: stunprod
- state: stunprod_on
visible: false
map: [ "enum.ToggleVisuals.Layer" ]
- state: stunprod_cell
visible: false
map: [ "enum.PowerDeviceVisualLayers.Powered" ]
- type: Item
sprite: Objects/Weapons/Melee/stunprod.rsi
- type: Clothing
sprite: Objects/Weapons/Melee/stunprod.rsi
quickEquip: false
slots:
- back
- type: DisarmMalus
malus: 0.225
- type: Appearance
- type: GenericVisualizer
visuals:
enum.ToggleVisuals.Toggled:
enum.ToggleVisuals.Layer:
True: {state: stunprod_on}
False: {state: stunprod_off}
- type: StaticPrice
price: 100
True: {visible: true}
False: {visible: false}
enum.PowerCellSlotVisuals.Enabled:
enum.PowerDeviceVisualLayers.Powered:
True: {visible: true}
False: {visible: false}
- type: Construction
deconstructionTarget: cuffs
graph: StunprodGraph
node: stunprod

- type: entity
parent: BaseItem
id: ProdUnfinished
name: wound rod
description: A rod with wires.
components:
- type: Sprite
sprite: _White/Objects/Weapons/Melee/prod.rsi
state: prod_unfinished
- type: Item
size: Small
shape:
- 0,0,1,0
storedRotation: 44
- type: Construction
graph: makeshiftstunprod
node: msstunprod
deconstructionTarget: cuffs
graph: StunprodGraph
node: unfinished
# WD EDIT END

This file was deleted.

11 changes: 0 additions & 11 deletions Resources/Prototypes/Recipes/Crafting/improvised.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,6 @@
icon: { sprite: Objects/Misc/cablecuffs.rsi, state: cuff }
objectType: Item

- type: construction
name: makeshift stunprod
id: makeshiftstunprod
graph: makeshiftstunprod
startNode: start
targetNode: msstunprod
category: construction-category-weapons
description: "Homemade stunprod."
icon: { sprite: Objects/Weapons/Melee/stunprod.rsi, state: stunprod_off }
objectType: Item

- type: construction
name: muzzle
id: muzzle
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
- type: entity
parent: StunprodBase
id: Snatcherprod
name: snatcher prod
description: It sparkles with a thirst for theft and treachery.
components:
- type: Sprite
sprite: _White/Objects/Weapons/Melee/snatcherprod.rsi
layers:
- state: snatcherprod
- state: snatcherprod_on
visible: false
map: [ "enum.ToggleVisuals.Layer" ]
- state: snatcherprod_cell
visible: false
map: [ "enum.PowerDeviceVisualLayers.Powered" ]
- type: Item
sprite: _White/Objects/Weapons/Melee/snatcherprod.rsi
- type: GenericVisualizer
visuals:
enum.ToggleVisuals.Toggled:
enum.ToggleVisuals.Layer:
True: {visible: true}
False: {visible: false}
enum.PowerCellSlotVisuals.Enabled:
enum.PowerDeviceVisualLayers.Powered:
True: {visible: true}
False: {visible: false}
- type: SnatchOnMeleeHit
- type: Construction
deconstructionTarget: cuffs
graph: StunprodGraph
node: snatcherprod
Loading

0 comments on commit ceea215

Please sign in to comment.