Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Port] Crossbow / Арбалет #76

Merged
merged 14 commits into from
Oct 26, 2024
21 changes: 21 additions & 0 deletions Content.Client/_White/Guns/Stretched/StretchedVisualizerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Content.Shared._White.Guns.Stretched;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Client.GameObjects;

namespace Content.Client._White.Guns.Stretched;

public sealed class StretchedVisualizerSystem : VisualizerSystem<StretchedVisualsComponent>
{
[Dependency] private readonly AppearanceSystem _appearance = default!;

protected override void OnAppearanceChange(EntityUid uid, StretchedVisualsComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;

_appearance.TryGetData<bool>(uid, StretchedVisuals.Stretched, out var stretched, args.Component);
_appearance.TryGetData<bool>(uid, AmmoVisuals.HasAmmo, out var hasAmmo, args.Component);

args.Sprite.LayerSetState(StretchedVisuals.Layer, stretched ? component.StretchedState : hasAmmo ? component.LoadedState : component.UnstrungVisible);
}
Spatison marked this conversation as resolved.
Show resolved Hide resolved
}
14 changes: 14 additions & 0 deletions Content.Client/_White/Guns/Stretched/StretchedVisualsComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Client._White.Guns.Stretched;

[RegisterComponent, Access(typeof(StretchedVisualizerSystem))]
public sealed partial class StretchedVisualsComponent : Component
{
[DataField]
public string? LoadedState;

[DataField]
public string? StretchedState;

[DataField]
public string? UnstrungVisible;
Spatison marked this conversation as resolved.
Show resolved Hide resolved
}
34 changes: 33 additions & 1 deletion 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 @@ -113,7 +117,7 @@ private void OnEmpDisabledRemoved(EntityUid uid, BatteryComponent component, ref
if (!TryComp<ChargingComponent>(uid, out var charging))
return;

var ev = new ChargerUpdateStatusEvent();
var ev = new ChargerUpdateStatusEvent();
RaiseLocalEvent<ChargerUpdateStatusEvent>(charging.ChargerUid, ref ev);
}

Expand Down Expand Up @@ -197,5 +201,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
}
}
99 changes: 99 additions & 0 deletions Content.Server/Projectiles/ProjectileSystem.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
using Content.Server.Administration.Logs;
using Content.Server.Effects;
using Content.Server.Hands.Systems;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared._White.Penetrated;
using Content.Shared._White.Projectile;
using Content.Shared.Camera;
using Content.Shared.Damage;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Projectiles;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Player;

Expand All @@ -17,11 +26,20 @@ public sealed class ProjectileSystem : SharedProjectileSystem
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly GunSystem _guns = default!;
[Dependency] private readonly SharedCameraRecoilSystem _sharedCameraRecoil = default!;
[Dependency] private readonly DamageableSystem _damageable = default!; // WD EDIT
[Dependency] private readonly HandsSystem _hands = default!; // WD EDIT
[Dependency] private readonly PhysicsSystem _physics = default!; // WD EDIT
[Dependency] private readonly SharedTransformSystem _transform = default!; // WD EDIT
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!; // WD EDIT
[Dependency] private readonly PenetratedSystem _penetrated = default!; // WD EDIT

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ProjectileComponent, StartCollideEvent>(OnStartCollide);
SubscribeLocalEvent<EmbeddableProjectileComponent, EmbedEvent>(OnEmbed); // WD EDIT
SubscribeLocalEvent<EmbeddableProjectileComponent, ActivateInWorldEvent>(OnEmbedActivate); // WD EDIT
SubscribeLocalEvent<EmbeddableProjectileComponent, RemoveEmbeddedProjectileEvent>(OnEmbedRemove); // WD EDIT
}

private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref StartCollideEvent args)
Expand Down Expand Up @@ -77,4 +95,85 @@ private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref St
RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager));
}
}

