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

Cleanup ExecutionSystem #24382

Merged
merged 30 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1d0e33c
Creat Execution Component and add to sharp items
nikthechampiongr Jan 20, 2024
98396e6
Kill Server ExecutionSystem. Create ExecutionSystem in shared. Create…
nikthechampiongr Jan 20, 2024
e3ded66
Fix bugs
nikthechampiongr Jan 20, 2024
a46da64
Remove clumsy text
nikthechampiongr Jan 20, 2024
b722723
Make BaseSword abstract
nikthechampiongr Jan 20, 2024
f93e22c
Add ExecutionComponent to every weapon
nikthechampiongr Jan 20, 2024
bf001c5
Fix bug
nikthechampiongr Jan 20, 2024
c714006
Remove execution comp from battery weapons
nikthechampiongr Jan 20, 2024
c085cc2
Cleanup
nikthechampiongr Jan 20, 2024
5037cfa
Revert "Remove clumsy text"
nikthechampiongr Jan 20, 2024
2a6adac
Actually fix the ExecutionSystem
nikthechampiongr Jan 21, 2024
6e37183
Make launchers able to execute
nikthechampiongr Jan 21, 2024
5926c43
Fix prediction bug
nikthechampiongr Jan 21, 2024
01dc118
Readd ability for clowns to accidentally shoot themselves while execu…
nikthechampiongr Jan 21, 2024
b8bc7ba
Cleanup
nikthechampiongr Jan 21, 2024
83be0ad
Reset melee cooldown to initial value
nikthechampiongr Jan 21, 2024
f952d2f
Address reviews fix bug
nikthechampiongr Jan 21, 2024
d181c99
Address Reviews
nikthechampiongr Jan 22, 2024
30c1e1e
Exorcise codebase
nikthechampiongr Jan 22, 2024
74f344d
Address reviews again
nikthechampiongr Jan 22, 2024
a3990eb
Remove melee weapon attack logic and rely on the system. Remove gun and
nikthechampiongr Jan 22, 2024
0b96487
Make system functional again and cleanup
nikthechampiongr Jan 23, 2024
75bb920
Remove code I forgot to remove
nikthechampiongr Jan 23, 2024
2f15999
Merge remote-tracking branch 'upstream/master' into execution_better
metalgearsloth Feb 25, 2024
af6dcb8
Cleanup
metalgearsloth Feb 25, 2024
b0ffa09
stalled
metalgearsloth Feb 25, 2024
debdade
Selectively revert gun penetration
metalgearsloth Feb 25, 2024
42eee06
Merge branch '2024-02-25-gun-pen' into execution_better
metalgearsloth Feb 25, 2024
7831199
Fixes
metalgearsloth Feb 25, 2024
8561c65
Merge remote-tracking branch 'upstream/master' into execution_better
metalgearsloth Feb 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
397 changes: 0 additions & 397 deletions Content.Server/Execution/ExecutionSystem.cs

This file was deleted.

28 changes: 24 additions & 4 deletions Content.Server/Projectiles/ProjectileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref St
{
// This is so entities that shouldn't get a collision are ignored.
if (args.OurFixtureId != ProjectileFixture || !args.OtherFixture.Hard
|| component.DamagedEntity || component is { Weapon: null, OnlyCollideWhenShot: true })
|| component.DamagedEntity || component is
{ Weapon: null, OnlyCollideWhenShot: true })
{
return;
}

var target = args.OtherEntity;

// it's here so this check is only done once before possible hit
var attemptEv = new ProjectileReflectAttemptEvent(uid, component, false);
RaiseLocalEvent(target, ref attemptEv);
Expand All @@ -41,11 +45,26 @@ private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref St
return;
}

if (TryHandleProjectile(target, (uid, component)))
{
var direction = args.OurBody.LinearVelocity.Normalized();
_sharedCameraRecoil.KickCamera(target, direction);
}
}

/// <summary>
/// Tries to handle a projectile interacting with the target.
/// </summary>
/// <returns>True if the target isn't deleted.</returns>
public bool TryHandleProjectile(EntityUid target, Entity<ProjectileComponent> projectile)
{
var uid = projectile.Owner;
var component = projectile.Comp;

var ev = new ProjectileHitEvent(component.Damage, target, component.Shooter);
RaiseLocalEvent(uid, ref ev);

var otherName = ToPrettyString(target);
var direction = args.OurBody.LinearVelocity.Normalized();
var modifiedDamage = _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances, origin: component.Shooter);
var deleted = Deleted(target);

