Skip to content

Commit

Permalink
[Port/Tweak] Eshield / Е-Щит (#94)
Browse files Browse the repository at this point in the history
* tweak: eshield

* add: energy shield

* fix
  • Loading branch information
Spatison authored Oct 23, 2024
1 parent d77c175 commit d5d5278
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 34 deletions.
32 changes: 32 additions & 0 deletions Content.Server/Power/EntitySystems/BatterySystem.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Cargo.Systems;
using Content.Server.Emp;
using Content.Shared.Emp;
using Content.Server.Power.Components;
using Content.Shared.Examine;
using Content.Shared.Rejuvenate;
using JetBrains.Annotations;
using Robust.Shared.Containers;
using Robust.Shared.Utility;

namespace Content.Server.Power.EntitySystems
{
[UsedImplicitly]
public sealed class BatterySystem : EntitySystem
{
[Dependency] private readonly SharedContainerSystem _containers = default!; // WD EDIT

public override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -181,5 +185,33 @@ public bool IsFull(EntityUid uid, BatteryComponent? battery = null)

return battery.CurrentCharge / battery.MaxCharge >= 0.99f;
}

// WD EDIT START
public 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
}
}
4 changes: 2 additions & 2 deletions Content.Server/PowerCell/PowerCellSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ private void OnCellSlotExamined(EntityUid uid, PowerCellSlotComponent component,
OnBatteryExamined(uid, battery, args);
}