// WD EDIT START
private void OnEmbed(EntityUid uid, EmbeddableProjectileComponent component, ref EmbedEvent args)
{
var dmg = _damageable.TryChangeDamage(args.Embedded, component.Damage, origin: args.Shooter);
if (dmg is { Empty: false })
_color.RaiseEffect(Color.Red, new List<EntityUid>() { args.Embedded }, Filter.Pvs(args.Embedded, entityManager: EntityManager));
}
Spatison marked this conversation as resolved.
Show resolved Hide resolved

private void OnEmbedActivate(EntityUid uid, EmbeddableProjectileComponent component, ActivateInWorldEvent args)
{
if (args.Handled
|| !AttemptEmbedRemove(uid, args.User, component))
return;

args.Handled = true;
}

private void OnEmbedRemove(EntityUid uid, EmbeddableProjectileComponent component, RemoveEmbeddedProjectileEvent args)
{
// Whacky prediction issues.
if (args.Cancelled)
return;

if (component.DeleteOnRemove)
{
QueueDel(uid);
FreePenetrated(uid);
return;
}

var xform = Transform(uid);
TryComp<PhysicsComponent>(uid, out var physics);
_physics.SetBodyType(uid, BodyType.Dynamic, body: physics, xform: xform);
Spatison marked this conversation as resolved.
Show resolved Hide resolved
_transform.AttachToGridOrMap(uid, xform);

// Reset whether the projectile has damaged anything if it successfully was removed
if (TryComp<ProjectileComponent>(uid, out var projectile))
{
projectile.Shooter = null;
projectile.Weapon = null;
projectile.DamagedEntity = false;
}

FreePenetrated(uid);

// Land it just coz uhhh yeah
var landEv = new LandEvent(args.User, true);
RaiseLocalEvent(uid, ref landEv);
_physics.WakeBody(uid, body: physics);

// try place it in the user's hand
_hands.TryPickupAnyHand(args.User, uid);
}

private bool AttemptEmbedRemove(EntityUid uid, EntityUid user, EmbeddableProjectileComponent? component = null)
{
if (!Resolve(uid, ref component, false)
|| component.RemovalTime == null
|| !TryComp<PhysicsComponent>(uid, out var physics)
|| physics.BodyType != BodyType.Static)
return false;
Spatison marked this conversation as resolved.
Show resolved Hide resolved

_doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, component.RemovalTime.Value,
new RemoveEmbeddedProjectileEvent(), eventTarget: uid, target: uid)
{
DistanceThreshold = SharedInteractionSystem.InteractionRange,
});

return true;
}

private void FreePenetrated(EntityUid uid, PenetratedProjectileComponent? penetratedProjectile = null)
{
if (!Resolve(uid, ref penetratedProjectile)
|| !penetratedProjectile.PenetratedUid.HasValue)
Spatison marked this conversation as resolved.
Show resolved Hide resolved
return;

_penetrated.FreePenetrated(penetratedProjectile.PenetratedUid.Value);
}
// WD EDIT END
}
40 changes: 5 additions & 35 deletions Content.Server/Stunnable/Systems/StunbatonSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Power.Events;
Expand All @@ -12,7 +11,6 @@
using Content.Shared.Popups;
using Content.Shared.PowerCell.Components;
using Content.Shared.Stunnable;
using Robust.Shared.Containers;