Expand All @@ -64,12 +83,11 @@ private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref St
if (!deleted)
{
_guns.PlayImpactSound(target, modifiedDamage, component.SoundHit, component.ForceSound);
_sharedCameraRecoil.KickCamera(target, direction);
}

component.DamagedEntity = true;

var afterProjectileHitEvent = new AfterProjectileHitEvent(component.Damage, target, args.OtherFixture);
var afterProjectileHitEvent = new AfterProjectileHitEvent(component.Damage, target);
RaiseLocalEvent(uid, ref afterProjectileHitEvent);

if (component.DeleteOnCollide)
Expand All @@ -79,5 +97,7 @@ private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref St
{
RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager));
}

return !deleted;
}
}
149 changes: 143 additions & 6 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Content.Server.Cargo.Systems;
using Content.Server.Interaction;
using Content.Server.Power.EntitySystems;
using Content.Server.Projectiles;
using Content.Server.Stunnable;
using Content.Server.Weapons.Ranged.Components;
using Content.Shared.Damage;
Expand All @@ -29,13 +30,13 @@ namespace Content.Server.Weapons.Ranged.Systems;

public sealed partial class GunSystem : SharedGunSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly DamageExamineSystem _damageExamine = default!;
[Dependency] private readonly InteractionSystem _interaction = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly ProjectileSystem _projectile = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
[Dependency] private readonly StunSystem _stun = default!;
Expand Down Expand Up @@ -65,14 +66,145 @@ private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent comp
args.Price += price * component.UnspawnedCount;
}

protected override bool ShootDirect(EntityUid gunUid, GunComponent gun, EntityUid target, List<(EntityUid? Entity, IShootable Shootable)> ammo, EntityUid user)
{
var result = false;

// TODO: This is dogshit. I just want to get executions slightly better.
// Ideally you'd pull out cartridge + ammo to separate handling functions and re-use it here, then hitscan you need to bypass entirely.
// You should also make shooting into a struct of args given how many there are now.
var fromCoordinates = Transform(gunUid).Coordinates;
var toCoordinates = Transform(target).Coordinates;

var fromMap = fromCoordinates.ToMap(EntityManager, TransformSystem);
var toMap = toCoordinates.ToMapPos(EntityManager, TransformSystem);
var mapDirection = toMap - fromMap.Position;
var angle = GetRecoilAngle(Timing.CurTime, gun, mapDirection.ToAngle());

// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out _)
? fromCoordinates.WithEntityId(gridUid, EntityManager)
: new EntityCoordinates(MapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);

// I must be high because this was getting tripped even when true.
// DebugTools.Assert(direction != Vector2.Zero);
var shotProjectiles = new List<EntityUid>(ammo.Count);
var cartridgeBullets = new List<EntityUid>();

foreach (var (ent, shootable) in ammo)
{
switch (shootable)
{
// Cartridge shoots something else
case CartridgeAmmoComponent cartridge:
if (!cartridge.Spent)
{
for (var i = 0; i < cartridge.Count; i++)
{
var uid = Spawn(cartridge.Prototype, fromEnt);
cartridgeBullets.Add(uid);
}

RaiseLocalEvent(ent!.Value, new AmmoShotEvent()
{
FiredProjectiles = cartridgeBullets,
});

shotProjectiles.AddRange(cartridgeBullets);
cartridgeBullets.Clear();
SetCartridgeSpent(ent.Value, cartridge, true);
MuzzleFlash(gunUid, cartridge, user);
Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);

if (cartridge.DeleteOnSpawn)
Del(ent.Value);
}
else
{
Audio.PlayPredicted(gun.SoundEmpty, gunUid, user);
}

// Something like ballistic might want to leave it in the container still
if (!cartridge.DeleteOnSpawn && !Containers.IsEntityInContainer(ent!.Value))
EjectCartridge(ent.Value, angle);

result = true;
Dirty(ent!.Value, cartridge);
break;
// Ammo shoots itself
case AmmoComponent newAmmo:
result = true;
shotProjectiles.Add(ent!.Value);
MuzzleFlash(gunUid, newAmmo, user);
Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
break;
case HitscanPrototype hitscan:
result = true;
var hitEntity = target;
if (hitscan.StaminaDamage > 0f)
_stamina.TakeStaminaDamage(hitEntity, hitscan.StaminaDamage, source: user);

var dmg = hitscan.Damage;

var hitName = ToPrettyString(hitEntity);
if (dmg != null)
dmg = Damageable.TryChangeDamage(hitEntity, dmg, origin: user);

// check null again, as TryChangeDamage returns modified damage values
if (dmg != null)
{
if (!Deleted(hitEntity))
{
if (dmg.Any())
{
_color.RaiseEffect(Color.Red, new List<EntityUid>() { hitEntity }, Filter.Pvs(hitEntity, entityManager: EntityManager));
}

// TODO get fallback position for playing hit sound.
PlayImpactSound(hitEntity, dmg, hitscan.Sound, hitscan.ForceSound);
}

Logs.Add(LogType.HitScanHit,
$"{ToPrettyString(user):user} hit {hitName:target} using hitscan and dealt {dmg.GetTotal():damage} damage");
}

Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
break;
default:
throw new ArgumentOutOfRangeException();
}
}