private void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args)
public void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args) // WD EDIT
{
if (component != null)
if (Resolve(uid, ref component, false)) // WD EDIT
{
var charge = component.CurrentCharge / component.MaxCharge * 100;
args.PushMarkup(Loc.GetString("power-cell-component-examine-details", ("currentCharge", $"{charge:F0}")));
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?

FireEffects(fromEffect, result.Distance, dir.Normalized().ToAngle(), hitscan, hit);

var ev = new HitScanReflectAttemptEvent(user, gunUid, hitscan.Reflective, dir, false);
var ev = new HitScanReflectAttemptEvent(user, gunUid, hitscan.Reflective, dir, false, hitscan.Damage); // WD EDIT
RaiseLocalEvent(hit, ref ev);

if (!ev.Reflected)
Expand Down
11 changes: 11 additions & 0 deletions Content.Server/_White/Blocking/RechargeableBlockingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Content.Server._White.Blocking;

[RegisterComponent]
public sealed partial class RechargeableBlockingComponent : Component
{
[DataField]
public float RechargeDelay = 30f;

[ViewVariables]
public bool Discharged;
}
91 changes: 91 additions & 0 deletions Content.Server/_White/Blocking/RechargeableBlockingSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using Content.Server.Item;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.PowerCell;
using Content.Shared.Damage;
using Content.Shared.Examine;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.PowerCell.Components;

namespace Content.Server._White.Blocking;

public sealed class RechargeableBlockingSystem : EntitySystem
{
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly ItemToggleSystem _itemToggle = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly PowerCellSystem _powerCell = default!;

public override void Initialize()
{
SubscribeLocalEvent<RechargeableBlockingComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<RechargeableBlockingComponent, DamageChangedEvent>(OnDamageChanged);
SubscribeLocalEvent<RechargeableBlockingComponent, ItemToggleActivateAttemptEvent>(AttemptToggle);
SubscribeLocalEvent<RechargeableBlockingComponent, ChargeChangedEvent>(OnChargeChanged);
SubscribeLocalEvent<RechargeableBlockingComponent, PowerCellChangedEvent>(OnPowerCellChanged);
}

private void OnExamined(EntityUid uid, RechargeableBlockingComponent component, ExaminedEvent args)
{
BatteryComponent? batteryComponent = null;

if (component.Discharged)
{
args.PushMarkup(Loc.GetString("rechargeable-blocking-discharged"));
if (_battery.TryGetBatteryComponent(uid, out batteryComponent, out var batteryUid)
&& TryComp<BatterySelfRechargerComponent>(batteryUid, out var recharger)
&& recharger is { AutoRechargeRate: > 0, AutoRecharge: true })
{
var remainingTime = (int) (component.RechargeDelay - batteryComponent.CurrentCharge) / recharger.AutoRechargeRate;
args.PushMarkup(Loc.GetString("rechargeable-blocking-remaining-time", ("remainingTime", remainingTime)));
}
}

_powerCell.OnBatteryExamined(uid, batteryComponent, args);
}

private void OnDamageChanged(EntityUid uid, RechargeableBlockingComponent component, DamageChangedEvent args)
{
if (!_battery.TryGetBatteryComponent(uid, out var batteryComponent, out var batteryUid)
|| !_itemToggle.IsActivated(uid)
|| args.DamageDelta == null)
return;

var batteryUse = Math.Min(args.DamageDelta.GetTotal().Float(), batteryComponent.CurrentCharge);
_battery.TryUseCharge(batteryUid.Value, batteryUse, batteryComponent);
}

private void AttemptToggle(EntityUid uid, RechargeableBlockingComponent component, ref ItemToggleActivateAttemptEvent args)
{
if (!component.Discharged)
return;

_popup.PopupEntity(Loc.GetString("stunbaton-component-low-charge"), args.User ?? uid);
args.Cancelled = true;
}
private void OnChargeChanged(EntityUid uid, RechargeableBlockingComponent component, ChargeChangedEvent args)
{
CheckCharge(uid, component);
}

private void OnPowerCellChanged(EntityUid uid, RechargeableBlockingComponent component, PowerCellChangedEvent args)
{
CheckCharge(uid, component);
}

private void CheckCharge(EntityUid uid, RechargeableBlockingComponent component)
{
if (!_battery.TryGetBatteryComponent(uid, out var battery, out _))
return;

if (battery.CurrentCharge < 1)
{
component.Discharged = true;
_itemToggle.TryDeactivate(uid, predicted: false);
}

if (battery.CurrentCharge > component.RechargeDelay)
component.Discharged = false;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Numerics;
using Content.Shared.Damage;
using Content.Shared.Weapons.Reflect;

namespace Content.Shared.Weapons.Ranged.Events;
Expand All @@ -8,4 +9,5 @@ namespace Content.Shared.Weapons.Ranged.Events;
/// and changing <see cref="Direction"/> where shot will go next
/// </summary>
[ByRefEvent]
public record struct HitScanReflectAttemptEvent(EntityUid? Shooter, EntityUid SourceItem, ReflectType Reflective, Vector2 Direction, bool Reflected);
public record struct HitScanReflectAttemptEvent(EntityUid? Shooter, EntityUid SourceItem, ReflectType Reflective,
Vector2 Direction, bool Reflected, DamageSpecifier? Damage); // WD EDIT
5 changes: 5 additions & 0 deletions Content.Shared/Weapons/Reflect/ReflectComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public sealed partial class ReflectComponent : Component
/// </summary>
[DataField]
public float MinReflectProb = 0.1f;

// WD START
[DataField, AutoNetworkedField]
public float DamageOnReflectModifier;
// WD END
}

[Flags]
Expand Down
20 changes: 18 additions & 2 deletions Content.Shared/Weapons/Reflect/ReflectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Content.Shared.Administration.Logs;
using Content.Shared.Alert;
using Content.Shared.Audio;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Database;
using Content.Shared.Gravity;
Expand Down Expand Up @@ -41,6 +42,7 @@ public sealed class ReflectSystem : EntitySystem
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly StandingStateSystem _standing = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly DamageableSystem _damageable = default!; // WD EDIT

public override void Initialize()
{
Expand All @@ -65,7 +67,7 @@ private void OnReflectUserHitscan(EntityUid uid, ReflectUserComponent component,

foreach (var ent in _inventorySystem.GetHandOrInventoryEntities(uid, SlotFlags.WITHOUT_POCKET))
{
if (!TryReflectHitscan(uid, ent, args.Shooter, args.SourceItem, args.Direction, out var dir))
if (!TryReflectHitscan(uid, ent, args.Shooter, args.SourceItem, args.Direction, args.Damage, out var dir))
continue;

args.Direction = dir.Value;
Expand Down Expand Up @@ -134,6 +136,14 @@ private bool TryReflectProjectile(EntityUid user, EntityUid reflector, EntityUid

if (Resolve(projectile, ref projectileComp, false))
{
// WD EDIT START
if (reflect.DamageOnReflectModifier != 0)
{
_damageable.TryChangeDamage(reflector, projectileComp.Damage * reflect.DamageOnReflectModifier,
projectileComp.IgnoreResistances, origin: projectileComp.Shooter);
}
// WD EDIT END

_adminLogger.Add(LogType.BulletHit, LogImpact.Medium, $"{ToPrettyString(user)} reflected {ToPrettyString(projectile)} from {ToPrettyString(projectileComp.Weapon)} shot by {projectileComp.Shooter}");

projectileComp.Shooter = user;
Expand Down Expand Up @@ -184,7 +194,7 @@ private void OnReflectHitscan(EntityUid uid, ReflectComponent component, ref Hit
return;
}

if (TryReflectHitscan(uid, uid, args.Shooter, args.SourceItem, args.Direction, out var dir))
if (TryReflectHitscan(uid, uid, args.Shooter, args.SourceItem, args.Direction, args.Damage, out var dir)) // WD EDIT
{
args.Direction = dir.Value;
args.Reflected = true;
Expand All @@ -197,6 +207,7 @@ private bool TryReflectHitscan(
EntityUid? shooter,
EntityUid shotSource,
Vector2 direction,
DamageSpecifier? damage, // WD EDIT
[NotNullWhen(true)] out Vector2? newDirection)
{
if (!TryComp<ReflectComponent>(reflector, out var reflect) ||
Expand All @@ -220,6 +231,11 @@ private bool TryReflectHitscan(
_audio.PlayPvs(reflect.SoundOnReflect, user, AudioHelpers.WithVariation(0.05f, _random));
}

// WD EDIT START
if (reflect.DamageOnReflectModifier != 0 && damage != null)
_damageable.TryChangeDamage(reflector, damage * reflect.DamageOnReflectModifier, origin: shooter);
// WD EDIT END

var spread = _random.NextAngle(-reflect.Spread / 2, reflect.Spread / 2);
newDirection = -spread.RotateVec(direction);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rechargeable-blocking-discharged = It is [color=red]discharged[/color].
rechargeable-blocking-remaining-time = Time left to charge: [color=green]{ $remainingTime }[/color] seconds.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rechargeable-blocking-discharged = Он [color=red]разряжен[/color].
rechargeable-blocking-remaining-time = Осталось времени для зарядки: [color=green]{ $remainingTime }[/color] секунд.
2 changes: 1 addition & 1 deletion Resources/Prototypes/Catalog/uplink_catalog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@
icon: { sprite: /Textures/Objects/Weapons/Melee/e_shield.rsi, state: eshield-on }
productEntity: EnergyShield
cost:
Telecrystal: 8
Telecrystal: 6 # WD EDIT
categories:
- UplinkMisc
conditions:
Expand Down
48 changes: 21 additions & 27 deletions Resources/Prototypes/Entities/Objects/Shields/shields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,17 @@
description: Exotic energy shield, when folded, can even fit in your pocket.
components:
- type: ItemToggle
predictable: false # WD EDIT
soundActivate:
path: /Audio/Weapons/ebladeon.ogg
soundDeactivate:
path: /Audio/Weapons/ebladeoff.ogg
# WD EDIT START
soundFailToActivate:
path: /Audio/Machines/button.ogg
params:
variation: 0.250
# WD EDIT END
- type: ItemToggleActiveSound
activeSound:
path: /Audio/Weapons/ebladehum.ogg
Expand Down Expand Up @@ -405,12 +412,12 @@
netsync: false
enabled: false
radius: 1.5
energy: 2
color: blue
energy: 0.7 # WD EDIT
color: "#678AD9" # WD EDIT
- type: Reflect
enabled: false
reflectProb: 0.95
innate: true
reflectProb: 1 # WD EDIT
damageOnReflectModifier: 0.5 # WD EDIT
reflects:
- Energy
- type: Blocking
Expand All @@ -432,31 +439,18 @@
- type: Appearance
- type: Damageable
damageContainer: Shield
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 180
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- trigger:
!type:DamageTrigger
damage: 100
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
BrokenEnergyShield:
min: 1
max: 1
- type: StaticPrice
price: 350
- type: MeleeBlock # WD EDIT
# WD EDIT START
- type: MeleeBlock
- type: Battery
maxCharge: 40
startingCharge: 40
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 1
- type: RechargeableBlocking
# WD EDIT END

- type: entity
name: broken energy shield
Expand Down

0 comments on commit d5d5278

Please sign in to comment.