From b771193fe4fd7009a8ea64d38348e281407c3748 Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Sun, 21 Apr 2024 19:59:17 +0100 Subject: [PATCH 1/8] Weapon Reflection Movement Mechanic Adds a movement mechanic to deflection. Standing still gives you your best chance of deflecting a shot. Moving lowers this to 2/3rds. Sprinting to 1/3rd. This allows for robust players to express better and provides counterplay to someone finding a goober-strong deflection weapon, giving more design space. As part of this PR I've also touched the numbers of a few swords, shields, etc. and modified some descriptions to make them read better. The balance numbers are not remotely final, but as intent: 1. All the sidearm swords (katana, cutlass, captain's sabre) have the same damage. There's no good reason the "ceremonial" blade the captain has doing more damage than a katana. 2. The Captain's Sabre has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting. This one is controversial due to the recent nerf, I suspect: This could easily be 15->10->5? 3. The Energy Katana has a flat 30% reflect chance. 4. The meme Throngler has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting. 5. The E-Sword has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting. 6. The Double E-Sword has a mighty 75% reflect chance, dropping to 50% and then 25%. 7. Both reflective shields - Mirror and Energy - have a 95% deflect chance, dropping to 63% then 31%. --- .../Weapons/Reflect/ReflectComponent.cs | 19 +++++++++ .../Weapons/Reflect/ReflectSystem.cs | 41 ++++++++++++++++++- Resources/Prototypes/Anomaly/behaviours.yml | 1 + .../Entities/Clothing/OuterClothing/armor.yml | 1 + .../Entities/Mobs/NPCs/hellspawn.yml | 1 + .../Entities/Objects/Shields/shields.yml | 6 +-- .../Objects/Weapons/Melee/e_sword.yml | 5 ++- .../Entities/Objects/Weapons/Melee/sword.yml | 13 +++--- 8 files changed, 75 insertions(+), 12 deletions(-) diff --git a/Content.Shared/Weapons/Reflect/ReflectComponent.cs b/Content.Shared/Weapons/Reflect/ReflectComponent.cs index 8e7b8975d9d1..1fa66d71eec4 100644 --- a/Content.Shared/Weapons/Reflect/ReflectComponent.cs +++ b/Content.Shared/Weapons/Reflect/ReflectComponent.cs @@ -32,6 +32,25 @@ public sealed partial class ReflectComponent : Component [DataField("soundOnReflect")] public SoundSpecifier? SoundOnReflect = new SoundPathSpecifier("/Audio/Weapons/Guns/Hits/laser_sear_wall.ogg"); + + /// + /// Is the deflection an innate power or something actively maintained? If true, this component grants a flat + /// deflection chance rather than a chance that degrades when moving/weightless/stunned/etc. + /// + [DataField] + public bool Innate = false; + + /// + /// The multiplier used when moving. + /// + [DataField] + public float MovingProbMultiplier = 0.66f; + + /// + /// The multiplier used when sprinting or when otherwise compromised (e.g. weightless) + /// + [DataField] + public float SprintingProbMultiplier = 0.33f; } [Flags] diff --git a/Content.Shared/Weapons/Reflect/ReflectSystem.cs b/Content.Shared/Weapons/Reflect/ReflectSystem.cs index 4a7c2f6b6a7b..96f50d54856f 100644 --- a/Content.Shared/Weapons/Reflect/ReflectSystem.cs +++ b/Content.Shared/Weapons/Reflect/ReflectSystem.cs @@ -1,14 +1,21 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; +using Content.Shared.ActionBlocker; using Content.Shared.Administration.Logs; using Content.Shared.Audio; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Systems; using Content.Shared.Database; +using Content.Shared.Gravity; using Content.Shared.Hands; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Item.ItemToggle.Components; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Projectiles; +using Content.Shared.Standing; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; using Robust.Shared.Audio; @@ -35,6 +42,9 @@ public sealed class ReflectSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly SharedGravitySystem _gravity = default!; + [Dependency] private readonly StandingStateSystem _standing = default!; + [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; public override void Initialize() { @@ -91,16 +101,43 @@ private void OnReflectCollide(EntityUid uid, ReflectComponent component, ref Pro private bool TryReflectProjectile(EntityUid user, EntityUid reflector, EntityUid projectile, ProjectileComponent? projectileComp = null, ReflectComponent? reflect = null) { + // Do we have the components needed to try a reflect at all? if (!Resolve(reflector, ref reflect, false) || !reflect.Enabled || !TryComp(projectile, out var reflective) || (reflect.Reflects & reflective.Reflective) == 0x0 || - !_random.Prob(reflect.ReflectProb) || !TryComp(projectile, out var physics)) - { return false; + + var reflectChance = reflect.ReflectProb; + + /* + * The rules of deflection are as follows: + * If you innately reflect things via magic, biology etc, you always have a full chance. + * If you are standing up and standing still, you're prepared to deflect and have full chance. + * If you are moving at all, your chance is multiplied by the movingProbMultiplier. + * If you are recklessly sprinting, your chance is instead multiplied by the sprintingProbMultiplier. + * If you floating, your chance is instead multiplied by the sprintingProbMultiplier. + * You cannot deflect if you are knocked down or stunned. + */ + + if (!reflect.Innate) + { + if (TryComp(reflector, out var staminaComponent) && staminaComponent.Critical) + return false; + + if (_standing.IsDown(reflector)) + return false; + + if (_gravity.IsWeightless(reflector)) + reflectChance *= reflect.SprintingProbMultiplier; + else if (TryComp(reflector, out var mover) && (mover.HeldMoveButtons & MoveButtons.AnyDirection) == MoveButtons.AnyDirection) + reflectChance *= mover.Sprinting ? reflect.SprintingProbMultiplier : reflect.MovingProbMultiplier; } + if (!_random.Prob(reflectChance)) + return false; + var rotation = _random.NextAngle(-reflect.Spread / 2, reflect.Spread / 2).Opposite(); var existingVelocity = _physics.GetMapLinearVelocity(projectile, component: physics); var relativeVelocity = existingVelocity - _physics.GetMapLinearVelocity(user); diff --git a/Resources/Prototypes/Anomaly/behaviours.yml b/Resources/Prototypes/Anomaly/behaviours.yml index aa9ad2f90d37..71595a5bb66c 100644 --- a/Resources/Prototypes/Anomaly/behaviours.yml +++ b/Resources/Prototypes/Anomaly/behaviours.yml @@ -84,6 +84,7 @@ description: anomaly-behavior-reflect components: - type: Reflect + innate: true reflectProb: 0.5 reflects: - Energy diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 9a1f14274024..574b83388b12 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -96,6 +96,7 @@ Heat: 0.4 # this technically means it protects against fires pretty well? -heat is just for lasers and stuff, not atmos temperature - type: Reflect reflectProb: 1 + innate: true # armor grants a passive shield that does not require concentration to maintain reflects: - Energy diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml index 5511c40baade..2f5ce292660c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml @@ -53,6 +53,7 @@ - type: Perishable - type: Reflect reflectProb: 0.7 + innate: true reflects: - Energy - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index b794e42ff7d3..f58db21c25a1 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -313,14 +313,14 @@ name: mirror shield parent: BaseShield id: MirrorShield - description: Eerily glows red... you hear the geometer whispering + description: Eerily glows red. You hear the geometer whispering... components: - type: Sprite state: mirror-icon - type: Item heldPrefix: mirror - type: Reflect - reflectProb: 0.95 + reflectProb: 0.95 # 0.63 when moving, 0.31 when sprinting reflects: - Energy - type: Blocking #Mirror shield reflects heat/laser, but is relatively weak to everything else. @@ -407,7 +407,7 @@ color: blue - type: Reflect enabled: false - reflectProb: 0.95 + reflectProb: 0.95 # 0.63 when moving, 0.31 when sprinting reflects: - Energy - type: Blocking diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 13c8b9cb25c5..18d8d51e5612 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -78,6 +78,7 @@ malus: 0 - type: Reflect enabled: false + reflectProb: 0.3 # 0.2 when moving, 0.1 when sprinting - type: IgnitionSource temperature: 700 @@ -218,7 +219,7 @@ name: double-bladed energy sword parent: EnergySword id: EnergySwordDouble - description: Syndicate Command Interns thought that having one blade on the energy sword was not enough. This can be stored in pockets. + description: Syndicate Command's intern thought that having only one blade on energy swords was not cool enough. This can be stored in pockets. components: - type: EnergySword - type: ItemToggle @@ -269,7 +270,7 @@ size: Small sprite: Objects/Weapons/Melee/e_sword_double-inhands.rsi - type: Reflect - reflectProb: .75 + reflectProb: .75 # 0.5 when moving, 0.25 when sprinting. spread: 75 - type: UseDelay delay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml index 7cc33b715501..e5795a27fab6 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml @@ -13,12 +13,12 @@ attackRate: 1.5 damage: types: - Slash: 17 #cmon, it has to be at least BETTER than the rest. + Slash: 15 soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Reflect enabled: true - reflectProb: .1 + reflectProb: .3 # 0.2 when moving, 0.1 when sprinting. spread: 90 - type: Item size: Normal @@ -83,6 +83,9 @@ - Back - Belt - type: Reflect + reflectProb: 0.3 + movingProbMultiplier: 1.0 # don't punish ninjas for being ninjas + sprintingProbMultiplier: 1.0 # it's a ninja weapon. you run around and slice bullets in half - type: entity name: machete @@ -152,7 +155,7 @@ wideAnimationRotation: -135 damage: types: - Slash: 16 + Slash: 15 soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item @@ -164,7 +167,7 @@ name: The Throngler parent: BaseItem id: Throngler - description: Why would you make this? + description: Why would someone make this? components: - type: Sharp - type: Sprite @@ -185,7 +188,7 @@ path: /Audio/Effects/explosion_small1.ogg - type: Reflect enabled: true - reflectProb: .25 + reflectProb: .3 # 0.2 when moving, 0.1 when sprinting spread: 90 - type: Item size: Ginormous From cc76aa5d664bf5debbe6215bfa7525eb3181fb6e Mon Sep 17 00:00:00 2001 From: Hannah FairlySadPanda Dawson Date: Tue, 23 Apr 2024 19:49:05 +0100 Subject: [PATCH 2/8] Resolve PR comments. --- .../Weapons/Reflect/ReflectComponent.cs | 26 ++++--- .../Weapons/Reflect/ReflectSystem.cs | 74 +++++++++++-------- .../Entities/Clothing/Head/misc.yml | 11 +++ .../Entities/Objects/Shields/shields.yml | 6 +- .../Objects/Weapons/Melee/e_sword.yml | 6 +- .../Entities/Objects/Weapons/Melee/sword.yml | 16 +++- 6 files changed, 90 insertions(+), 49 deletions(-) diff --git a/Content.Shared/Weapons/Reflect/ReflectComponent.cs b/Content.Shared/Weapons/Reflect/ReflectComponent.cs index 1fa66d71eec4..5d8432ac776c 100644 --- a/Content.Shared/Weapons/Reflect/ReflectComponent.cs +++ b/Content.Shared/Weapons/Reflect/ReflectComponent.cs @@ -21,12 +21,6 @@ public sealed partial class ReflectComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField("reflects")] public ReflectType Reflects = ReflectType.Energy | ReflectType.NonEnergy; - /// - /// Probability for a projectile to be reflected. - /// - [DataField("reflectProb"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float ReflectProb = 0.25f; - [DataField("spread"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public Angle Spread = Angle.FromDegrees(45); @@ -41,16 +35,28 @@ public sealed partial class ReflectComponent : Component public bool Innate = false; /// - /// The multiplier used when moving. + /// Maximum probability for a projectile to be reflected. + /// + [DataField("reflectProb"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float ReflectProb = 0.25f; + + /// + /// The maximum velocity a wielder can move at before losing effectiveness. + /// + [DataField] + public float VelocityBeforeNotMaxProb = 2.5f; // Walking speed for a human. Suitable for a weightless deflector like an e-sword. + + /// + /// The velocity a wielder has to be moving at to use the minimum effectiveness value. /// [DataField] - public float MovingProbMultiplier = 0.66f; + public float VelocityBeforeMinProb = 4.5f; // Sprinting speed for a human. Suitable for a weightless deflector like an e-sword. /// - /// The multiplier used when sprinting or when otherwise compromised (e.g. weightless) + /// Minimum probability for a projectile to be reflected. /// [DataField] - public float SprintingProbMultiplier = 0.33f; + public float MinReflectProb = 0.1f; } [Flags] diff --git a/Content.Shared/Weapons/Reflect/ReflectSystem.cs b/Content.Shared/Weapons/Reflect/ReflectSystem.cs index 96f50d54856f..6a08dc2747ba 100644 --- a/Content.Shared/Weapons/Reflect/ReflectSystem.cs +++ b/Content.Shared/Weapons/Reflect/ReflectSystem.cs @@ -44,7 +44,6 @@ public sealed class ReflectSystem : EntitySystem [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly StandingStateSystem _standing = default!; - [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; public override void Initialize() { @@ -102,40 +101,18 @@ private void OnReflectCollide(EntityUid uid, ReflectComponent component, ref Pro private bool TryReflectProjectile(EntityUid user, EntityUid reflector, EntityUid projectile, ProjectileComponent? projectileComp = null, ReflectComponent? reflect = null) { // Do we have the components needed to try a reflect at all? - if (!Resolve(reflector, ref reflect, false) || + if ( + !Resolve(reflector, ref reflect, false) || !reflect.Enabled || !TryComp(projectile, out var reflective) || (reflect.Reflects & reflective.Reflective) == 0x0 || - !TryComp(projectile, out var physics)) + !TryComp(projectile, out var physics) || + TryComp(reflector, out var staminaComponent) && staminaComponent.Critical || + _standing.IsDown(reflector) + ) return false; - var reflectChance = reflect.ReflectProb; - - /* - * The rules of deflection are as follows: - * If you innately reflect things via magic, biology etc, you always have a full chance. - * If you are standing up and standing still, you're prepared to deflect and have full chance. - * If you are moving at all, your chance is multiplied by the movingProbMultiplier. - * If you are recklessly sprinting, your chance is instead multiplied by the sprintingProbMultiplier. - * If you floating, your chance is instead multiplied by the sprintingProbMultiplier. - * You cannot deflect if you are knocked down or stunned. - */ - - if (!reflect.Innate) - { - if (TryComp(reflector, out var staminaComponent) && staminaComponent.Critical) - return false; - - if (_standing.IsDown(reflector)) - return false; - - if (_gravity.IsWeightless(reflector)) - reflectChance *= reflect.SprintingProbMultiplier; - else if (TryComp(reflector, out var mover) && (mover.HeldMoveButtons & MoveButtons.AnyDirection) == MoveButtons.AnyDirection) - reflectChance *= mover.Sprinting ? reflect.SprintingProbMultiplier : reflect.MovingProbMultiplier; - } - - if (!_random.Prob(reflectChance)) + if (!_random.Prob(CalcReflectChance(reflector, reflect))) return false; var rotation = _random.NextAngle(-reflect.Spread / 2, reflect.Spread / 2).Opposite(); @@ -174,6 +151,34 @@ private bool TryReflectProjectile(EntityUid user, EntityUid reflector, EntityUid return true; } + private float CalcReflectChance(EntityUid reflector, ReflectComponent reflect) + { + /* + * The rules of deflection are as follows: + * If you innately reflect things via magic, biology etc., you always have a full chance. + * If you are standing up and standing still, you're prepared to deflect and have full chance. + * If you have velocity, your deflection chance depends on your velocity, clamped. + * If you are floating, your chance is the minimum value possible. + * You cannot deflect if you are knocked down or stunned. + */ + + if (reflect.Innate) + return reflect.ReflectProb; + + if (_gravity.IsWeightless(reflector)) + return reflect.MinReflectProb; + + if (!TryComp(reflector, out var reflectorPhysics)) + return reflect.ReflectProb; + + return MathHelper.Lerp( + reflect.MinReflectProb, + reflect.ReflectProb, + // Inverse progression between velocities fed in as progression between probabilities. We go high -> low so the output here needs to be _inverted_. + 1 - Math.Clamp((reflectorPhysics.LinearVelocity.Length() - reflect.VelocityBeforeNotMaxProb) / (reflect.VelocityBeforeMinProb - reflect.VelocityBeforeNotMaxProb), 0, 1) + ); + } + private void OnReflectHitscan(EntityUid uid, ReflectComponent component, ref HitScanReflectAttemptEvent args) { if (args.Reflected || @@ -199,7 +204,14 @@ private bool TryReflectHitscan( { if (!TryComp(reflector, out var reflect) || !reflect.Enabled || - !_random.Prob(reflect.ReflectProb)) + TryComp(reflector, out var staminaComponent) && staminaComponent.Critical || + _standing.IsDown(reflector)) + { + newDirection = null; + return false; + } + + if (!_random.Prob(CalcReflectChance(reflector, reflect))) { newDirection = null; return false; diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index c7ba6e0b32a3..49ed1146774d 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -267,3 +267,14 @@ - WhitelistChameleon - type: StaticPrice price: 1 + +- type: entity + parent: ClothingHeadBase + id: ClothingHeadLizardPlushie + name: lizard plushie hat + description: Weh? + components: + - type: Sprite + sprite: Clothing/Head/Misc/lizardplushiehat.rsi + - type: Clothing + sprite: Clothing/Head/Misc/lizardplushiehat.rsi diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index f58db21c25a1..0ff27e713030 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -320,7 +320,8 @@ - type: Item heldPrefix: mirror - type: Reflect - reflectProb: 0.95 # 0.63 when moving, 0.31 when sprinting + reflectProb: 0.95 + minReflectProb: 0.6 reflects: - Energy - type: Blocking #Mirror shield reflects heat/laser, but is relatively weak to everything else. @@ -407,7 +408,8 @@ color: blue - type: Reflect enabled: false - reflectProb: 0.95 # 0.63 when moving, 0.31 when sprinting + reflectProb: 0.95 + minReflectProb: 0.6 reflects: - Energy - type: Blocking diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 18d8d51e5612..8fee5aa7b310 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -78,7 +78,8 @@ malus: 0 - type: Reflect enabled: false - reflectProb: 0.3 # 0.2 when moving, 0.1 when sprinting + reflectProb: 0.5 + minReflectProb: 0.25 - type: IgnitionSource temperature: 700 @@ -270,7 +271,8 @@ size: Small sprite: Objects/Weapons/Melee/e_sword_double-inhands.rsi - type: Reflect - reflectProb: .75 # 0.5 when moving, 0.25 when sprinting. + reflectProb: .90 + minReflectProb: .65 spread: 75 - type: UseDelay delay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml index e5795a27fab6..11e7f983e054 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml @@ -18,7 +18,12 @@ path: /Audio/Weapons/bladeslice.ogg - type: Reflect enabled: true - reflectProb: .3 # 0.2 when moving, 0.1 when sprinting. + # Design intent: a robust captain or tot can sacrifice movement to make the most of this weapon, but they have to + # really restrict themselves to walking speed or less. + reflectProb: 0.5 + velocityBeforeNotMaxProb: 1.0 + velocityBeforeMinProb: 3.0 + minReflectProb: 0.1 spread: 90 - type: Item size: Normal @@ -84,8 +89,8 @@ - Belt - type: Reflect reflectProb: 0.3 - movingProbMultiplier: 1.0 # don't punish ninjas for being ninjas - sprintingProbMultiplier: 1.0 # it's a ninja weapon. you run around and slice bullets in half + velocityBeforeNotMaxProb: 6.0 # don't punish ninjas for being ninjas + velocityBeforeMinProb: 10.0 - type: entity name: machete @@ -188,7 +193,10 @@ path: /Audio/Effects/explosion_small1.ogg - type: Reflect enabled: true - reflectProb: .3 # 0.2 when moving, 0.1 when sprinting + reflectProb: 0.5 # In robust hands, deflects as well as an e-sword + velocityBeforeNotMaxProb: 1.0 + velocityBeforeMinProb: 3.0 + minReflectProb: 0.1 spread: 90 - type: Item size: Ginormous From a06467294b743da59a4d62ab60fdae76cf6a6d3f Mon Sep 17 00:00:00 2001 From: Hannah FairlySadPanda Dawson Date: Tue, 23 Apr 2024 20:04:02 +0100 Subject: [PATCH 3/8] Weh? --- Resources/Prototypes/Entities/Clothing/Head/misc.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 49ed1146774d..c7ba6e0b32a3 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -267,14 +267,3 @@ - WhitelistChameleon - type: StaticPrice price: 1 - -- type: entity - parent: ClothingHeadBase - id: ClothingHeadLizardPlushie - name: lizard plushie hat - description: Weh? - components: - - type: Sprite - sprite: Clothing/Head/Misc/lizardplushiehat.rsi - - type: Clothing - sprite: Clothing/Head/Misc/lizardplushiehat.rsi From ef2d05142faea6da6bc64500bc3d50a85af41506 Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Tue, 23 Apr 2024 22:08:06 +0100 Subject: [PATCH 4/8] Reign in double esword a tad --- Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 8fee5aa7b310..7f593353bb51 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -271,7 +271,7 @@ size: Small sprite: Objects/Weapons/Melee/e_sword_double-inhands.rsi - type: Reflect - reflectProb: .90 + reflectProb: .80 minReflectProb: .65 spread: 75 - type: UseDelay From 8ed9d4ed0940d40749bd1ba7ffaaf385ed02c274 Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Tue, 23 Apr 2024 23:20:19 +0100 Subject: [PATCH 5/8] Shield nerfs no longer real --- Resources/Prototypes/Entities/Objects/Shields/shields.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 0ff27e713030..9c262d6fa64f 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -321,7 +321,7 @@ heldPrefix: mirror - type: Reflect reflectProb: 0.95 - minReflectProb: 0.6 + innate: true reflects: - Energy - type: Blocking #Mirror shield reflects heat/laser, but is relatively weak to everything else. @@ -409,7 +409,7 @@ - type: Reflect enabled: false reflectProb: 0.95 - minReflectProb: 0.6 + innate: true reflects: - Energy - type: Blocking From c155071c86ce2fcbbe929d798eca1344d8481e8e Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Tue, 23 Apr 2024 23:23:19 +0100 Subject: [PATCH 6/8] Improve Mirror Cult desc --- Resources/Prototypes/Entities/Objects/Shields/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 9c262d6fa64f..e7ebb1b98d45 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -313,7 +313,7 @@ name: mirror shield parent: BaseShield id: MirrorShield - description: Eerily glows red. You hear the geometer whispering... + description: Glows an eerie red. You hear the Geometer whispering... components: - type: Sprite state: mirror-icon From 9d383c1662d1d28737ea890048323ac2901586af Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Tue, 23 Apr 2024 23:56:48 +0100 Subject: [PATCH 7/8] Simple alert for deflection! No art yet. --- Content.Shared/Alert/AlertType.cs | 3 +- .../Weapons/Reflect/ReflectSystem.cs | 31 ++++++++++++++++--- Resources/Locale/en-US/alerts/alerts.ftl | 3 ++ Resources/Prototypes/Alerts/alerts.yml | 9 ++++++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Content.Shared/Alert/AlertType.cs b/Content.Shared/Alert/AlertType.cs index b917dd692d7e..b989b8d4b6f5 100644 --- a/Content.Shared/Alert/AlertType.cs +++ b/Content.Shared/Alert/AlertType.cs @@ -52,7 +52,8 @@ public enum AlertType : byte SuitPower, BorgHealth, BorgCrit, - BorgDead + BorgDead, + Deflecting } } diff --git a/Content.Shared/Weapons/Reflect/ReflectSystem.cs b/Content.Shared/Weapons/Reflect/ReflectSystem.cs index 6a08dc2747ba..fb984ddb31d0 100644 --- a/Content.Shared/Weapons/Reflect/ReflectSystem.cs +++ b/Content.Shared/Weapons/Reflect/ReflectSystem.cs @@ -1,24 +1,20 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; -using Content.Shared.ActionBlocker; using Content.Shared.Administration.Logs; +using Content.Shared.Alert; using Content.Shared.Audio; using Content.Shared.Damage.Components; -using Content.Shared.Damage.Systems; using Content.Shared.Database; using Content.Shared.Gravity; using Content.Shared.Hands; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Item.ItemToggle.Components; -using Content.Shared.Movement.Components; -using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Projectiles; using Content.Shared.Standing; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; using Robust.Shared.Physics.Components; @@ -44,6 +40,7 @@ public sealed class ReflectSystem : EntitySystem [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly StandingStateSystem _standing = default!; + [Dependency] private readonly AlertsSystem _alerts = default!; public override void Initialize() { @@ -240,6 +237,9 @@ private void OnReflectEquipped(EntityUid uid, ReflectComponent component, GotEqu return; EnsureComp(args.Equipee); + + if (component.Enabled) + EnableAlert(args.Equipee); } private void OnReflectUnequipped(EntityUid uid, ReflectComponent comp, GotUnequippedEvent args) @@ -253,6 +253,9 @@ private void OnReflectHandEquipped(EntityUid uid, ReflectComponent component, Go return; EnsureComp(args.User); + + if (component.Enabled) + EnableAlert(args.User); } private void OnReflectHandUnequipped(EntityUid uid, ReflectComponent component, GotUnequippedHandEvent args) @@ -264,6 +267,11 @@ private void OnToggleReflect(EntityUid uid, ReflectComponent comp, ref ItemToggl { comp.Enabled = args.Activated; Dirty(uid, comp); + + if (comp.Enabled) + EnableAlert(uid); + else + DisableAlert(uid); } /// @@ -277,9 +285,22 @@ private void RefreshReflectUser(EntityUid user) continue; EnsureComp(user); + EnableAlert(user); + return; } RemCompDeferred(user); + DisableAlert(user); + } + + private void EnableAlert(EntityUid alertee) + { + _alerts.ShowAlert(alertee, AlertType.Deflecting); + } + + private void DisableAlert(EntityUid alertee) + { + _alerts.ClearAlert(alertee, AlertType.Deflecting); } } diff --git a/Resources/Locale/en-US/alerts/alerts.ftl b/Resources/Locale/en-US/alerts/alerts.ftl index 795d740141b9..2bf7fd2fdc30 100644 --- a/Resources/Locale/en-US/alerts/alerts.ftl +++ b/Resources/Locale/en-US/alerts/alerts.ftl @@ -110,3 +110,6 @@ alerts-revenant-essence-desc = The power of souls. It sustains you and is used f alerts-revenant-corporeal-name = Corporeal alerts-revenant-corporeal-desc = You have manifested physically. People around you can see and hurt you. + +alerts-deflecting-name = Deflecting +alerts-deflecting-desc = You can deflect shots. You have your highest chance of doing so whilst standing still or moving slowly. diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index e9a7f9c95848..6c4319e3567d 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -24,6 +24,7 @@ - category: Thirst - alertType: Magboots - alertType: Pacified + - alertType: Deflecting - type: entity id: AlertSpriteView @@ -474,3 +475,11 @@ state: critical name: Debug6 description: Debug + +- type: alert + id: Deflecting + icons: + - sprite: /Textures/deprecated.rsi + state: deprecated + name: alerts-deflecting-name + description: alerts-deflecting-desc From 0eb6861f054e247813ebb8efe9bdb8a37b97dd9c Mon Sep 17 00:00:00 2001 From: Hannah FairlySadPanda Dawson Date: Wed, 24 Apr 2024 23:39:57 +0100 Subject: [PATCH 8/8] Added a new icon for deflecting --- Resources/Locale/en-US/alerts/alerts.ftl | 2 +- Resources/Prototypes/Alerts/alerts.yml | 4 ++-- .../Alerts/deflecting.rsi/deflecting0.png | Bin 0 -> 1761 bytes .../Interface/Alerts/deflecting.rsi/meta.json | 14 ++++++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 Resources/Textures/Interface/Alerts/deflecting.rsi/deflecting0.png create mode 100644 Resources/Textures/Interface/Alerts/deflecting.rsi/meta.json diff --git a/Resources/Locale/en-US/alerts/alerts.ftl b/Resources/Locale/en-US/alerts/alerts.ftl index 2bf7fd2fdc30..fb8572d9afad 100644 --- a/Resources/Locale/en-US/alerts/alerts.ftl +++ b/Resources/Locale/en-US/alerts/alerts.ftl @@ -112,4 +112,4 @@ alerts-revenant-corporeal-name = Corporeal alerts-revenant-corporeal-desc = You have manifested physically. People around you can see and hurt you. alerts-deflecting-name = Deflecting -alerts-deflecting-desc = You can deflect shots. You have your highest chance of doing so whilst standing still or moving slowly. +alerts-deflecting-desc = You have a chance to deflect incoming projectiles. Standing still or moving slowly will increase this chance. diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index 6c4319e3567d..7881cddd4aab 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -479,7 +479,7 @@ - type: alert id: Deflecting icons: - - sprite: /Textures/deprecated.rsi - state: deprecated + - sprite: /Textures/Interface/Alerts/deflecting.rsi + state: deflecting0 name: alerts-deflecting-name description: alerts-deflecting-desc diff --git a/Resources/Textures/Interface/Alerts/deflecting.rsi/deflecting0.png b/Resources/Textures/Interface/Alerts/deflecting.rsi/deflecting0.png new file mode 100644 index 0000000000000000000000000000000000000000..37404e77f76444946eaa481b8f4ec861f85736c6 GIT binary patch literal 1761 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}e5nzhX}-P; zT0k}j5QD&_;K@Lev%n*=n1MmW7law7oa)tQU|_Dx42dX-@b$4u&d=3LOvz75)vL%Y z0PC`;umUo3Q%e#RDspr3imfVamB1>jfNYSkzLEl1NlCV?QiN}Sf^&XRs)CuGfu4bq z9hZWFf=y9MnpKdC8&o@xXRDM^Qc_^0uU}qXu2*iXmtT~wZ)j<0sc&GUZ)BtkRH0j3 znOBlnp_^B%3^4>|j!SBBa#3bMNoIbY0?6FNr2NtnTO}osMQ{LdXG${Mo`TY%9I!1Z z$@-}|sky0nCB^!NdWQPg^p#|$AzYYO3=Ixo!03ZyfZ7bOYV#~8Nj3q7lxqdhJy8Dv z9hwZbx40xlA4!3}k%57Qu7Q!Rk)=M|e?aHkq$FFFWR~Qlf&&ijA8-gd=9Hj{g4Bb8 zASV+PvQ{~XdFi%F6}l;@X^EvdB}#Uod0?Yb6da36%JYk|ZS*0kQB8q}q8e_akHsA} zAm3X>2Bj9~=ahoN-_Fq3$OarHD58j%far+8ssmXRT}MDhen~zsWff&6d*+p-78Mi$ zQyJJsn0>fapqquTJTxz}#13WvnlO?sq*$_o23!a@MlgdDr&6eKkf23Mv5@Qljs{?U zu;a4PhvzLjuD|Ez{a|2VdgSTi7!twxHf(>ll%q)9>g)3aH%&4L?C@0f=sKY3^-_5x?PXMg=&dwlOg7bU|>CT~x9 zb_T6CWpZ@TUF_5_Lklimk-JuS7}Ko>mE&-XwT%@ zz~AnCsWjGS_c!$k_qyy%=bv{x)ZwDkSM>CArNyI_f|-FzCbQ0}DK0pe;IJ{`jA%$K z$3xdA@?HlRJyy6KS>*1mHaTQ%m}f)%-=FRGo-dZ+d604WWl4U)jbbK=2$gdI!WH>j zqh6HV`q?dPS6*4`o*(~j>3RD+3qv0!n~cdU8!k@z*R#?f>E!~ag&Ur}|8vr7UvkaQ z=;b+Pr=RmN9(OaAd3jBxQDi~KqKg_A7l)U0m1^@YVz=nh@z^ISVL63sg*fk&6Deo1 z6F1+ypsT#ltU+0H_0+W;yW~=II3G+hT(|GUqiho?6S@AK`V$0rA1qp_DOl|Id#y;u z%5t^N%geXT-<=&@XLj20rd8Jjj+DHd=yt)~@iJ*|HCHywVB%a6_`e{Ld3DQ-g`9e2 zJHC5NO!Nqp7KGu&fThp?^U)%zxfj8D>H6YSo*o)!HwtY_Bk?~ z3617rwSO<0-|6{uH|pctX{S|7cgLQ8@i3*mA^1zdvC9PwTy;L%{TO><_x)_sd|sTk z@bjThlf;icpI+^l)7}u_&|l5Ce9_&!$2uEl8U5J%o_$~c7pCKr88jzx3*G2gzbKlU ziBEnW%e&>y6Ao;Tv%SAUaD|Y_o#_q1Q<_}#rY|nA(CNRW_~66)T7N6U4bP6eznPTy lZ%sw4nOvUSG&zw4^;={Tb>7Fkn+K|1JYD@<);T3K0RY#fl2ZTx literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Alerts/deflecting.rsi/meta.json b/Resources/Textures/Interface/Alerts/deflecting.rsi/meta.json new file mode 100644 index 000000000000..f5d94c891a73 --- /dev/null +++ b/Resources/Textures/Interface/Alerts/deflecting.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Deflecting icon by Ubaser", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "deflecting0" + } + ] +}