foreach (var ammoUid in shotProjectiles)
{
// TODO: Handle this shit
if (!TryComp(ammoUid, out ProjectileComponent? projectileComponent))
{
QueueDel(ammoUid);
continue;
}

_projectile.TryHandleProjectile(target, (ammoUid, projectileComponent));
// Even this deletion handling is mega sussy.
Del(ammoUid);
}

RaiseLocalEvent(gunUid, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
});

return result;
}

public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? Entity, IShootable Shootable)> ammo,
EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, out bool userImpulse, EntityUid? user = null, bool throwItems = false)
{
userImpulse = true;

// Try a clumsy roll
// TODO: Who put this here
if (TryComp<ClumsyComponent>(user, out var clumsy) && gun.ClumsyProof == false)
if (TryComp<ClumsyComponent>(user, out var clumsy) && !gun.ClumsyProof)
{
for (var i = 0; i < ammo.Count; i++)
{
Expand All @@ -93,14 +225,16 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?
}
}

// As the above message wasn't obvious stop putting stuff here and use events

var fromMap = fromCoordinates.ToMap(EntityManager, TransformSystem);
var toMap = toCoordinates.ToMapPos(EntityManager, TransformSystem);
var mapDirection = toMap - fromMap.Position;
var mapAngle = mapDirection.ToAngle();
var angle = GetRecoilAngle(Timing.CurTime, gun, mapDirection.ToAngle());

// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out var grid)
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out _)
? fromCoordinates.WithEntityId(gridUid, EntityManager)
: new EntityCoordinates(MapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);

Expand All @@ -112,6 +246,7 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?
// I must be high because this was getting tripped even when true.
// DebugTools.Assert(direction != Vector2.Zero);
var shotProjectiles = new List<EntityUid>(ammo.Count);
var cartridgeBullets = new List<EntityUid>();

foreach (var (ent, shootable) in ammo)
{
Expand Down Expand Up @@ -140,21 +275,23 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?
{
var uid = Spawn(cartridge.Prototype, fromEnt);
ShootOrThrow(uid, angles[i].ToVec(), gunVelocity, gun, gunUid, user);
shotProjectiles.Add(uid);
cartridgeBullets.Add(uid);
}
}
else
{
var uid = Spawn(cartridge.Prototype, fromEnt);
ShootOrThrow(uid, mapDirection, gunVelocity, gun, gunUid, user);
shotProjectiles.Add(uid);
cartridgeBullets.Add(uid);
}

RaiseLocalEvent(ent!.Value, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
FiredProjectiles = cartridgeBullets,
});

shotProjectiles.AddRange(cartridgeBullets);
cartridgeBullets.Clear();
SetCartridgeSpent(ent.Value, cartridge, true);
MuzzleFlash(gunUid, cartridge, user);
Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
Expand Down
26 changes: 26 additions & 0 deletions Content.Shared/Execution/ExecutionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Robust.Shared.GameStates;

namespace Content.Shared.Execution;

/// <summary>
/// Added to entities that can be used to execute another target.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ExecutionComponent : Component
{
/// <summary>
/// How long the execution duration lasts.
/// </summary>
[DataField, AutoNetworkedField]
public float DoAfterDuration = 5f;

[DataField, AutoNetworkedField]
public float DamageModifier = 9f;

// Not networked because this is transient inside of a tick.
/// <summary>
/// True if it is currently executing for handlers.
/// </summary>
[DataField]
public bool Executing = true;
}
Loading
Loading