diff --git a/Content.Server/Execution/ExecutionSystem.cs b/Content.Server/Execution/ExecutionSystem.cs deleted file mode 100644 index d0fce534ff..0000000000 --- a/Content.Server/Execution/ExecutionSystem.cs +++ /dev/null @@ -1,419 +0,0 @@ -using Content.Server.Interaction; -using Content.Server.Kitchen.Components; -using Content.Server.Weapons.Ranged.Systems; -using Content.Shared.ActionBlocker; -using Content.Shared.Damage; -using Content.Shared.Database; -using Content.Shared.DoAfter; -using Content.Shared.Execution; -using Content.Shared.Interaction.Components; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Popups; -using Content.Shared.Projectiles; -using Content.Shared.Verbs; -using Content.Shared.Weapons.Melee; -using Content.Shared.Weapons.Ranged; -using Content.Shared.Weapons.Ranged.Components; -using Content.Shared.Weapons.Ranged.Events; -using Content.Shared.Weapons.Ranged.Systems; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Player; -using Robust.Shared.Prototypes; - -namespace Content.Server.Execution; - -/// -/// Verb for violently murdering cuffed creatures. -/// -public sealed class ExecutionSystem : EntitySystem -{ - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; - [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly MobStateSystem _mobStateSystem = default!; - [Dependency] private readonly InteractionSystem _interactionSystem = default!; - [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; - [Dependency] private readonly DamageableSystem _damageableSystem = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IComponentFactory _componentFactory = default!; - [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly GunSystem _gunSystem = default!; - - private const float MeleeExecutionTimeModifier = 5.0f; - private const float GunExecutionTime = 6.0f; - private const float DamageModifier = 9.0f; - - /// - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent>(OnGetInteractionVerbsMelee); - SubscribeLocalEvent>(OnGetInteractionVerbsGun); - - SubscribeLocalEvent(OnDoafterMelee); - SubscribeLocalEvent(OnDoafterGun); - } - - private void OnGetInteractionVerbsMelee( - EntityUid uid, - SharpComponent component, - GetVerbsEvent args) - { - if (args.Hands == null || args.Using == null || !args.CanAccess || !args.CanInteract) - return; - - var attacker = args.User; - var weapon = args.Using!.Value; - var victim = args.Target; - - if (!CanExecuteWithMelee(weapon, victim, attacker)) - return; - - UtilityVerb verb = new() - { - Act = () => - { - TryStartMeleeExecutionDoafter(weapon, victim, attacker); - }, - Impact = LogImpact.High, - Text = Loc.GetString("execution-verb-name"), - Message = Loc.GetString("execution-verb-message"), - }; - - args.Verbs.Add(verb); - } - - private void OnGetInteractionVerbsGun( - EntityUid uid, - GunComponent component, - GetVerbsEvent args) - { - if (args.Hands == null || args.Using == null || !args.CanAccess || !args.CanInteract) - return; - - var attacker = args.User; - var weapon = args.Using!.Value; - var victim = args.Target; - - if (!CanExecuteWithGun(weapon, victim, attacker)) - return; - - UtilityVerb verb = new() - { - Act = () => - { - TryStartGunExecutionDoafter(weapon, victim, attacker); - }, - Impact = LogImpact.High, - Text = Loc.GetString("execution-verb-name"), - Message = Loc.GetString("execution-verb-message"), - }; - - args.Verbs.Add(verb); - } - - private bool CanExecuteWithAny(EntityUid victim, EntityUid attacker) - { - // No point executing someone if they can't take damage - if (!TryComp(victim, out _)) - return false; - - // You can't execute something that cannot die - if (!TryComp(victim, out var mobState)) - return false; - - // You're not allowed to execute dead people (no fun allowed) - if (_mobStateSystem.IsDead(victim, mobState)) - return false; - - // You must be able to attack people to execute - if (!_actionBlockerSystem.CanAttack(attacker, victim)) - return false; - - // The victim must be incapacitated to be executed - if (victim != attacker && _actionBlockerSystem.CanInteract(victim, null)) - return false; - - // All checks passed - return true; - } - - private bool CanExecuteWithMelee(EntityUid weapon, EntityUid victim, EntityUid user) - { - if (!CanExecuteWithAny(victim, user)) return false; - - // We must be able to actually hurt people with the weapon - if (!TryComp(weapon, out var melee) && melee!.Damage.GetTotal() > 0.0f) - return false; - - return true; - } - - private bool CanExecuteWithGun(EntityUid weapon, EntityUid victim, EntityUid user) - { - if (!CanExecuteWithAny(victim, user)) return false; - - // We must be able to actually fire the gun - if (!TryComp(weapon, out var gun) && _gunSystem.CanShoot(gun!)) - return false; - - return true; - } - - private void TryStartMeleeExecutionDoafter(EntityUid weapon, EntityUid victim, EntityUid attacker) - { - if (!CanExecuteWithMelee(weapon, victim, attacker)) - return; - - var executionTime = (1.0f / Comp(weapon).AttackRate) * MeleeExecutionTimeModifier; - - if (attacker == victim) - { - ShowExecutionPopup("suicide-popup-melee-initial-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("suicide-popup-melee-initial-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - else - { - ShowExecutionPopup("execution-popup-melee-initial-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("execution-popup-melee-initial-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - - var doAfter = new DoAfterArgs(EntityManager, attacker, executionTime, new ExecutionDoAfterEvent(), weapon, - target: victim, used: weapon) - { - BreakOnMove = true, - BreakOnDamage = true, - NeedHand = true - }; - - _doAfterSystem.TryStartDoAfter(doAfter); - } - - private void TryStartGunExecutionDoafter(EntityUid weapon, EntityUid victim, EntityUid attacker) - { - if (!CanExecuteWithGun(weapon, victim, attacker)) - return; - - if (attacker == victim) - { - ShowExecutionPopup("suicide-popup-gun-initial-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("suicide-popup-gun-initial-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - else - { - ShowExecutionPopup("execution-popup-gun-initial-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("execution-popup-gun-initial-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - - var doAfter = new DoAfterArgs(EntityManager, attacker, GunExecutionTime, new ExecutionDoAfterEvent(), weapon, - target: victim, used: weapon) - { - BreakOnDamage = true, - NeedHand = true - }; - - _doAfterSystem.TryStartDoAfter(doAfter); - } - - private void OnDoafterMelee(EntityUid uid, SharpComponent component, DoAfterEvent args) - { - if (args.Handled || args.Cancelled || args.Used == null || args.Target == null) - return; - - var attacker = args.User; - var victim = args.Target!.Value; - var weapon = args.Used!.Value; - - if (!CanExecuteWithMelee(weapon, victim, attacker)) return; - - if (!TryComp(weapon, out var melee) && melee!.Damage.GetTotal() > 0.0f) - return; - - _damageableSystem.TryChangeDamage(victim, melee.Damage * DamageModifier, true); - _audioSystem.PlayEntity(melee.HitSound, Filter.Pvs(weapon), weapon, true, AudioParams.Default); - - if (attacker == victim) - { - ShowExecutionPopup("suicide-popup-melee-complete-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("suicide-popup-melee-complete-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - else - { - ShowExecutionPopup("execution-popup-melee-complete-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("execution-popup-melee-complete-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - } - } - - // TODO: This repeats a lot of the code of the serverside GunSystem, make it not do that - private void OnDoafterGun(EntityUid uid, GunComponent component, DoAfterEvent args) - { - if (args.Handled || args.Cancelled || args.Used == null || args.Target == null) - return; - - var attacker = args.User; - var weapon = args.Used!.Value; - var victim = args.Target!.Value; - - if (!CanExecuteWithGun(weapon, victim, attacker)) return; - - // Check if any systems want to block our shot - var prevention = new ShotAttemptedEvent - { - User = attacker, - Used = weapon - }; - - RaiseLocalEvent(weapon, ref prevention); - if (prevention.Cancelled) - return; - - RaiseLocalEvent(attacker, ref prevention); - if (prevention.Cancelled) - return; - - // Not sure what this is for but gunsystem uses it so ehhh - var attemptEv = new AttemptShootEvent(attacker, null); - RaiseLocalEvent(weapon, ref attemptEv); - - if (attemptEv.Cancelled) - { - if (attemptEv.Message != null) - { - _popupSystem.PopupEntity(attemptEv.Message, weapon, attacker); - return; - } - } - - // Take some ammunition for the shot (one bullet) - var fromCoordinates = Transform(attacker).Coordinates; - var ev = new TakeAmmoEvent(1, new List<(EntityUid? Entity, IShootable Shootable)>(), fromCoordinates, attacker); - RaiseLocalEvent(weapon, ev); - - // Check if there's any ammo left - if (ev.Ammo.Count <= 0) - { - _audioSystem.PlayEntity(component.SoundEmpty, Filter.Pvs(weapon), weapon, true, AudioParams.Default); - ShowExecutionPopup("execution-popup-gun-empty", Filter.Pvs(weapon), PopupType.Medium, attacker, victim, - weapon); - - return; - } - - // Information about the ammo like damage - DamageSpecifier damage = new DamageSpecifier(); - - // Get some information from IShootable - var ammoUid = ev.Ammo[0].Entity; - switch (ev.Ammo[0].Shootable) - { - case CartridgeAmmoComponent cartridge: - // Get the damage value - var prototype = _prototypeManager.Index(cartridge.Prototype); - prototype.TryGetComponent(out var projectileA, - _componentFactory); // sloth forgive me - - if (projectileA != null) - { - damage = projectileA.Damage * cartridge.Count; - } - - // Expend the cartridge - cartridge.Spent = true; - _appearanceSystem.SetData(ammoUid!.Value, AmmoVisuals.Spent, true); - Dirty(ammoUid.Value, cartridge); - - break; - - case AmmoComponent newAmmo: - TryComp(ammoUid, out var projectileB); - if (projectileB != null) - { - damage = projectileB.Damage; - } - - Del(ammoUid); - break; - - case HitscanPrototype hitscan: - damage = hitscan.Damage!; - break; - - default: - throw new ArgumentOutOfRangeException(); - } - - // Clumsy people have a chance to shoot themselves - if (TryComp(attacker, out var clumsy) && component.ClumsyProof == false) - { - if (_interactionSystem.TryRollClumsy(attacker, 0.33333333f, clumsy)) - { - ShowExecutionPopup("execution-popup-gun-clumsy-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("execution-popup-gun-clumsy-external", Filter.PvsExcept(attacker), - PopupType.MediumCaution, attacker, victim, weapon); - - // You shoot yourself with the gun (no damage multiplier) - _damageableSystem.TryChangeDamage(attacker, damage, origin: attacker); - _audioSystem.PlayEntity(component.SoundGunshot, Filter.Pvs(weapon), weapon, true, AudioParams.Default); - return; - } - } - - // Gun successfully fired, deal damage - _damageableSystem.TryChangeDamage(victim, damage * DamageModifier, true); - _audioSystem.PlayEntity(component.SoundGunshot, Filter.Pvs(weapon), weapon, false, AudioParams.Default); - - // Popups - if (attacker != victim) - { - ShowExecutionPopup("execution-popup-gun-complete-internal", Filter.Entities(attacker), PopupType.Medium, - attacker, victim, weapon); - - ShowExecutionPopup("execution-popup-gun-complete-external", Filter.PvsExcept(attacker), - PopupType.LargeCaution, attacker, victim, weapon); - } - else - { - ShowExecutionPopup("suicide-popup-gun-complete-internal", Filter.Entities(attacker), PopupType.LargeCaution, - attacker, victim, weapon); - - ShowExecutionPopup("suicide-popup-gun-complete-external", Filter.PvsExcept(attacker), - PopupType.LargeCaution, attacker, victim, weapon); - } - } - - private void ShowExecutionPopup( - string locString, - Filter filter, - PopupType type, - EntityUid attacker, - EntityUid victim, - EntityUid weapon) - { - _popupSystem.PopupEntity(Loc.GetString( - locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), - attacker, filter, true, type); - } -} \ No newline at end of file diff --git a/Content.Server/Projectiles/ProjectileSystem.cs b/Content.Server/Projectiles/ProjectileSystem.cs index a561ca65d4..6431ba87de 100644 --- a/Content.Server/Projectiles/ProjectileSystem.cs +++ b/Content.Server/Projectiles/ProjectileSystem.cs @@ -7,7 +7,6 @@ using Content.Shared.Database; using Content.Shared.Projectiles; using Content.Shared._White; using Robust.Shared.Configuration; -using Robust.Shared.Physics.Dynamics; using Robust.Shared.Player; using Robust.Shared.Physics.Events; @@ -62,27 +61,12 @@ public sealed class ProjectileSystem : SharedProjectileSystem return; } - if (TryHandleProjectile(target, (uid, component), args.OtherFixture)) - { - var direction = args.OurBody.LinearVelocity.Normalized(); - _sharedCameraRecoil.KickCamera(target, direction); - } - } - - /// - /// Tries to handle a projectile interacting with the target. - /// - /// True if the target isn't deleted. - public bool TryHandleProjectile(EntityUid target, Entity projectile, Fixture? otherFixture) - { - 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 modifiedDamage = _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances, origin: component.Shooter); + var direction = args.OurBody.LinearVelocity.Normalized(); + var modifiedDamage = _damageableSystem.TryChangeDamage(target, ev.Damage * DamageModifier, component.IgnoreResistances, origin: component.Shooter); var deleted = Deleted(target); if (modifiedDamage is not null && EntityManager.EntityExists(component.Shooter)) @@ -100,13 +84,11 @@ public sealed class ProjectileSystem : SharedProjectileSystem if (!deleted) { _guns.PlayImpactSound(target, modifiedDamage, component.SoundHit, component.ForceSound); + _sharedCameraRecoil.KickCamera(target, direction); } component.DamagedEntity = true; - var afterProjectileHitEvent = new AfterProjectileHitEvent(component.Damage, target, otherFixture); - RaiseLocalEvent(uid, ref afterProjectileHitEvent); - if (component.DeleteOnCollide) QueueDel(uid); @@ -114,7 +96,5 @@ public sealed class ProjectileSystem : SharedProjectileSystem { RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager)); } - - return !deleted; } } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index f77e61f06d..c84e92f24e 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -3,7 +3,6 @@ using System.Numerics; 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.Server._White.Crossbow; @@ -38,7 +37,6 @@ public sealed partial class GunSystem : SharedGunSystem [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!; @@ -69,137 +67,6 @@ public sealed partial class GunSystem : SharedGunSystem 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(ammo.Count); - var cartridgeBullets = new List(); - - 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, [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), null); - // 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) { @@ -207,7 +74,7 @@ public sealed partial class GunSystem : SharedGunSystem // Try a clumsy roll // TODO: Who put this here - if (TryComp(user, out var clumsy) && !gun.ClumsyProof) + if (TryComp(user, out var clumsy) && gun.ClumsyProof == false) { for (var i = 0; i < ammo.Count; i++) { @@ -230,8 +97,6 @@ public sealed partial class GunSystem : SharedGunSystem } } - // 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; @@ -258,7 +123,6 @@ public sealed partial class GunSystem : SharedGunSystem // I must be high because this was getting tripped even when true. // DebugTools.Assert(direction != Vector2.Zero); var shotProjectiles = new List(ammo.Count); - var cartridgeBullets = new List(); foreach (var (ent, shootable) in ammo) { @@ -287,23 +151,21 @@ public sealed partial class GunSystem : SharedGunSystem { var uid = Spawn(cartridge.Prototype, fromEnt); ShootOrThrow(uid, angles[i].ToVec(), gunVelocity, gun, gunUid, user); - cartridgeBullets.Add(uid); + shotProjectiles.Add(uid); } } else { var uid = Spawn(cartridge.Prototype, fromEnt); ShootOrThrow(uid, mapDirection, gunVelocity, gun, gunUid, user); - cartridgeBullets.Add(uid); + shotProjectiles.Add(uid); } RaiseLocalEvent(ent!.Value, new AmmoShotEvent() { - FiredProjectiles = cartridgeBullets, + FiredProjectiles = shotProjectiles, }); - shotProjectiles.AddRange(cartridgeBullets); - cartridgeBullets.Clear(); SetCartridgeSpent(ent.Value, cartridge, true); MuzzleFlash(gunUid, cartridge, user); Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user); diff --git a/Content.Shared/Execution/DoafterEvent.cs b/Content.Shared/Execution/DoafterEvent.cs deleted file mode 100644 index 7854974527..0000000000 --- a/Content.Shared/Execution/DoafterEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.Execution; - -[Serializable, NetSerializable] -public sealed partial class ExecutionDoAfterEvent : SimpleDoAfterEvent -{ -} diff --git a/Content.Shared/Execution/ExecutionComponent.cs b/Content.Shared/Execution/ExecutionComponent.cs deleted file mode 100644 index f9c5111d63..0000000000 --- a/Content.Shared/Execution/ExecutionComponent.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Robust.Shared.GameStates; - -namespace Content.Shared.Execution; - -/// -/// Added to entities that can be used to execute another target. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class ExecutionComponent : Component -{ - /// - /// How long the execution duration lasts. - /// - [DataField, AutoNetworkedField] - public float DoAfterDuration = 5f; - - [DataField, AutoNetworkedField] - public float DamageModifier = 9f; - - // Not networked because this is transient inside of a tick. - /// - /// True if it is currently executing for handlers. - /// - [DataField] - public bool Executing = true; -} diff --git a/Content.Shared/Execution/ExecutionSystem.cs b/Content.Shared/Execution/ExecutionSystem.cs deleted file mode 100644 index 602f01f94a..0000000000 --- a/Content.Shared/Execution/ExecutionSystem.cs +++ /dev/null @@ -1,244 +0,0 @@ -using Content.Shared.Weapons.Ranged.Systems; -using Content.Shared.ActionBlocker; -using Content.Shared.CombatMode; -using Content.Shared.Damage; -using Content.Shared.Database; -using Content.Shared.DoAfter; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Popups; -using Content.Shared.Verbs; -using Content.Shared.Weapons.Melee; -using Content.Shared.Weapons.Melee.Events; -using Content.Shared.Weapons.Ranged.Components; -using Robust.Shared.Player; - -namespace Content.Shared.Execution; - -/// -/// Verb for violently murdering cuffed creatures. -/// -public sealed class ExecutionSystem : EntitySystem -{ - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; - [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly MobStateSystem _mobStateSystem = default!; - [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; - [Dependency] private readonly SharedGunSystem _gunSystem = default!; - [Dependency] private readonly SharedCombatModeSystem _combatSystem = default!; - [Dependency] private readonly SharedMeleeWeaponSystem _meleeSystem = default!; - - // TODO: Still needs more cleaning up. - private const string DefaultInternalMeleeExecutionMessage = "execution-popup-melee-initial-internal"; - private const string DefaultExternalMeleeExecutionMessage = "execution-popup-melee-initial-external"; - private const string DefaultCompleteInternalMeleeExecutionMessage = "execution-popup-melee-complete-internal"; - private const string DefaultCompleteExternalMeleeExecutionMessage = "execution-popup-melee-complete-external"; - private const string DefaultInternalGunExecutionMessage = "execution-popup-gun-initial-internal"; - private const string DefaultExternalGunExecutionMessage = "execution-popup-gun-initial-external"; - private const string DefaultCompleteInternalGunExecutionMessage = "execution-popup-gun-complete-internal"; - private const string DefaultCompleteExternalGunExecutionMessage = "execution-popup-gun-complete-external"; - - /// - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent>(OnGetInteractionsVerbs); - SubscribeLocalEvent(OnExecutionDoAfter); - SubscribeLocalEvent(OnGetMeleeDamage); - } - - private void OnGetInteractionsVerbs(EntityUid uid, ExecutionComponent comp, GetVerbsEvent args) - { - if (args.Hands == null || args.Using == null || !args.CanAccess || !args.CanInteract) - return; - - var attacker = args.User; - var weapon = args.Using.Value; - var victim = args.Target; - - if (!CanExecuteWithAny(victim, attacker)) - return; - - UtilityVerb verb = new() - { - Act = () => TryStartExecutionDoAfter(weapon, victim, attacker, comp), - Impact = LogImpact.High, - Text = Loc.GetString("execution-verb-name"), - Message = Loc.GetString("execution-verb-message"), - }; - - args.Verbs.Add(verb); - } - - private void TryStartExecutionDoAfter( - EntityUid weapon, - EntityUid victim, - EntityUid attacker, - ExecutionComponent comp) - { - if (!CanExecuteWithAny(victim, attacker)) - return; - - // TODO: This should just be on the weapons as a single execution message. - var defaultExecutionInternal = DefaultInternalMeleeExecutionMessage; - var defaultExecutionExternal = DefaultExternalMeleeExecutionMessage; - - if (HasComp(weapon)) - { - defaultExecutionExternal = DefaultInternalGunExecutionMessage; - defaultExecutionInternal = DefaultExternalGunExecutionMessage; - } - - var internalMsg = defaultExecutionInternal; - var externalMsg = defaultExecutionExternal; - ShowExecutionInternalPopup(internalMsg, attacker, victim, weapon); - ShowExecutionExternalPopup(externalMsg, attacker, victim, weapon); - - var doAfter = new DoAfterArgs(EntityManager, attacker, comp.DoAfterDuration, new ExecutionDoAfterEvent(), - weapon, target: victim, used: weapon) - { - BreakOnMove = true, - BreakOnDamage = true, - NeedHand = true - }; - - _doAfterSystem.TryStartDoAfter(doAfter); - } - - private bool CanExecuteWithAny(EntityUid victim, EntityUid attacker) - { - // Use suicide. - if (victim == attacker) - return false; - - // No point executing someone if they can't take damage - if (!TryComp(victim, out _)) - return false; - - // You can't execute something that cannot die - if (!TryComp(victim, out var mobState)) - return false; - - // You're not allowed to execute dead people (no fun allowed) - if (_mobStateSystem.IsDead(victim, mobState)) - return false; - - // You must be able to attack people to execute - if (!_actionBlockerSystem.CanAttack(attacker, victim)) - return false; - - // The victim must be incapacitated to be executed - if (victim != attacker && _actionBlockerSystem.CanInteract(victim, null)) - return false; - - // All checks passed - return true; - } - - private void OnExecutionDoAfter(EntityUid uid, ExecutionComponent component, ExecutionDoAfterEvent args) - { - if (args.Handled || args.Cancelled || args.Used == null || args.Target == null) - return; - - var attacker = args.User; - var victim = args.Target.Value; - var weapon = args.Used.Value; - - if (!CanExecuteWithAny(victim, attacker)) - return; - - // This is needed so the melee system does not stop it. - var prev = _combatSystem.IsInCombatMode(attacker); - _combatSystem.SetInCombatMode(attacker, true); - component.Executing = true; - string? internalMsg = null; - string? externalMsg = null; - - if (TryComp(uid, out MeleeWeaponComponent? melee)) - { - _meleeSystem.AttemptLightAttack(attacker, weapon, melee, victim); - internalMsg = DefaultCompleteInternalMeleeExecutionMessage; - externalMsg = DefaultCompleteExternalMeleeExecutionMessage; - } - else if (TryComp(uid, out GunComponent? gun)) - { - // TODO: This should just be an event or something instead to get this. - // TODO: Handle clumsy. - if (!_gunSystem.AttemptDirectShoot(args.User, uid, args.Target.Value, gun)) - { - internalMsg = null; - externalMsg = null; - } - else - { - internalMsg = DefaultCompleteInternalGunExecutionMessage; - externalMsg = DefaultCompleteExternalGunExecutionMessage; - } - - args.Handled = true; - } - - _combatSystem.SetInCombatMode(attacker, prev); - component.Executing = false; - args.Handled = true; - - if (internalMsg != null && externalMsg != null) - { - ShowExecutionInternalPopup(internalMsg, attacker, victim, uid); - ShowExecutionExternalPopup(externalMsg, attacker, victim, uid); - } - } - - private void OnGetMeleeDamage(EntityUid uid, ExecutionComponent comp, ref GetMeleeDamageEvent args) - { - if (!TryComp(uid, out var melee) || - !TryComp(uid, out var execComp) || - !execComp.Executing) - { - return; - } - - var bonus = melee.Damage * execComp.DamageModifier - melee.Damage; - args.Damage += bonus; - } - - private void ShowExecutionInternalPopup( - string locString, - EntityUid attacker, - EntityUid victim, - EntityUid weapon, - bool predict = true) - { - if (predict) - { - _popupSystem.PopupClient( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), - attacker, - attacker, - PopupType.Medium - ); - } - else - { - _popupSystem.PopupEntity( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), - attacker, - Filter.Entities(attacker), - true, - PopupType.Medium - ); - } - } - - private void ShowExecutionExternalPopup(string locString, EntityUid attacker, EntityUid victim, EntityUid weapon) - { - _popupSystem.PopupEntity( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), - attacker, - Filter.PvsExcept(attacker), - true, - PopupType.MediumCaution - ); - } -} \ No newline at end of file diff --git a/Content.Shared/Projectiles/SharedProjectileSystem.cs b/Content.Shared/Projectiles/SharedProjectileSystem.cs index 97330f598f..d72df753da 100644 --- a/Content.Shared/Projectiles/SharedProjectileSystem.cs +++ b/Content.Shared/Projectiles/SharedProjectileSystem.cs @@ -308,9 +308,3 @@ public record struct ProjectileReflectAttemptEvent(EntityUid ProjUid, Projectile /// [ByRefEvent] public record struct ProjectileHitEvent(DamageSpecifier Damage, EntityUid Target, EntityUid? Shooter = null); - -/// -/// Raised after a projectile has dealt it's damage. -/// -[ByRefEvent] -public record struct AfterProjectileHitEvent(DamageSpecifier Damage, EntityUid Target, Fixture? Fixture); diff --git a/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs b/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs index 6325d95330..40925ad614 100644 --- a/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs +++ b/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs @@ -19,7 +19,7 @@ public record struct ShotAttemptedEvent public bool Cancelled { get; private set; } - /// + /// /// Prevent the gun from shooting /// public void Cancel() @@ -27,7 +27,7 @@ public record struct ShotAttemptedEvent Cancelled = true; } - /// + /// /// Allow the gun to shoot again, only use if you know what you are doing /// public void Uncancel() diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 55fbe362b1..e5b91e876f 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -22,7 +22,6 @@ using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; -using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; @@ -142,7 +141,7 @@ public abstract partial class SharedGunSystem : EntitySystem gun.ShootCoordinates = GetCoordinates(msg.Coordinates); gun.Target = GetEntity(msg.Target); Log.Debug($"Set shoot coordinates to {gun.ShootCoordinates}"); - AttemptShootInternal(user.Value, ent, gun); + AttemptShoot(user.Value, ent, gun); } private void OnStopShootRequest(RequestStopShootEvent ev, EntitySessionEventArgs args) @@ -206,38 +205,13 @@ public abstract partial class SharedGunSystem : EntitySystem Dirty(uid, gun); } - /// - /// Attempts to shoot the specified target directly. - /// This may bypass projectiles firing etc. - /// - public bool AttemptDirectShoot(EntityUid user, EntityUid gunUid, EntityUid target, GunComponent gun) - { - // Unique name so people don't think it's "shoot towards" and not "I will teleport a bullet into them". - gun.ShootCoordinates = Transform(target).Coordinates; - - if (!TryTakeAmmo(user, gunUid, gun, out _, out _, out var args)) - { - gun.ShootCoordinates = null; - return false; - } - - var result = ShootDirect(gunUid, gun, target, args.Ammo, user: user); - gun.ShootCoordinates = null; - return result; - } - - protected virtual bool ShootDirect(EntityUid gunUid, GunComponent gun, EntityUid target, List<(EntityUid? Entity, IShootable Shootable)> ammo, EntityUid user) - { - return false; - } - /// /// Attempts to shoot at the target coordinates. Resets the shot counter after every shot. /// public void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun, EntityCoordinates toCoordinates) { gun.ShootCoordinates = toCoordinates; - AttemptShootInternal(user, gunUid, gun); + AttemptShoot(user, gunUid, gun); gun.ShotCounter = 0; } @@ -248,35 +222,20 @@ public abstract partial class SharedGunSystem : EntitySystem { var coordinates = new EntityCoordinates(gunUid, new Vector2(0, -1)); gun.ShootCoordinates = coordinates; - AttemptShootInternal(gunUid, gunUid, gun); + AttemptShoot(gunUid, gunUid, gun); gun.ShotCounter = 0; } - private void AttemptShootInternal(EntityUid user, EntityUid gunUid, GunComponent gun) - { - if (!TryTakeAmmo(user, gunUid, gun, out var fromCoordinates, out var toCoordinates, out var args)) - return; - - Shoot(gunUid, gun, args.Ammo, fromCoordinates, toCoordinates, out var userImpulse, user: user); - - if (userImpulse && TryComp(user, out var userPhysics)) - { - if (_gravity.IsWeightless(user, userPhysics)) - CauseImpulse(fromCoordinates, toCoordinates, user, userPhysics); - } - } - - /// - /// Validates if a gun can currently shoot. - /// - [Pure] - private bool CanShoot(EntityUid user, EntityUid gunUid, GunComponent gun) + private void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun) { if (gun.FireRateModified <= 0f || !_actionBlockerSystem.CanAttack(user)) - { - return false; - } + return; + + var toCoordinates = gun.ShootCoordinates; + + if (toCoordinates == null) + return; var curTime = Timing.CurTime; @@ -288,42 +247,17 @@ public abstract partial class SharedGunSystem : EntitySystem }; RaiseLocalEvent(gunUid, ref prevention); if (prevention.Cancelled) - return false; + return; RaiseLocalEvent(user, ref prevention); if (prevention.Cancelled) - return false; + return; // Need to do this to play the clicking sound for empty automatic weapons // but not play anything for burst fire. if (gun.NextFire > curTime) - return false; + return; - return true; - } - - /// - /// Tries to return ammo prepped for shooting if a gun is available to shoot. - /// - private bool TryTakeAmmo( - EntityUid user, - EntityUid gunUid, GunComponent gun, - out EntityCoordinates fromCoordinates, - out EntityCoordinates toCoordinates, - [NotNullWhen(true)] out TakeAmmoEvent? args) - { - toCoordinates = EntityCoordinates.Invalid; - fromCoordinates = EntityCoordinates.Invalid; - args = null; - - if (!CanShoot(user, gunUid, gun)) - return false; - - if (gun.ShootCoordinates == null) - return false; - - toCoordinates = gun.ShootCoordinates.Value; - var curTime = Timing.CurTime; var fireRate = TimeSpan.FromSeconds(1f / gun.FireRateModified); // First shot @@ -375,11 +309,10 @@ public abstract partial class SharedGunSystem : EntitySystem } gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds)); - return false; + return; } - fromCoordinates = Transform(user).Coordinates; - + var fromCoordinates = Transform(user).Coordinates; // Remove ammo var ev = new TakeAmmoEvent(shots, new List<(EntityUid? Entity, IShootable Shootable)>(), fromCoordinates, user); @@ -414,18 +347,24 @@ public abstract partial class SharedGunSystem : EntitySystem // May cause prediction issues? Needs more tweaking gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds)); Audio.PlayPredicted(gun.SoundEmpty, gunUid, user); - return false; + return; } - return false; + return; } // Shoot confirmed - sounds also played here in case it's invalid (e.g. cartridge already spent). + Shoot(gunUid, gun, ev.Ammo, fromCoordinates, toCoordinates.Value, out var userImpulse, user, throwItems: attemptEv.ThrowItems); var shotEv = new GunShotEvent(user, ev.Ammo); RaiseLocalEvent(gunUid, ref shotEv); - args = ev; - return true; + if (userImpulse && TryComp(user, out var userPhysics)) + { + if (_gravity.IsWeightless(user, userPhysics)) + CauseImpulse(fromCoordinates, toCoordinates.Value, user, userPhysics); + } + + Dirty(gunUid, gun); } public void Shoot( diff --git a/Resources/Locale/en-US/execution/execution.ftl b/Resources/Locale/en-US/execution/execution.ftl deleted file mode 100644 index 5bd4613e8c..0000000000 --- a/Resources/Locale/en-US/execution/execution.ftl +++ /dev/null @@ -1,20 +0,0 @@ -execution-verb-name = Execute -execution-verb-message = Use your weapon to execute someone. - -# All the below localisation strings have access to the following variables -# attacker (the person committing the execution) -# victim (the person being executed) -# weapon (the weapon used for the execution) - -execution-popup-gun-initial-internal = You ready the muzzle of {THE($weapon)} against {$victim}'s head. -execution-popup-gun-initial-external = {$attacker} readies the muzzle of {THE($weapon)} against {$victim}'s head. -execution-popup-gun-complete-internal = You blast {$victim} in the head! -execution-popup-gun-complete-external = {$attacker} blasts {$victim} in the head! -execution-popup-gun-clumsy-internal = You miss {$victim}'s head and shoot your foot instead! -execution-popup-gun-clumsy-external = {$attacker} misses {$victim} and shoots {POSS-ADJ($attacker)} foot instead! -execution-popup-gun-empty = {CAPITALIZE(THE($weapon))} clicks. - -execution-popup-melee-initial-internal = You ready {THE($weapon)} against {$victim}'s throat. -execution-popup-melee-initial-external = {$attacker} readies {POSS-ADJ($attacker)} {$weapon} against the throat of {$victim}. -execution-popup-melee-complete-internal = You slit the throat of {$victim}! -execution-popup-melee-complete-external = {$attacker} slits the throat of {$victim}! diff --git a/Resources/Locale/en-US/kitchen/components/butcherable-component.ftl b/Resources/Locale/en-US/kitchen/components/butcherable-component.ftl index 4a83cd455d..ff28cc44db 100644 --- a/Resources/Locale/en-US/kitchen/components/butcherable-component.ftl +++ b/Resources/Locale/en-US/kitchen/components/butcherable-component.ftl @@ -1,4 +1,4 @@ -butcherable-different-tool = You need a different tool to butcher { THE($target) }. +butcherable-different-tool = You are going to need a different tool to butcher { THE($target) }. butcherable-knife-butchered-success = You butcher { THE($target) } with { THE($knife) }. butcherable-need-knife = Use a sharp object to butcher { THE($target) }. butcherable-not-in-container = { CAPITALIZE(THE($target)) } can't be in a container. diff --git a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml index 47828ed8f5..8f522abce4 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml @@ -6,8 +6,6 @@ description: A small piece of crystal. components: - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: Sprite layers: - sprite: Objects/Materials/Shards/crystal.rsi diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index 5c69fd6e40..b565d14508 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -5,8 +5,6 @@ description: It's a shard of some unknown material. components: - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: Sprite layers: - sprite: Objects/Materials/Shards/shard.rsi diff --git a/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml b/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml index 98bc92968b..b7c73f5e0c 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml @@ -5,8 +5,6 @@ description: In Space Glasgow this is called a conversation starter. components: - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: MeleeWeapon attackRate: 1.5 damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml index 236ed20681..9d685e1ddc 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml @@ -19,7 +19,6 @@ path: /Audio/Weapons/Guns/Empty/lmg_empty.ogg - type: StaticPrice price: 500 - - type: Execution # No chamber because HMG may want its own - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml index 499a950e78..49b2eeaada 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -60,7 +60,6 @@ price: 500 - type: UseDelay delay: 1 - - type: Execution - type: entity name: L6 SAW diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index a84ecb215d..1315eb6de1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -19,7 +19,6 @@ containers: ballistic-ammo: !type:Container ents: [] - - type: Execution - type: entity name: china lake diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml index 613d94fbf2..a607ccb06c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml @@ -66,7 +66,6 @@ - type: AmmoCounter - type: StaticPrice price: 500 - - type: Execution - type: entity name: viper @@ -201,7 +200,7 @@ name: N1984 parent: BaseWeaponPistol id: WeaponPistolN1984 # the spaces in description are for formatting. - description: The sidearm of any self respecting officer. Comes in .45 magnum, the lord's caliber. + description: The sidearm of any self respecting officer. Comes in .45 magnum, the lord's caliber. components: - type: Sprite sprite: Objects/Weapons/Guns/Pistols/N1984.rsi diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index 243eb7c16b..36f36a101a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -50,7 +50,6 @@ gun_chamber: !type:ContainerSlot - type: StaticPrice price: 500 - - type: Execution - type: entity name: AKMS diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index 5cedc1feac..790c27f414 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -54,7 +54,6 @@ gun_chamber: !type:ContainerSlot - type: StaticPrice price: 500 - - type: Execution - type: entity name: Atreides diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml index 0ab12d8a1a..25949f933a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml @@ -43,7 +43,6 @@ ents: [] - type: StaticPrice price: 500 - - type: Execution - type: entity name: Bulldog @@ -100,7 +99,6 @@ - type: Appearance - type: StaticPrice price: 500 - - type: Execution - type: entity name: double-barreled shotgun diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index 315d527b77..bef349e8af 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -38,7 +38,6 @@ ents: [] - type: StaticPrice price: 500 - - type: Execution - type: entity name: Kardashev-Mosin diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml index 8a6cc46eca..9b046a7aae 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml @@ -37,4 +37,3 @@ slots: - Belt - suitStorage - - type: Execution diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml index add776422d..ae1f5df3c1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml @@ -107,7 +107,6 @@ containers: storagebase: !type:Container ents: [] - - type: Execution # shoots bullets instead of throwing them, no other changes - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml index 28a0832b0d..2814c4202c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml @@ -5,8 +5,6 @@ description: A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter. components: - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: Sprite sprite: Objects/Weapons/Melee/armblade.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml index 66aa857da4..61bd2c9334 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml @@ -8,8 +8,6 @@ tags: - FireAxe - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: Sprite sprite: Objects/Weapons/Melee/fireaxe.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml index 7bac8251db..6827f3a3e8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml @@ -7,8 +7,6 @@ tags: - Knife - type: Sharp - - type: Execution - doAfterDuration: 4.0 - type: Utensil types: - Knife diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml index 66fbb3e086..0745425e9d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml @@ -1,21 +1,10 @@ -- type: entity - name: Sword - parent: BaseItem - id: BaseSword - description: A sharp sword. - abstract: true - components: - - type: Sharp - - type: Execution - doAfterDuration: 4.0 - - type: DisarmMalus - - type: entity name: captain's sabre - parent: BaseSword + parent: BaseItem id: CaptainSabre description: A ceremonial weapon belonging to the captain of the station. components: + - type: Sharp - type: Sprite sprite: Objects/Weapons/Melee/captain_sabre.rsi state: icon @@ -38,13 +27,15 @@ - type: Tag tags: - CaptainSabre + - type: DisarmMalus - type: entity name: katana - parent: BaseSword + parent: BaseItem id: Katana description: Ancient craftwork made with not so ancient plasteel. components: + - type: Sharp - type: Tag tags: - Katana @@ -67,6 +58,7 @@ - Back - Belt - SuitStorage + - type: DisarmMalus - type: entity name: energy katana @@ -102,10 +94,11 @@ - type: entity name: machete - parent: BaseSword + parent: BaseItem id: Machete description: A large, vicious looking blade. components: + - type: Sharp - type: Tag tags: - Machete @@ -127,6 +120,7 @@ slots: - Belt - SuitStorage + - type: DisarmMalus - type: Construction deconstructionTarget: null graph: SwordGraph @@ -134,10 +128,11 @@ - type: entity name: claymore - parent: BaseSword + parent: BaseItem id: Claymore description: An ancient war blade. components: + - type: Sharp - type: Sprite sprite: Objects/Weapons/Melee/claymore.rsi state: icon @@ -157,6 +152,7 @@ - back - belt - suitStorage + - type: DisarmMalus - type: Construction deconstructionTarget: null graph: SwordGraph @@ -164,10 +160,11 @@ - type: entity name: cutlass - parent: BaseSword + parent: BaseItem id: Cutlass description: A wickedly curved blade, often seen in the hands of space pirates. components: + - type: Sharp - type: Tag tags: - Machete @@ -184,13 +181,15 @@ - type: Item size: Large sprite: Objects/Weapons/Melee/cutlass.rsi + - type: DisarmMalus - type: entity name: The Throngler - parent: BaseSword + parent: BaseItem id: Throngler description: Why would you make this? components: + - type: Sharp - type: Sprite sprite: Objects/Weapons/Melee/Throngler2.rsi state: icon @@ -214,3 +213,4 @@ - type: Item size: Ginormous sprite: Objects/Weapons/Melee/Throngler-in-hand.rsi + - type: DisarmMalus