diff --git a/Content.Server/Weapons/Reflect/ReflectSystem.cs b/Content.Server/Weapons/Reflect/ReflectSystem.cs index 4045bf7b79..48dffd87e3 100644 --- a/Content.Server/Weapons/Reflect/ReflectSystem.cs +++ b/Content.Server/Weapons/Reflect/ReflectSystem.cs @@ -9,6 +9,7 @@ public sealed class ReflectSystem : SharedReflectSystem public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(EnableReflect); SubscribeLocalEvent(DisableReflect); SubscribeLocalEvent(ShieldEnableReflect); diff --git a/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs b/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs index e38c08a9d0..302fd8ac9a 100644 --- a/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs +++ b/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs @@ -5,6 +5,8 @@ using Content.Shared.Audio; using Content.Shared.Database; using Content.Shared.Hands.Components; using Content.Shared.Weapons.Ranged.Events; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; using Robust.Shared.Physics.Components; using Content.Shared.Popups; using Content.Shared.Projectiles; @@ -27,15 +29,20 @@ public abstract class SharedReflectSystem : EntitySystem [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly InventorySystem _inventorySystem = default!; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnHandReflectProjectile); SubscribeLocalEvent(OnHandsReflectHitscan); SubscribeLocalEvent(OnReflectCollide); SubscribeLocalEvent(OnReflectHitscan); + + SubscribeLocalEvent(OnReflectEquipped); + SubscribeLocalEvent(OnReflectUnequipped); } private void OnReflectCollide(EntityUid uid, ReflectComponent component, ref ProjectileCollideEvent args) @@ -160,4 +167,49 @@ public abstract class SharedReflectSystem : EntitySystem return true; } + + private void OnReflectEquipped(EntityUid uid, ReflectComponent comp, GotEquippedEvent args) + { + + if (!TryComp(args.Equipee, out ReflectComponent? reflection)) + return; + + reflection.Enabled = true; + + // reflection probability should be: (1 - old probability) * newly-equipped item probability + old probability + // example: if entity has .25 reflection and newly-equipped item has .7, entity should have (1 - .25) * .7 + .25 = .775 + reflection.ReflectProb += (1 - reflection.ReflectProb) * comp.ReflectProb; + + } + + private void OnReflectUnequipped(EntityUid uid, ReflectComponent comp, GotUnequippedEvent args) + { + + if (!TryComp(args.Equipee, out ReflectComponent? reflection)) + return; + + if (!_inventorySystem.TryGetSlots(args.Equipee, out var slotDef)) + return; + + // you could recalculate reflectprob with new = (old - component) / (1 - component), but component=1 introduces loss + // still need to either maintain a counter or loop through all slots to determine reflection.enabled anyway? + float newProb = 1; + var reflecting = false; + + foreach (var slot in slotDef) + { + if (!_inventorySystem.TryGetSlotEntity(args.Equipee, slot.Name, out var slotEnt)) + continue; + + if (!TryComp(slotEnt, out ReflectComponent? refcomp)) + continue; + + reflecting = true; + var prob = refcomp.ReflectProb; + newProb -= newProb * prob; + } + + reflection.ReflectProb = 1 - newProb; + reflection.Enabled = reflecting; + } } diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 06cdb94fa1..1d30482db3 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -94,6 +94,8 @@ Slash: 0.9 Piercing: 0.9 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 - type: entity parent: ClothingOuterBaseLarge @@ -246,7 +248,7 @@ Radiation: 0.8 - type: ClothingSpeedModifier walkModifier: 0.7 - sprintModifier: 0.65 + sprintModifier: 0.65 - type: ExplosionResistance damageCoefficient: 0.5 - type: GroupExamine diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/ship_vs_ship.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/ship_vs_ship.yml index bb42d7d51d..d6999a0a26 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/ship_vs_ship.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/ship_vs_ship.yml @@ -93,4 +93,4 @@ - type: Sprite sprite: Clothing/Uniforms/Jumpsuit/ce_syndie.rsi - type: Clothing - sprite: Clothing/Uniforms/Jumpsuit/ce_syndie.rsi \ No newline at end of file + sprite: Clothing/Uniforms/Jumpsuit/ce_syndie.rsi diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 4fe8bb1e42..ebbd76d7a5 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -149,6 +149,9 @@ visible: false - type: Physics bodyType: KinematicController + - type: Reflect + enabled: false + reflectProb: 0 - type: Fixtures fixtures: # TODO: This needs a second fixture just for mob collisions. fix1: diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index e6faa23a1b..4da0c57273 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -672,6 +672,8 @@ damageModifierSet: Metallic - type: Physics bodyType: Static + - type: Reflect + reflectProb: 1 - type: Pullable - type: Airtight noAirWhenFullyAirBlocked: false @@ -743,6 +745,8 @@ acts: ["Destruction"] destroySound: path: /Audio/Effects/metalbreak.ogg + - type: Reflect + reflectProb: 1 - type: IconSmooth key: walls base: state