namespace Content.Server.Stunnable.Systems
{
Expand All @@ -23,8 +21,6 @@ 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()
{
base.Initialize();
Expand All @@ -42,7 +38,7 @@ private void OnStaminaHitAttempt(Entity<StunbatonComponent> entity, ref StaminaD
{
// WD EDIT START
if (!_itemToggle.IsActivated(entity.Owner)
|| !TryGetBatteryComponent(entity, out var battery, out var batteryUid)
|| !_battery.TryGetBatteryComponent(entity, out var battery, out var batteryUid)
|| !_battery.TryUseCharge(batteryUid.Value, entity.Comp.EnergyPerUse, battery))
args.Cancelled = true;
// WD EDIT END
Expand All @@ -55,7 +51,7 @@ private void OnExamined(Entity<StunbatonComponent> entity, ref ExaminedEvent arg
: Loc.GetString("comp-stunbaton-examined-off");
args.PushMarkup(onMsg);

if (TryGetBatteryComponent(entity, out var battery, out _)) // WD EDIT
if (_battery.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 @@ -70,7 +66,7 @@ private void ToggleDone(Entity<StunbatonComponent> entity, ref ItemToggledEvent
private void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
{
// WD EDIT START
if (!TryGetBatteryComponent(entity, out var battery, out _)
if (!_battery.TryGetBatteryComponent(entity, out var battery, out _)
|| battery.CurrentCharge < entity.Comp.EnergyPerUse)
{

Expand All @@ -81,7 +77,7 @@ private void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivate
_popup.PopupEntity(Loc.GetString("stunbaton-component-low-charge"), (EntityUid) args.User,
(EntityUid) args.User);
}

return;
}
// WD EDIT END
Expand Down Expand Up @@ -126,36 +122,10 @@ private void OnPowerCellChanged(Entity<StunbatonComponent> entity, ref PowerCell

private void CheckCharge(Entity<StunbatonComponent> entity)
{
if (!TryGetBatteryComponent(entity, out var battery, out _)
if (!_battery.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
}
}
4 changes: 3 additions & 1 deletion Content.Server/UserInterface/ActivatableUISystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Administration.Managers;
using Content.Server.Projectiles;
using Content.Shared.ActionBlocker;
using Content.Shared.Ghost;
using Content.Shared.Hands;
Expand All @@ -24,7 +25,7 @@ public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ActivatableUIComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<ActivatableUIComponent, ActivateInWorldEvent>(OnActivate, after: new[] {typeof(ProjectileSystem)});
SubscribeLocalEvent<ActivatableUIComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<ActivatableUIComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<ActivatableUIComponent, HandDeselectedEvent>(OnHandDeselected);
Expand Down Expand Up @@ -87,6 +88,7 @@ private void AddOpenUiVerb(EntityUid uid, ActivatableUIComponent component, GetV

private void OnActivate(EntityUid uid, ActivatableUIComponent component, ActivateInWorldEvent args)
{
Log.Error("2");
Spatison marked this conversation as resolved.
Show resolved Hide resolved
if (args.Handled)
return;

Expand Down
11 changes: 11 additions & 0 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.Ballistic.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Content.Server.Stack;
using Content.Shared.Stacks;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Map;
Expand All @@ -6,6 +8,8 @@ namespace Content.Server.Weapons.Ranged.Systems;

public sealed partial class GunSystem
{
[Dependency] private readonly StackSystem _stack = default!;

protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
{
EntityUid? ent = null;
Expand All @@ -32,4 +36,11 @@ protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent comp
var cycledEvent = new GunCycledEvent();
RaiseLocalEvent(uid, ref cycledEvent);
}

// WD EDIT START
protected override EntityUid GetStackEntity(EntityUid uid, StackComponent stack)
{
return _stack.Split(uid, 1, Transform(uid).Coordinates, stack) ?? uid;
}
// WD EDIT END
}
6 changes: 6 additions & 0 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Content.Shared.Effects;
using Content.Shared.Interaction.Components;
using Content.Shared.Projectiles;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Ranged;
using Content.Shared.Weapons.Ranged.Components;
Expand Down Expand Up @@ -293,7 +294,12 @@ private void ShootOrThrow(EntityUid uid, Vector2 mapDirection, Vector2 gunVeloci
{
RemoveShootable(uid);
// TODO: Someone can probably yeet this a billion miles so need to pre-validate input somewhere up the call stack.
// WD EDIT START
if (gun.ThrowAngle.HasValue)
EnsureComp<ThrowingAngleComponent>(uid).Angle = gun.ThrowAngle.Value;
// WD EDIT END
ThrowingSystem.TryThrow(uid, mapDirection, gun.ProjectileSpeedModified, user);
RemComp<ThrowingAngleComponent>(uid); // WD EDIT
return;
}

Expand Down
Loading
Loading