Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Port/Feature] Knockdown / Сбитие С Ног #114

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

Spatison
Copy link
Member

@Spatison Spatison commented Nov 1, 2024

Описание PR

Порт всякого разного связанного с сбитием с ног.


Изменения

🆑 Spatison

  • add: Added energy bola / Добавлена энергетическая бола
  • add: Full-size headphones and some helmets received additional protection from flashbang grenades / В полноразмерные наушники и некоторые шлема добавлена защита от светошумовых гранат
  • add: Bola are now being knocked down / Болы теперь сбивают с ног
  • add: Stunbatons are now being knocked down / Дубинки-шокеры теперь сбивают с ног
  • add: Taser shot now being knocked down / Выстрел тазера теперь сбивает с ног
  • tweak: The Attack rate of the stunbatons has been lowered / Скорость атаки дубинок-шокеров понижена
  • tweak: Stamina damage from stunbaton has been increased / Увеличен урон по стамине у дубинок-шокеров
  • remove: Deleted taser stun / Удаленно оглушение у тазера

Copy link
Contributor

coderabbitai bot commented Nov 1, 2024

Walkthrough

This pull request introduces significant updates across multiple systems related to combat and interaction mechanics, particularly focusing on melee and ranged weapon functionality, flash effects, and knockdown mechanics. Key changes include the refinement of attack actions in the MeleeWeaponSystem, enhancements to the FlashSystem for managing flash effects, and the introduction of new components for knockdown behavior. Additionally, new localization entries for alerts and weapon descriptions are added, along with modifications to existing entities and systems to support these features.

Changes

File Path Change Summary
Content.Client/Weapons/Melee/MeleeWeaponSystem.cs Updated attack logic to check if a weapon can perform heavy attacks and refined ranged weapon handling during alternate attacks. Enhanced checks in Update and DoDisarm methods.
Content.Server/Explosion/EntitySystems/TriggerSystem.cs Expanded HandleFlashTrigger method to include stunTime and knockdownTime parameters for flash effects.
Content.Server/Flash/FlashSystem.cs Introduced FlashStun method for applying stun effects based on distance. Updated FlashArea method to include stun and knockdown times.
Content.Server/Speech/EntitySystems/StutteringSystem.cs Updated regex pattern for stuttering to include Cyrillic consonants.
Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs Added new FlashSoundSuppressionComponent with a MaxRange field.
Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs Created FlashSoundSuppressionSystem to manage flash suppression events.
Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs Introduced BaseKnockdownOnComponent with timing parameters for knockdown mechanics.
Content.Server/_White/Knockdown/KnockComponent.cs Added KnockComponent for handling knockdown timing.
Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs Created KnockdownOnCollideComponent for knockdown on collision.
Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs Created KnockdownOnHitComponent for knockdown on hit.
Content.Server/_White/Knockdown/KnockdownSystem.cs Implemented KnockdownSystem to manage knockdown mechanics and effects.
Content.Shared/Alert/AlertType.cs Added KnockedDown and RecentlyBlocked alert types to the enum.
Content.Shared/Flash/Components/FlashOnTriggerComponent.cs Added StunTime and KnockdownTime fields to FlashOnTriggerComponent.
Content.Shared/Flash/SharedFlashSystem.cs Introduced FlashbangedEvent class for handling flashbang events.
Content.Shared/Inventory/InventorySystem.Relay.cs Updated InitializeRelay to handle FlashbangedEvent.
Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs Modified component management logic to allow up to 8 components.
Content.Shared/Stunnable/SharedStunSystem.cs Adjusted item drop behavior when an entity is knocked down.
Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs Added CanHeavyAttack and CanBeBlocked properties to MeleeWeaponComponent.
Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs Removed KnockdownOnCollideSystem.
Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs Renamed KnockdownOnCollideComponent to LayDownOnCollideComponent.
Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs Created LayDownOnCollideSystem for handling laying down mechanics.
Resources/Locale/en-US/_white/alerts/alerts.ftl Added new alert messages for knockdown.
Resources/Locale/ru-RU/_white/alerts/alerts.ftl Added localized alert messages for knockdown in Russian.
Resources/Prototypes/Alerts/alerts.yml Added new alert types and definitions for KnockedDown and RecentlyBlocked.
Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml Added EnergyBola to SecTechInventory.
Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml Added FlashSoundSuppression component to ClothingHeadsetAlt.
Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml Added protective components to various hardsuit helmets.
Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml Updated BulletFlashGrenade and BulletTaser entities with new properties.
Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml Modified stun prod properties and added new components.
Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml Introduced new entities Bola and EnergyBola with specific properties.
Resources/Prototypes/status_effects.yml Modified status effects for KnockedDown, added RecentlyBlocked and BlurryVision.
Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json Added metadata for knockdown alert graphics.
Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json Added metadata for energy bola graphics.

Possibly related PRs

Suggested labels

Status: Needs Review

Suggested reviewers

  • Remuchi

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

github-actions bot commented Nov 1, 2024

RSI Diff Bot; head commit d435c27 merging into ec0cbe6
This PR makes changes to 1 or more RSIs. Here is a summary of all changes:

Resources/Textures/_White/Interface/Alerts/knockdown.rsi

State Old New Status
knockdown Added

Edit: diff updated after d435c27

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

🧹 Outside diff range and nitpick comments (31)
Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1)

1-4: LGTM! Consider adding XML documentation.

The component implementation follows good practices:

  • Proper namespace organization
  • Correct component registration
  • Appropriate use of sealed and partial modifiers

Consider adding XML documentation to describe:

  • The component's purpose
  • How it interacts with the knockdown system
  • Required components/dependencies
 namespace Content.Server._White.Knockdown;

+/// <summary>
+/// Component that enables an entity to apply knockdown effects on hit.
+/// Works in conjunction with the knockdown system for melee, projectile, and throwing interactions.
+/// </summary>
 [RegisterComponent]
 public sealed partial class KnockdownOnHitComponent : BaseKnockdownOnComponent;
Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1)

1-4: LGTM! Consider adding documentation.

The component structure follows good practices with appropriate modifiers and inheritance. Consider adding XML documentation to describe the component's purpose and usage.

Add documentation like this:

+/// <summary>
+/// A component that marks an entity as capable of causing knockdown effects upon collision.
+/// </summary>
 [RegisterComponent]
 public sealed partial class KnockdownOnCollideComponent : BaseKnockdownOnComponent;
Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1)

1-8: LGTM! Consider adding XML documentation.

The component is well-structured and follows best practices. The MaxRange field with a default value of 2f provides a good baseline for flash sound suppression.

Consider adding XML documentation to describe:

  • The component's purpose
  • The MaxRange field's unit (meters/units) and its effect on gameplay
 namespace Content.Server._White.Flash;

+/// <summary>
+/// Component that suppresses flash-related sound effects within a specified range.
+/// Used by headphones and helmets for flashbang protection.
+/// </summary>
 [RegisterComponent]
 public sealed partial class FlashSoundSuppressionComponent : Component
 {
+    /// <summary>
+    /// Maximum range in units where flash sound effects are suppressed.
+    /// </summary>
     [DataField]
     public float MaxRange = 2f;
 }
Content.Server/_White/Knockdown/KnockComponent.cs (1)

4-11: Add XML documentation for better code maintainability.

Consider adding XML documentation to describe the component's purpose and its properties.

+/// <summary>
+/// Component that configures knockdown behavior for an entity.
+/// </summary>
 public sealed partial class KnockComponent : Component
 {
+    /// <summary>
+    /// The delay before the knockdown effect is applied.
+    /// </summary>
     [DataField]
     public TimeSpan Delay = TimeSpan.FromSeconds(2);
 
+    /// <summary>
+    /// The duration for which the entity remains knocked down.
+    /// </summary>
     [DataField]
     public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);
 }
Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

3-4: Add XML documentation for the component class.

Since this is a base component that will be inherited by other knockdown-related components, it would be beneficial to document its purpose and usage.

+/// <summary>
+/// Base component for implementing knockdown mechanics. Derived components can specify
+/// different conditions for when the knockdown effect should be applied.
+/// </summary>
 public abstract partial class BaseKnockdownOnComponent : Component
Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (2)

18-19: Add documentation for KnockdownTime field.

While the field aligns with PR objectives, its purpose and units should be documented for clarity.

+ /// <summary>
+ /// The duration of the knockdown effect in seconds when flashed.
+ /// </summary>
 [DataField]
-public float KnockdownTime;
+public float KnockdownTime = 0f;

14-20: Remove unnecessary source control comments.

The "WD EDIT" comments are redundant as Git already tracks these changes.

-    // WD EDIT START
     [DataField]
     public float StunTime = 0f;

     [DataField]
     public float KnockdownTime = 0f;
-    // WD EDIT END
Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (2)

1-4: Consider standardizing the namespace convention.

The _White prefix in the namespace appears to be a custom naming convention. Consider moving this to a more standard namespace structure like Content.Server.Flash for better maintainability and consistency with the rest of the codebase.


6-7: Add XML documentation for the public class.

Since this is a new system implementation, please add XML documentation to describe its purpose and responsibilities.

+/// <summary>
+/// Handles the suppression of flash-related sound effects based on protective equipment.
+/// </summary>
 public sealed class FlashSoundSuppressionSystem : EntitySystem
Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

29-31: Consider documenting the gameplay impact.

The combination of LayDownOnCollide and BlurOnCollide components suggests this projectile now drops and causes a blur effect instead of knockdown. Consider adding a comment to explain this gameplay mechanic change.

  - type: LayDownOnCollide
    behavior: AlwaysDrop
+ # Energy bolts now drop and blur targets instead of knockdown
  - type: BlurOnCollide
🧰 Tools
🪛 yamllint

[error] 31-31: no new line character at the end of file

(new-line-at-end-of-file)

Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (2)

3-4: LGTM! Good architectural decision.

Converting this to an abstract base entity promotes better code organization and reusability. The ID change to "BaseBola" clearly indicates its role as a base prototype.

This abstraction will make it easier to create variations of bolas with different effects while maintaining consistent base behavior.


Line range hint 8-12: Consider effect timing coordination.

The entity has both sound effects (throw/land) and the new knockdown effect. Consider documenting or verifying that these effects are properly synchronized for a smooth player experience.

Would you like me to help create a timing sequence diagram or documentation for these effects?

Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1)

10-10: Remove unnecessary comment and approve addition.

The addition of EnergyBola with quantity 5 is well-balanced with other less-lethal options in the security vending machine. However, the comment # WD EDIT should be removed as it breaks consistency with other entries and doesn't provide meaningful information.

-    EnergyBola: 5 # WD EDIT
+    EnergyBola: 5
Content.Shared/Flash/SharedFlashSystem.cs (1)

21-32: Implementation looks good with room for minor improvements.

The FlashbangedEvent implementation correctly integrates with the inventory system for handling flashbang protection via headphones and helmets. The use of SlotFlags for targeting specific equipment slots is well-designed.

Some suggestions for future improvements:

  1. Consider adding XML documentation to describe the event's purpose and MaxRange parameter
  2. Consider adding range validation in the constructor

Example documentation:

/// <summary>
/// Event raised when an entity is affected by a flashbang.
/// Allows inventory items in EARS and HEAD slots to provide protection.
/// </summary>
public sealed class FlashbangedEvent : EntityEventArgs, IInventoryRelayEvent
{
    /// <summary>
    /// Maximum range at which the flashbang effect can impact an entity.
    /// </summary>
    public readonly float MaxRange;
Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1)

7-10: Consider documenting the system's purpose and behavior.

Adding XML documentation to describe the system's purpose, responsibilities, and interaction patterns would improve maintainability.

+/// <summary>
+/// Handles the application of laying down effects when entities collide with projectiles or thrown objects.
+/// </summary>
 public sealed class LayDownOnCollideSystem : EntitySystem
Resources/Prototypes/status_effects.yml (2)

10-10: Remove unnecessary comment.

The comment # WD EDIT is redundant as Git already tracks the changes and their authors. Consider removing it to maintain cleaner code.

-  alert: KnockedDown # WD EDIT
+  alert: KnockedDown

Line range hint 46-54: Remove unnecessary block comments.

The block comments # WD EDIT START and # WD EDIT END are redundant as Git already tracks these changes. Consider removing them to maintain cleaner code.

-# WD EDIT START
 - type: statusEffect
   id: RecentlyBlocked
   alwaysAllowed: true
   alert: RecentlyBlocked

 - type: statusEffect
   id: BlurryVision
   alwaysAllowed: true
-# WD EDIT END
Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (1)

41-46: Consider adding visual effects for energy weapon.

As an energy-based weapon that emits sparks sound, it would be more immersive to include visual effects (like particles or overlays) when the bola lands or activates.

Example addition:

  - type: EmitSoundOnLand
    sound:
      collection: sparks
+  - type: ParticleEmitter
+    particles:
+      - name: Sparks
+        lifetime: 0.5
+        color: "#4169E1"
Content.Shared/Alert/AlertType.cs (2)

20-20: LGTM! Consider adding XML documentation.

The KnockedDown alert type is well-positioned in the enum and aligns with the new knockdown mechanics. Consider adding XML documentation to describe its purpose and usage.

 /// <summary>
 /// Every kind of alert. Corresponds to alertType field in alert prototypes defined in YML
 /// </summary>
 public enum AlertType : byte
 {
     // ...
     Stun,
+    /// <summary>
+    /// Indicates that an entity has been knocked down by weapons like energy balls, shock batons, or tasers.
+    /// </summary>
     KnockedDown, // WD EDIT
     // ...

Line range hint 73-73: LGTM! Consider adding XML documentation.

The RecentlyBlocked alert type is appropriately placed near other combat-related states. Consider adding XML documentation to describe its purpose and usage.

     Offer,
+    /// <summary>
+    /// Indicates that an entity has recently blocked an attack, typically used for combat feedback.
+    /// </summary>
     RecentlyBlocked, // WD EDIT
Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (1)

Line range hint 1-63: Well-structured implementation with significant gameplay impact

The changes create a more tactical weapon with:

  • Slower but more impactful attacks
  • Power cell management mechanics
  • Knockdown capabilities replacing stun effects

This aligns well with the PR objectives of introducing knockdown mechanics and removing stun effects.

Consider documenting these significant gameplay changes in the game's wiki or player guide, as the weapon's usage pattern has changed substantially.

Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (2)

125-126: Consider documenting the CanHeavyAttack property.

While the property is properly implemented, adding XML documentation would help other developers understand its purpose and impact on gameplay mechanics.

Add documentation above the property:

+    /// <summary>
+    /// Whether this weapon can perform heavy attacks. Heavy attacks may have different
+    /// damage, range, and stamina costs as defined by the Heavy* properties.
+    /// </summary>
     [DataField, AutoNetworkedField]
     public bool CanHeavyAttack = true;

Line range hint 171-172: Consider documenting the CanBeBlocked property and its interaction with ContestArgs.

The property appears to work in conjunction with ContestArgs for combat mechanics, but this relationship isn't documented.

Add documentation above the property:

+    /// <summary>
+    /// Whether this weapon's attacks can be blocked during combat contests.
+    /// Works in conjunction with ContestArgs to determine the outcome of combat interactions.
+    /// </summary>
     [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
     public bool CanBeBlocked = true;
Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1)

Line range hint 119-141: Document knockdown interaction with heavy attacks.

Since this PR introduces knockdown mechanics, consider adding documentation comments explaining how heavy attacks interact with the knockdown system, especially for weapons like shock batons and tasers.

+// Heavy attacks may trigger knockdown effects depending on the weapon type.
+// For shock-based weapons (e.g., shock batons, tasers), this will initiate
+// the knockdown effect on successful hits.
if (altDown == BoundKeyState.Down && weapon.CanHeavyAttack)
Content.Shared/Stunnable/SharedStunSystem.cs (2)

Line range hint 1-456: Consider enhancing the stun system for the new knockdown mechanics.

Given the PR's focus on knockdown mechanics and removal of taser stuns, consider the following suggestions to improve the system:

  1. Add specific events or properties to differentiate between knockdown sources (energy balls, shock batons, tasers).
  2. Consider adding a cooldown mechanism to prevent knockdown spam.
  3. Add configuration options for different knockdown behaviors (e.g., item dropping, recovery time).

Consider adding these interfaces and configurations:

public interface IKnockdownSource
{
    KnockdownType Type { get; }
    float KnockdownDuration { get; }
    DropHeldItemsBehavior DropBehavior { get; }
}

public enum KnockdownType
{
    EnergyBall,
    ShockBaton,
    Taser,
    Other
}

This would allow for more granular control over different knockdown sources and their behaviors.


Line range hint 48-48: Document the knockdown behavior change.

The constant KnockDownModifier is documented, but the new AlwaysDrop behavior lacks documentation. Consider adding XML documentation to explain this significant change.

Add documentation above the OnKnockInit method:

+    /// <summary>
+    /// Initializes knockdown state. Always drops held items as per design decision for enhanced knockdown mechanics.
+    /// </summary>
     private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args)

Also applies to: 113-113

Resources/Prototypes/Alerts/alerts.yml (1)

634-634: Consider creating a dedicated icon for RecentlyBlocked.

Currently using a shield icon (shields.rsi/buckler-icon.png) which might be misleading as it's not specifically related to blocking. Consider creating a dedicated icon that better represents the "recently blocked" state.

Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (2)

202-204: Fix trailing whitespace.

There's a trailing space on line 204 that should be removed.

-  
+
🧰 Tools
🪛 yamllint

[error] 204-204: trailing spaces

(trailing-spaces)


Flash protection is inconsistently applied across utility hardsuits

The review comment's concern about flash protection balance is valid but incomplete. The current implementation shows inconsistencies:

  • Utility hardsuits (Engineering, Atmos, Salvage) have flash protection despite the comment suggesting they shouldn't
  • This creates an unintended balance issue where utility roles get combat advantages meant for security/command roles
  • The "WD EDIT" comments suggest these were unplanned additions

Recommended changes:

  • Remove FlashImmunity and FlashSoundSuppression components from utility hardsuits:
    • ClothingHeadHelmetHardsuitAtmos
    • ClothingHeadHelmetHardsuitEngineering
    • ClothingHeadHelmetHardsuitSalvage
  • Keep flash protection only on combat/command hardsuits (Security, Command, Syndicate, ERT)

This will restore the intended balance distinction between utility and combat roles.

🔗 Analysis chain

Line range hint 1-804: Verify flash protection balance.

The changes consistently add flash protection to high-tier helmets (Security, Command, Syndicate, ERT) while leaving utility hardsuits (Engineering, Medical, Mining) without it. This creates a clear distinction between combat and utility roles.


Let me run another script to specifically identify which helmets have flash protection to get a clearer picture.


Let me try a different approach to identify the helmets with flash protection.


Let me get the specific helmet IDs to confirm which ones have flash protection.


Let me try one more approach to get the helmet information.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that utility hardsuits don't have flash protection
# to ensure game balance is maintained

echo "Checking for flash protection components in utility hardsuit helmets..."
rg -l "ClothingHeadHelmetHardsuit(Engineering|Medical|Mining|Atmos|Salvage)" | \
  xargs rg "FlashImmunity|FlashSoundSuppression"

# If no output, then utility hardsuits correctly lack flash protection

Length of output: 3968


Script:

#!/bin/bash
# Get the context of flash protection components to see which helmets have them
rg -B 2 "FlashImmunity" Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml | grep -B 1 "id: ClothingHeadHelmet"

Length of output: 125


Script:

#!/bin/bash
# Get 3 lines before each FlashImmunity occurrence to identify the helmet
rg -B 3 "FlashImmunity" Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

Length of output: 2053


Script:

#!/bin/bash
# Get the helmet ID and name for each one that has FlashImmunity
rg -B 10 "FlashImmunity" Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml | grep -E "id: |name: "

Length of output: 113


Script:

#!/bin/bash
# Find sections containing both the ID and FlashImmunity
echo "=== Helmets with Flash Protection ==="
awk '/^- type: entity/{p=NR+3}(NR<=p){printf "%s ", $0}/-.*FlashImmunity/{print ""; print "---"}' Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

echo -e "\n=== Utility Helmets (Engineering/Medical/Mining/Atmos/Salvage) ==="
rg "id: ClothingHeadHelmetHardsuit(Engineering|Medical|Mining|Atmos|Salvage)" -A 2 Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

Length of output: 6503

🧰 Tools
🪛 yamllint

[error] 204-204: trailing spaces

(trailing-spaces)

Content.Server/_White/Knockdown/KnockdownSystem.cs (1)

70-71: Potential logic issue with time comparison in delayed knockdown

In the Update method:

if (delayedKnockdown.Delay > _timing.CurTime)
    continue;

Ensure that the comparison correctly determines when to apply the knockdown effect. Consider reversing the comparison operator for clarity:

-if (delayedKnockdown.Delay > _timing.CurTime)
+if (_timing.CurTime < delayedKnockdown.Delay)
    continue;

This change maintains the same logic but may improve readability.

Content.Server/Flash/FlashSystem.cs (1)

203-203: Method signature complexity

The method FlashArea now has a large number of parameters, which can make it difficult to read and use correctly.

Consider grouping related parameters into a configuration object or using named parameters to improve readability.

-public void FlashArea(Entity<FlashComponent?> source, EntityUid? user, float range, float duration, float slowTo = 0.8f,
-    bool displayPopup = false, float probability = 1f, SoundSpecifier? sound = null, float stunTime = 0f, float knockdownTime = 0f)
+public void FlashArea(Entity<FlashComponent?> source, EntityUid? user, FlashAreaConfig config)

...

+public struct FlashAreaConfig
+{
+    public float Range { get; init; }
+    public float Duration { get; init; }
+    public float SlowTo { get; init; }
+    public bool DisplayPopup { get; init; }
+    public float Probability { get; init; }
+    public SoundSpecifier? Sound { get; init; }
+    public float StunTime { get; init; }
+    public float KnockdownTime { get; init; }
+}

This refactoring enhances maintainability and makes it easier to pass parameters.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 76634ba and 3b3d6da.

⛔ Files ignored due to path filters (2)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/knockdown.png is excluded by !**/*.png
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/icon.png is excluded by !**/*.png
📒 Files selected for processing (39)
  • Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1 hunks)
  • Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1 hunks)
  • Content.Server/Flash/FlashSystem.cs (3 hunks)
  • Content.Server/Speech/EntitySystems/StutteringSystem.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (1 hunks)
  • Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownSystem.cs (1 hunks)
  • Content.Shared/Alert/AlertType.cs (1 hunks)
  • Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1 hunks)
  • Content.Shared/Flash/SharedFlashSystem.cs (2 hunks)
  • Content.Shared/Inventory/InventorySystem.Relay.cs (2 hunks)
  • Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (2 hunks)
  • Content.Shared/Stunnable/SharedStunSystem.cs (1 hunks)
  • Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs (0 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1 hunks)
  • Resources/Locale/en-US/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/white-shit.ftl (0 hunks)
  • Resources/Prototypes/Alerts/alerts.yml (2 hunks)
  • Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (18 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml (1 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/security.yml (3 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (1 hunks)
  • Resources/Prototypes/status_effects.yml (1 hunks)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json (1 hunks)
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json (1 hunks)
💤 Files with no reviewable changes (2)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs
  • Resources/Locale/ru-RU/_white/white-shit.ftl
✅ Files skipped from review due to trivial changes (4)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs
  • Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json
🧰 Additional context used
🪛 yamllint
Resources/Prototypes/Alerts/alerts.yml

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

[error] 204-204: trailing spaces

(trailing-spaces)

🔇 Additional comments (48)
Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1)

4-4: Verify the base component implementation.

Let's ensure the base component exists and contains the expected fields for knockdown mechanics.

Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1)

3-4: Verify the component's integration with collision handling.

Since this is a marker component for collision-based knockdowns, we should verify its proper integration with the collision system.

✅ Verification successful

Component is properly integrated with projectile and throw collision events

The verification shows that KnockdownOnCollideComponent is correctly integrated into the collision system through:

  • ProjectileHitEvent handling
  • ThrowDoHitEvent handling

Both events properly invoke the Knockdown method with appropriate parameters. The base class (BaseKnockdownOnComponent) provides all necessary configuration fields for the knockdown effect:

  • Delay timing
  • Knockdown duration
  • Jitter and stutter effects
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how this component is used in collision handling systems

# Look for collision system implementations that handle this component
echo "Checking collision system implementations..."
rg -l "KnockdownOnCollideComponent" --type cs

# Look for specific collision handling logic
echo "Checking collision handling logic..."
ast-grep --pattern 'class $_ : ISystem
{
  $$$
  $_(EntityUid $_, KnockdownOnCollideComponent $_) {
    $$$
  }
  $$$
}'

Length of output: 464


Script:

#!/bin/bash
# Let's check the KnockdownSystem.cs implementation to see how it handles collisions
echo "=== Checking KnockdownSystem.cs implementation ==="
rg -A 10 "KnockdownOnCollideComponent" Content.Server/_White/Knockdown/KnockdownSystem.cs

# Let's also check if there are any collision-related event subscriptions
echo -e "\n=== Checking for collision event subscriptions ==="
rg "ICollide|StartCollide|EndCollide" Content.Server/_White/Knockdown/KnockdownSystem.cs

# Let's verify the base class implementation
echo -e "\n=== Checking BaseKnockdownOnComponent ==="
fd "BaseKnockdownOn.*\.cs" --exec cat {}

Length of output: 1886

Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1)

1-8: Consider adding validation and configuration options.

Since this component is part of a larger flash protection system, consider these architectural improvements:

  1. Add configuration options for different protection levels (e.g., for different types of headgear)
  2. Add validation to ensure MaxRange doesn't exceed reasonable limits

Let's verify the usage of this component:

Content.Server/_White/Knockdown/KnockComponent.cs (1)

3-5: LGTM! Component structure follows ECS pattern.

The component is properly registered and follows the Entity Component System pattern with a clear single responsibility for knockdown configuration.

Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

1-2: Verify the namespace convention.

The underscore prefix in the namespace _White suggests this might be internal/private code. Ensure this aligns with your project's namespace conventions.

✅ Verification successful

Based on the results, I can generate the final response as we have sufficient information about the namespace convention usage across the codebase.

The _White namespace prefix appears to be an established convention in this codebase

The _White namespace prefix is consistently used across multiple components of the codebase:

  • In Content.Server._White.*
  • In Content.Client._White.*
  • In Content.Shared._White.*

This appears to be an intentional and well-established namespace organization pattern, likely representing a specific module or feature set in the project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other files follow similar namespace convention
rg -g "*.cs" "namespace.*_White" -A 1

Length of output: 19276

Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1)

15-16: Verify the inclusion of StunTime field.

The PR objectives mention removing stun effects from tasers, yet this change introduces a new stun mechanic. Please clarify if this is intentional or if it conflicts with the intended design.

Consider adding XML documentation and a default value:

+ /// <summary>
+ /// The duration of the stun effect in seconds when flashed.
+ /// </summary>
 [DataField]
-public float StunTime;
+public float StunTime = 0f;
Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (1)

6-19: Verify integration with protective equipment.

The system appears to handle flash suppression, but we should verify it properly integrates with the protective equipment mentioned in the PR objectives (headphones and helmets).

Let's check the component usage:

✅ Verification successful

Based on the results, I can generate the final response as we have sufficient information about the integration with protective equipment.

Flash sound suppression is properly integrated with protective equipment

The system is correctly integrated with both hardsuit helmets and headsets:

  • All hardsuit helmets have the FlashSoundSuppression component alongside FlashImmunity
  • Alternative headsets (headsets_alt.yml) include the FlashSoundSuppression component
  • The system properly handles the suppression through the InventoryRelayedEvent subscription, which ensures it works when the equipment is worn
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration with protective equipment

# Check for component usage in equipment definitions
echo "Checking equipment definitions for FlashSoundSuppressionComponent..."
rg -l "FlashSoundSuppressionComponent" | grep -i "helmet\|headphone"

# Check for any relevant prototypes
echo "Checking entity prototypes..."
fd -e yml -e yaml | xargs rg "FlashSoundSuppression" -B 2 -A 2

Length of output: 8965

Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

29-30: ⚠️ Potential issue

Verify if removing knockdown effect is intended.

The change from KnockdownOnCollide to LayDownOnCollide with AlwaysDrop behavior appears to remove the knockdown effect from energy crossbow bolts, making the bolt drop instead of knocking down the target. This seems to contradict the PR objectives which aim to enhance knockdown mechanics.

Consider one of these alternatives:

  - type: LayDownOnCollide
-   behavior: AlwaysDrop
+   behavior: KnockdownTarget

or

- - type: LayDownOnCollide
-   behavior: AlwaysDrop
+ - type: KnockdownOnCollide
+   knockdownTime: 3
Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (1)

23-23: Verify knockdown interaction with existing ensnaring effect.

The addition of LayDownOnCollide aligns with the PR's knockdown mechanics. However, this entity already has an Ensnaring component with specific timing and movement effects.

Let's check for potential conflicts or overlapping effects:

Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (3)

1-6: LGTM: Clean and focused imports.

The imports are minimal and relevant to the system's functionality.


11-17: LGTM: Clean event subscription setup.

The Initialize method follows the proper pattern by calling the base implementation and setting up event subscriptions.


29-32: 🛠️ Refactor suggestion

Consider adding validation and error handling for the TryLieDown operation.

The ApplyEffects method should handle potential failures from TryLieDown. Consider checking the return value and logging any failures.

Let's verify if TryLieDown has error handling in its implementation:

 private void ApplyEffects(EntityUid target, LayDownOnCollideComponent component)
 {
-    _layingDown.TryLieDown(target, null, null, component.Behavior);
+    if (!_layingDown.TryLieDown(target, null, null, component.Behavior))
+    {
+        Log.Debug($"Failed to apply lay down effect to entity {target}");
+    }
 }
Resources/Prototypes/status_effects.yml (1)

Line range hint 52-53: Consider adding an alert for BlurryVision.

The BlurryVision status effect might benefit from having an alert to provide visual feedback to players when their vision is impaired. This would be consistent with other visual effects in the game.

Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (3)

51-53: LGTM: Security equipment tag is appropriate.

The SecBeltEquip tag correctly identifies this as security equipment, which is appropriate for its intended use as a less-lethal capture tool.


47-50: Review knockdown duration for game balance.

The current configuration sets:

  • knockdownTime: 2 seconds
  • jitterTime: 7 seconds
  • stutterTime: 7 seconds

These durations seem quite long and might make the weapon overpowered, especially considering it's a throwable item that can be carried on the security belt.

Let's check other knockdown effects in the game for comparison:

#!/bin/bash
# Search for other knockdown configurations
rg "knockdownTime|jitterTime|stutterTime" "Resources/Prototypes/"

1-32: Consider moving common components to BaseBola parent entity.

The current implementation defines many components directly in the Bola entity. Since both Bola and EnergyBola inherit from BaseBola, common components like Construction, Damageable, and Destructible could be moved to the parent entity if they represent shared behavior.

Let's verify if these damage thresholds align with other similar weapons:

Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (2)

28-36: Verify combat balance changes

The significant combat adjustments (50% slower attacks, 59% more stamina damage) represent a major shift in the weapon's effectiveness. While this makes each hit more impactful, it could affect game balance.

Let's check if similar weapons have comparable stats:

✅ Verification successful

Let me search for more specific information about stamina damage to complete the balance verification.


Combat balance changes are appropriate

The stun prod's new stats are well-balanced within the game's weapon ecosystem:

  • Its 0.4 attack rate is among the fastest, justified by its specialized role (other weapons range from 0.65 to 2.0)
  • The bluntStaminaDamageFactor of 2.0 matches most other blunt weapons (baseball bat, sledgehammer, mining tools)
  • Disabling heavy attacks is appropriate for a precision stun weapon
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other melee weapons with attackRate and stamina damage
rg -A 5 "attackRate:|StaminaDamageOnHit:" "Resources/Prototypes/Entities/Objects/Weapons/Melee/"

Length of output: 15865


Script:

#!/bin/bash
# Search for StaminaDamageOnHit components and bluntStaminaDamageFactor in melee weapons
rg "StaminaDamageOnHit:|bluntStaminaDamageFactor:" "Resources/Prototypes/Entities/Objects/Weapons/Melee/"

Length of output: 1004


Line range hint 50-60: Verify power cell integration with existing energy system

The power cell system looks well-implemented, but we should verify compatibility with the existing energyPerUse: 120 in the Stunbaton component.

Let's check the power cell configurations:

✅ Verification successful

Let me search for the Stunbaton component to verify the energy usage:


Let me check the power cell capacities to verify compatibility:


Based on the gathered information, I can now provide the final response:

Power cell integration is compatible with energy usage

The stunprod's energy usage (120 per use) is well within the capacity ranges of standard power cells:

  • Small power cells: 360 charge
  • Medium power cells: 720 charge
  • High power cells: 1080 charge
  • Hyper power cells: 1800 charge

Even the smallest power cell can provide 3 uses (360/120), while higher capacity cells can provide significantly more uses. This is consistent with similar energy weapons in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for power cell definitions and their capacities
rg "type: PowerCell" -A 10

Length of output: 37304


Script:

#!/bin/bash
# Search for Stunbaton component and its energy usage configuration
rg "energyPerUse|type: Stunbaton" -A 5

Length of output: 1725


Script:

#!/bin/bash
# Search for power cell definitions and their charge capacities
rg "PowerCell.*:|maxCharge:|startingCharge:" -A 3

Length of output: 36015

Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (3)

50-51: Good fix: IsActive flag now set after successful component addition.

Moving IsActive = true after the component addition logic is a good improvement. It ensures the flag is only set if all components are successfully added.


Line range hint 36-49: Verify component combination safety.

While the core logic remains unchanged, allowing multiple components increases the risk of conflicting component interactions. Please ensure that all possible component combinations have been tested, particularly for components related to the new knockdown and protection features.


31-34: Verify the increased component limit aligns with all clothing items.

The component limit increase from 1 to 8 makes sense given the PR's objectives (flashbang protection, knockdown effects). However, we should verify this doesn't enable unintended component combinations.

Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (2)

12-12: LGTM: FlashSoundSuppression component addition aligns with PR objectives.

The addition of the FlashSoundSuppression component to the base ClothingHeadsetAlt entity effectively implements the flashbang protection feature mentioned in the PR objectives. This component-based approach ensures all derived headset types inherit this protection.


Line range hint 143-157: LGTM: New freelancer headset follows established patterns.

The ClothingHeadsetAltFreelancer entity is well-structured and consistent with other headset implementations:

  • Proper inheritance from ClothingHeadsetAlt
  • Matches the 5-key-slot configuration like the syndicate variant
  • Correctly configured components (Headset, EncryptionKeyHolder, ContainerFill, Sprite, Clothing)
Resources/Prototypes/Entities/Objects/Weapons/security.yml (3)

Line range hint 144-148: Flash mechanics changes align with protection system.

Setting canBeBlocked: false is appropriate since the PR implements flash protection through equipment (headphones/helmets) rather than blocking mechanics. The explicit damage: 0 ensures it remains a non-lethal tool.

✅ Verification successful

Flash mechanics changes are consistent with the codebase's protection system

The verification confirms that the flash mechanics align with the existing protection system:

  • FlashImmunity component is properly implemented across various protective equipment (glasses, masks, helmets)
  • canBeBlocked: false is consistently used for non-blockable items, including other non-weapon items
  • The change maintains consistency with how similar mechanics are handled in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for related flash protection implementations
rg "canBeBlocked|FlashImmunity" --type yaml

Length of output: 5121


13-13: Verify the increased energy consumption impact.

The energy cost per use has been doubled from 50 to 100. This significant increase will affect the weapon's sustainability in prolonged encounters.

✅ Verification successful

Energy consumption change is balanced with other weapon parameters

The increased energy cost (100 from 50) is balanced by:

  • Maximum charge capacity of 1000 units (10 uses per full charge)
  • Reduced stamina damage (55 down from previous values)
  • Added knockdown effect
  • Slower attack rate (0.4)

The changes form part of a broader rebalancing of the stun baton, making it a more tactical weapon with limited sustained usage while maintaining its effectiveness through the new knockdown mechanic.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any battery-related configurations or balance discussions
rg -l "maxCharge.*1000" | xargs rg "energyPerUse"

Length of output: 5121


Script:

#!/bin/bash
# Let's search for energy-related configurations in security.yml and related files
rg -l "energyPerUse|maxCharge" Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 406


Script:

#!/bin/bash
# Get the content of security.yml to see the full context
cat Resources/Prototypes/Entities/Objects/Weapons/security.yml

Length of output: 5667


Script:

#!/bin/bash
# Search for any other stun baton configurations in the codebase
rg "stunbaton" --type yaml

Length of output: 1553


37-38: Combat mechanics overhaul looks good but needs testing.

The changes implement a balanced approach to the stun baton:

  • Slower attack rate (0.4) compensates for increased stamina damage (55)
  • Disabled heavy attacks prevent abuse
  • Added knockdown effect aligns with PR objectives

The combination of higher stamina damage and knockdown effect could be powerful, but the slower attack rate provides counterplay opportunity.

Also applies to: 41-41, 88-88

Content.Shared/Inventory/InventorySystem.Relay.cs (2)

7-7: LGTM: Required import for FlashbangedEvent.

The addition of the Flash namespace import is necessary for the new event subscription.


33-33: LGTM: Event subscription enables flashbang protection via inventory items.

The subscription to FlashbangedEvent follows the existing relay pattern and enables the implementation of flashbang protection through worn items (headphones/helmets).

Let's verify the event implementation:

✅ Verification successful

Event subscription and implementation verified as correct

The verification confirms that:

  • FlashbangedEvent is properly implemented in SharedFlashSystem.cs with required properties (MaxRange and TargetSlots)
  • It implements IInventoryRelayEvent interface, making it compatible with the relay system
  • The event targets appropriate slots (EARS | HEAD) for flashbang protection
  • The relay subscription is correctly integrated into the existing inventory relay system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify FlashbangedEvent implementation and usage

# Test 1: Check if FlashbangedEvent is properly defined with required properties
ast-grep --pattern 'class FlashbangedEvent {
  $$$
  MaxRange $_
  $$$
  TargetSlots $_
  $$$
}'

# Test 2: Check for proper implementation of flashbang protection in equipment
rg -l "FlashbangedEvent" --type cs

Length of output: 98


Script:

#!/bin/bash
# Let's try a broader search for FlashbangedEvent definition and usage

# Search for FlashbangedEvent class definition
rg -A 10 "class FlashbangedEvent" --type cs

# Search for files containing FlashbangedEvent
rg -l "FlashbangedEvent" --type cs

# Search for any relay handling of FlashbangedEvent
rg -A 5 "FlashbangedEvent.*Relay" --type cs

# Search for any equipment handling of FlashbangedEvent
rg -A 5 "FlashbangedEvent.*Handle" --type cs

Length of output: 2127

Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (2)

124-124: LGTM: DisarmAnimation property follows component conventions.

The property is properly decorated with necessary attributes and follows the existing animation property patterns in the component.


Line range hint 124-172: Verify the impact of new properties on existing combat systems.

The addition of CanHeavyAttack and CanBeBlocked properties may affect existing combat mechanics. Let's verify their usage across the codebase.

✅ Verification successful

Let me gather more information about the combat systems and heavy attack implementation to better understand the impact.


Properties are properly integrated into the combat system

The new properties CanHeavyAttack and related changes are well-integrated into the existing combat system:

  • CanHeavyAttack is properly checked in the client-side melee system before allowing heavy attacks
  • Heavy attacks are fully implemented in SharedMeleeWeaponSystem with proper event handling and stamina costs
  • The properties are already being used in weapon prototypes (e.g., security.yml and stunprod.yml)
  • The blocking system correctly handles these mechanics through MeleeBlockSystem

The implementation is consistent and follows the existing patterns in the codebase. No issues were found with the integration of these new properties.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of new properties in combat-related systems

echo "Checking CanHeavyAttack usage:"
rg "CanHeavyAttack" -A 3

echo -e "\nChecking CanBeBlocked usage:"
rg "CanBeBlocked" -A 3

echo -e "\nChecking related combat systems:"
ast-grep --pattern 'class $_ : ISystem
{
  $$$
  public void $_(EntityUid uid, MeleeWeaponComponent weapon)
  {
    $$$
  }
}'

Length of output: 1752


Script:

#!/bin/bash
# Check for heavy attack implementations and related systems
echo "Checking heavy attack implementations:"
rg "HeavyAttack" -A 5

echo -e "\nChecking melee weapon systems:"
fd -e cs -E "*Test*" -X rg "class.*MeleeWeapon.*System" -A 3

echo -e "\nChecking stamina cost usage:"
rg "HeavyStaminaCost" -A 3

echo -e "\nChecking blocking system implementation:"
fd -e cs -E "*Test*" -X rg "class.*Block.*System" -A 3

Length of output: 14074

Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (2)

119-119: ⚠️ Potential issue

Add null check for CanHeavyAttack property.

Consider adding a null check to prevent potential issues if the property isn't initialized:

-if (altDown == BoundKeyState.Down && weapon.CanHeavyAttack)
+if (altDown == BoundKeyState.Down && weapon.CanHeavyAttack == true)

Likely invalid or redundant comment.


Line range hint 119-141: Verify weapon type handling across the codebase.

The changes to heavy attack conditions need verification to ensure proper handling of all weapon types, especially the newly modified ones (energy balls, shock batons, tasers).

✅ Verification successful

Let me generate additional scripts to gather more specific information about weapon handling and heavy attacks.


Based on the gathered information, I can now provide a final response:

Heavy attack handling has been properly implemented for modified weapons

The codebase shows consistent handling of heavy attacks with proper safeguards:

  • Energy weapons and shock/taser type weapons explicitly set canHeavyAttack: false in their prototypes (e.g., in security.yml and stunprod.yml)
  • The MeleeWeaponComponent properly tracks the CanHeavyAttack property
  • The heavy attack logic in MeleeWeaponSystem correctly checks this flag before allowing heavy attacks
  • The changes properly handle the interaction between gun components and melee weapon components

The modifications ensure that weapons like energy balls, shock batons, and tasers cannot perform heavy attacks while maintaining their intended light attack functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for weapon definitions and verify they properly set CanHeavyAttack
echo "Searching for weapon prototypes..."
rg -l "shock|taser|energy.*ball" "Resources/Prototypes"

# Search for other systems that might interact with heavy attacks
echo "Checking for heavy attack interactions..."
ast-grep --pattern 'CanHeavyAttack'

# Check for potential weapon system interactions
echo "Checking for weapon system interactions..."
rg "MeleeWeapon.*System"

Length of output: 1780


Script:

#!/bin/bash
# Search for MeleeWeapon component definition and usage
echo "Checking MeleeWeapon component definition..."
rg -A 10 "class MeleeWeapon" 

# Search for heavy attack related code
echo "Checking heavy attack implementations..."
rg -A 5 "CanHeavyAttack|HeavyAttack"

# Search specifically for energy weapon implementations
echo "Checking energy weapon implementations..."
rg -A 5 "GunComponent.*Energy|EnergyAmmo"

# Check for shock/taser specific logic
echo "Checking shock/taser specific implementations..."
rg -A 5 "ShockComponent|TaserComponent"

Length of output: 13648

Content.Shared/Stunnable/SharedStunSystem.cs (1)

113-113: Verify the impact of always dropping items on knockdown.

The change from DropIfStanding to AlwaysDrop means that entities will now drop their held items whenever they're knocked down, regardless of their previous state. While this makes the knockdown mechanic more impactful, it could affect gameplay balance.

Let's verify the knockdown sources to ensure this behavior is intended:

✅ Verification successful

Let me gather more context about the knockdown implementation in the PR to understand if this change is intentional.


Based on the gathered context, I can now provide a final response:

The AlwaysDrop behavior change is intentional and correct for knockdowns

The change from DropIfStanding to AlwaysDrop in SharedStunSystem.cs is specifically for the KnockedDownComponent initialization, which is a distinct mechanic from regular lying down. This is correct because:

  1. The new KnockdownSystem.cs shows this is part of a dedicated knockdown mechanic for combat situations (energy balls, shock batons, etc.)
  2. Other lying down cases (like shuttle FTL and general lying down) still use DropIfStanding or NoDrop
  3. The behavior change only affects forced knockdowns from combat, making it a balanced gameplay mechanic where victims drop their items when forcibly knocked down
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for components and systems that can trigger knockdowns
echo "Searching for knockdown triggers..."
rg -l "TryKnockdown|KnockedDownComponent" --type cs

# Search for existing drop behavior configurations
echo "Searching for drop behavior configurations..."
rg "DropHeldItemsBehavior\." --type cs

Length of output: 1938


Script:

#!/bin/bash
# Check the knockdown system implementation
echo "=== Checking knockdown system implementation ==="
cat Content.Server/_White/Knockdown/KnockdownSystem.cs

# Check the laying down system to understand drop behavior usage
echo -e "\n=== Checking laying down system implementation ==="
cat Content.Shared/Standing/SharedLayingDownSystem.cs

# Check for any PR-related changes in these files
echo -e "\n=== Checking git diff for knockdown related files ==="
git diff origin/master -- Content.Server/_White/Knockdown/KnockdownSystem.cs Content.Shared/Standing/SharedLayingDownSystem.cs Content.Shared/Stunnable/SharedStunSystem.cs

Length of output: 15125

Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml (1)

70-71: Verify integration with headphone/helmet protection.

The PR objectives mention that "full-size headphones and certain helmets now provide protection against flashbangs", but this protection mechanism isn't visible in the flashbang configuration.

Let's check for the protection implementation:

✅ Verification successful

The previous search showed some equipment with flash protection in descriptions, but we need to verify the actual implementation. Let's check the code files for flash-related components and protection mechanisms, and also look for specific equipment configurations that might include flash protection properties.


The search results show that flash protection is implemented through FlashImmunity and FlashSoundSuppression components, which are present in various headgear and eyewear. Let's verify the actual implementation of these protection mechanisms to understand how they work with the flashbang configuration.


Based on the gathered information, I can now provide a final response regarding the flash protection implementation:

Flash protection is properly implemented in the codebase

The protection mechanism for flashbangs is implemented through two components:

  • FlashImmunity: Provides immunity against the blinding effect
  • FlashSoundSuppression: Reduces the effective range of the flashbang's sound effect

These components are correctly added to various protective equipment:

  • Hardsuit helmets
  • Security glasses and sunglasses
  • Full-size headsets (with sound suppression)
  • Welding masks and gas masks
  • Ninja visors and mercenary glasses

The flashbang configuration in grenades.yml works in conjunction with these protection components, as the FlashSystem checks for their presence when processing flash effects.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for flashbang protection in equipment files
rg -i 'flash.*protection|protect.*flash' --type yaml

# Search for the FlashOnTrigger component implementation
ast-grep --pattern 'class $_ : IComponent {
  $$$
  flash$_($$$) {
    $$$
  }
  $$$
}'

Length of output: 1773


Script:

#!/bin/bash
# Let's search for flash-related components and systems
rg -l "Flash" --type cs

# Then look for specific flash protection implementation
ast-grep --pattern 'class $_ {
  $$$
  flash$_($$$) {
    $$$
  }
}'

# Search for flash-related yaml configurations
rg -i "flash" --type yaml -A 5 -B 5 Resources/Prototypes/Entities/Clothing/

Length of output: 55849


Script:

#!/bin/bash
# Let's check the flash protection system implementation
rg -A 10 "FlashImmunity|FlashSoundSuppression" --type cs Content.Server/Flash/
rg -A 10 "FlashImmunity|FlashSoundSuppression" --type cs Content.Shared/Flash/

# Also check for any flash-related configuration in the base prototypes
rg -i "flash.*protection|protect.*flash" Resources/Prototypes/base_*.yml

Length of output: 3472

Resources/Prototypes/Alerts/alerts.yml (2)

20-20: LGTM: Alert ordering is appropriate.

The placement of the new alerts in the order list is logical:

  • KnockedDown before Breathing category ensures high visibility for this critical status effect
  • RecentlyBlocked before Deflecting groups related defensive mechanics together

627-628: Verify knockdown sprite existence.

The sprite path references a custom directory. Let's verify its existence.

✅ Verification successful

Sprite exists and is correctly referenced

The knockdown sprite exists at the correct location:

  • Found at Resources/Textures/_White/Interface/Alerts/knockdown.rsi/knockdown.png
  • Directory structure matches the path referenced in alerts.yml
  • The sprite reference in alerts.yml is accurate
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the knockdown sprite exists
fd -t f "knockdown.rsi" "Textures/_White/Interface/Alerts"

# If not found, check if it exists elsewhere in the repository
fd -t f "knockdown.rsi"

Length of output: 200


Script:

#!/bin/bash
# Let's first check the directory structure to understand where textures are stored
fd -t d "Textures"

# Then look for any .rsi files related to knockdown
fd -t f "knockdown.*\.rsi"

# Also check if there might be a different casing
fd -t f -i "knockdown.*\.rsi"

# Let's also check the content of the alerts.yml to see if there are similar sprite references
cat "Resources/Prototypes/Alerts/alerts.yml"

Length of output: 15880


Script:

#!/bin/bash
# Let's check if the correct directory structure exists for the sprite
fd -t d "_White" "Resources/Textures"

# Let's also check for any knockdown-related sprites anywhere in the textures directory
fd -t f -e rsi -e png "knockdown" "Resources/Textures"

# Let's see if there are any other alerts using _White directory pattern
rg "_White/Interface/Alerts" "Resources/Prototypes"

Length of output: 335

🧰 Tools
🪛 yamllint

[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1)

157-157: Verify knockdown integration and parameter validation

The addition of stunTime and knockdownTime parameters aligns with the PR objectives. However, we should ensure proper validation and handling of these durations.

Let's verify the implementation:

#!/bin/bash
# Check FlashSystem implementation for parameter validation
ast-grep --pattern 'class FlashSystem {
  $$$
  FlashArea($_,$_,$_,$_,$_,stunTime:$_,knockdownTime:$_) {
    $$$
  }
  $$$
}'

# Check for any existing knockdown duration validation patterns
rg -A 5 "knockdownTime|stunTime" --type cs
Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (5)

202-204: LGTM: Security helmet flash protection.

The addition of FlashImmunity and FlashSoundSuppression components to security-related helmets (Security, Brigmedic/Corpsman, Warden) is appropriate given their role in handling riot control equipment and flashbangs.

Also applies to: 232-233, 259-260

🧰 Tools
🪛 yamllint

[error] 204-204: trailing spaces

(trailing-spaces)


279-280: LGTM: Captain's helmet flash protection.

Adding flash protection to the Captain's hardsuit helmet is consistent with its role as high-tier protective equipment.


407-409: LGTM: Enhanced Syndicate helmet protection.

The addition of both EyeProtection and flash protection components to Syndicate helmets is appropriate given their role as advanced combat equipment. The inclusion of EyeProtection provides additional protection beyond just flash immunity.

Also applies to: 435-437, 467-469, 495-497, 521-523


622-624: LGTM: ERT helmet protection.

The consistent application of EyeProtection, FlashImmunity, and FlashSoundSuppression across all ERT variants maintains balance while providing appropriate protection for emergency response operations.

Also applies to: 640-642, 665-667, 683-685, 708-710, 726-728


768-770: LGTM: Special helmet enhancements.

The addition of flash protection to CBURN and Deathsquad helmets is appropriate. The Deathsquad helmet's maxRange: 0 parameter on FlashSoundSuppression provides complete sound protection, which is fitting for this elite unit.

Also applies to: 801-804

Content.Server/_White/Knockdown/KnockdownSystem.cs (4)

58-61: Confirm correct scheduling of delayed knockdown

When scheduling a delayed knockdown, you set the Delay property by adding component.Delay to the current time:

knockdown.Delay = _timing.CurTime + component.Delay;

Ensure that component.Delay represents the correct duration and that time units are consistent. Misalignment could cause the knockdown to occur sooner or later than intended.


26-39: Consistent handling of event arguments in event subscribers

In the event handlers OnMeleeHit, OnProjectileHit, and OnThrowDoHit, you're using args.Target as the target entity:

Knockdown(args.Target, component);

Verify that args.Target correctly references the entity intended to be knocked down in all cases. For example, in TakeStaminaDamageEvent, ensure that args.Target is the entity receiving damage.


47-47: ⚠️ Potential issue

Verify the correctness of named parameters in method calls

In lines 47 and 50, you are using named parameters status and statusEffects respectively in the method calls:

  • _jitter.DoJitter(target, component.JitterTime, true, status: statusEffects);
  • _stutter.DoStutter(target, component.StutterTime, true, statusEffects);

Ensure that the parameter names match the method definitions. The inconsistency between status and positional parameters may lead to unexpected behavior.

Run the following script to verify the method signatures and parameter names:

Also applies to: 50-50

✅ Verification successful

Based on the shell script results, I can now generate the final response:

Parameter names in method calls are correct and consistent

The method signatures show that both DoJitter and DoStutter use the parameter name status of type StatusEffectsComponent:

  • DoJitter(EntityUid uid, TimeSpan time, bool refresh, float amplitude = 10f, float frequency = 4f, bool forceValueChange = false, StatusEffectsComponent? status = null)
  • DoStutter(EntityUid uid, TimeSpan time, bool refresh, StatusEffectsComponent? status = null)

The code in question correctly uses the named parameter status in the DoJitter call, and the positional parameter for DoStutter is also correct as it matches the parameter order.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify method signatures for DoJitter and DoStutter

# Search for the DoJitter method definition
rg 'void\s+DoJitter\(' -A 2

# Search for the DoStutter method definition
rg 'void\s+DoStutter\(' -A 2

Length of output: 1216


54-54: ⚠️ Potential issue

Inconsistent usage of statusEffects in _sharedStun.TryKnockdown

In line 54, statusEffects is passed to _sharedStun.TryKnockdown, but in line 73, it is omitted:

  • Line 54: _sharedStun.TryKnockdown(target, component.KnockdownTime, true, statusEffects);
  • Line 73: _sharedStun.TryKnockdown(uid, delayedKnockdown.KnockdownTime, true);

Verify whether statusEffects should be consistently passed in both cases to ensure the knockdown effect applies correctly, especially if statusEffects is required for the method to function as intended.

Run the following script to check the method signature and determine if statusEffects is optional or required:

Also applies to: 73-73

Content.Server/Flash/FlashSystem.cs (2)

2-2: Import statement inclusion is appropriate

The addition of using Content.Server._White.Flash; is necessary for accessing the FlashSoundSuppressionComponent and any other types defined in that namespace.


225-226: Accuracy in distance calculation

The calculation of distance may not account for entities at different map depths or with non-uniform coordinate systems, potentially causing incorrect effect scaling.

Please verify that the distance calculation accurately reflects the in-game spatial relationships, and consider using a method that accounts for map grids and coordinate transforms.

Resources/Locale/ru-RU/_white/alerts/alerts.ftl Outdated Show resolved Hide resolved
Resources/Locale/en-US/_white/alerts/alerts.ftl Outdated Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Outdated Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 28

🧹 Outside diff range and nitpick comments (32)
Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (2)

1-4: Consider adding XML documentation.

Since this component implements important gameplay mechanics (knockdown on collision), it would be helpful to add XML documentation describing:

  • The component's purpose
  • Expected usage scenarios
  • Configuration options inherited from BaseKnockdownOnComponent

Example:

 namespace Content.Server._White.Knockdown;

+/// <summary>
+/// Applies knockdown effect when the entity collides with another entity.
+/// Inherits knockdown configuration (delay, duration, etc.) from <see cref="BaseKnockdownOnComponent"/>.
+/// </summary>
 [RegisterComponent]
 public sealed partial class KnockdownOnCollideComponent : BaseKnockdownOnComponent;

1-4: Consider adding configuration validation.

Since this component will be used with various entities (energy balls, shock batons, taser shots), consider adding data validation through a [DataDefinition] to ensure proper configuration in YAML files.

Example approach:

[DataDefinition]
public sealed partial class KnockdownOnCollideComponent : BaseKnockdownOnComponent
{
    [DataField("enabled")]
    public bool Enabled { get; set; } = true;

    /// <summary>
    /// If true, only apply knockdown to the target entity, not the colliding entity.
    /// </summary>
    [DataField("targetOnly")]
    public bool TargetOnly { get; set; } = true;
}
Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (2)

4-8: Add documentation and improve encapsulation.

The component would benefit from XML documentation explaining its purpose and proper property encapsulation.

 [RegisterComponent]
+/// <summary>
+/// Component that suppresses flash sound effects within a specified range.
+/// Used by headphones and helmets for flashbang protection.
+/// </summary>
 public sealed partial class FlashSoundSuppressionComponent : Component
 {
     [DataField]
-    public float MaxRange = 2f;
+    private float _maxRange = 2f;
+
+    /// <summary>
+    /// Maximum range in meters where flash sound effects are suppressed.
+    /// </summary>
+    public float MaxRange
+    {
+        get => _maxRange;
+        set => _maxRange = Math.Max(0f, value);
+    }
 }

7-7: Consider making the range configurable via prototype.

The hardcoded default range of 2f might need adjustment for game balance. Consider making it configurable via prototype data.

Example prototype:

- type: flashSoundSuppression
  maxRange: 2.0
Content.Server/_White/Knockdown/KnockComponent.cs (2)

3-5: Add XML documentation for the component class.

Since this is a new component implementing game mechanics, please add XML documentation describing its purpose, usage, and interaction with the knockdown system.

 [RegisterComponent]
+/// <summary>
+/// Component that handles knockdown behavior with configurable delay and duration.
+/// Used in conjunction with weapons and items that can knock down characters.
+/// </summary>
 public sealed partial class KnockComponent : Component

1-11: Consider architectural improvements for the knockdown system.

A few suggestions to enhance the component:

  1. Consider adding an interface (e.g., IKnockdownEffect) to standardize knockdown behavior across different implementations
  2. Add events/delegates for knockdown state changes to allow other systems to react
  3. Consider adding a cooldown mechanism to prevent knockdown spam

Would you like me to provide a more detailed implementation for these architectural improvements?

Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

3-4: Add XML documentation for the component class.

Consider adding XML documentation to describe the purpose and usage of this base component, as it's a key part of the knockdown system architecture.

+/// <summary>
+/// Base component for implementing knockdown effects across different interactions.
+/// Derived components can be used to apply knockdown on specific triggers like collision or hits.
+/// </summary>
 public abstract partial class BaseKnockdownOnComponent : Component
Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1)

15-19: Add XML documentation and validation for new public members.

The new fields need documentation and validation:

  1. Add XML documentation to describe the purpose and expected values
  2. Consider adding default values and validation constraints
  3. Consider using properties for better encapsulation

Apply these changes:

     [DataField]
-    public float StunTime;
+    /// <summary>
+    /// The duration in seconds that the flash will stun affected entities.
+    /// </summary>
+    [DataField]
+    public float StunTime { get; set; } = 0f;

     [DataField]
-    public float KnockdownTime;
+    /// <summary>
+    /// The duration in seconds that the flash will knock down affected entities.
+    /// </summary>
+    [DataField]
+    public float KnockdownTime { get; set; } = 0f;
Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (1)

6-13: Add XML documentation to describe the system's purpose.

Consider adding XML documentation to explain that this system handles flash protection for equipment like headphones and helmets.

+/// <summary>
+/// Handles flash sound suppression for protective equipment like headphones and helmets,
+/// reducing the effective range of flashbang effects.
+/// </summary>
 public sealed class FlashSoundSuppressionSystem : EntitySystem
Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

31-31: Consider documenting the blur effect duration

The BlurOnCollide component has been added, but its duration and intensity parameters aren't specified. Consider documenting these parameters to ensure consistent behavior.

🧰 Tools
🪛 yamllint

[error] 31-31: no new line character at the end of file

(new-line-at-end-of-file)

Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1)

10-10: Consider removing the "WD EDIT" comment.

The comment # WD EDIT appears to be non-standard compared to other comments in the file. Consider removing it to maintain consistency with the codebase's commenting style.

-    EnergyBola: 5 # WD EDIT
+    EnergyBola: 5
Content.Shared/Flash/SharedFlashSystem.cs (3)

21-22: Remove custom edit markers

The "WD EDIT" comments are unnecessary when using version control systems. Git already tracks these changes.

-    // WD EDIT START
     public sealed class FlashbangedEvent : EntityEventArgs, IInventoryRelayEvent

22-32: Add XML documentation for public API

Please add documentation to describe the purpose and behavior of this event class and its members.

+    /// <summary>
+    /// Event raised when an entity is affected by a flashbang, allowing inventory items to provide protection.
+    /// </summary>
     public sealed class FlashbangedEvent : EntityEventArgs, IInventoryRelayEvent
     {
+        /// <summary>
+        /// Maximum range at which the flashbang effect should be applied.
+        /// </summary>
         public float MaxRange { get; }

+        /// <summary>
+        /// Inventory slots that can provide protection against flashbangs.
+        /// </summary>
         public SlotFlags TargetSlots => SlotFlags.EARS | SlotFlags.HEAD;

26-26: Consider making TargetSlots more configurable

The hardcoded slot flags might limit future extensibility. Consider making this configurable through a constructor parameter or game configuration.

-    public SlotFlags TargetSlots => SlotFlags.EARS | SlotFlags.HEAD;
+    public SlotFlags TargetSlots { get; }
+
+    public FlashbangedEvent(float maxRange, SlotFlags targetSlots = SlotFlags.EARS | SlotFlags.HEAD)
+    {
+        MaxRange = maxRange;
+        TargetSlots = targetSlots;
+    }
Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (3)

7-9: Consider adding XML documentation for the class.

While the code is clear, adding XML documentation would help other developers understand the system's purpose and responsibilities.

+/// <summary>
+/// Handles laying down behavior when entities collide with projectiles or thrown objects.
+/// </summary>
 public sealed class LayDownOnCollideSystem : EntitySystem

29-32: Add documentation and consider parameter validation.

The method could benefit from XML documentation explaining the purpose and parameters, especially the behavior parameter's significance.

+/// <summary>
+/// Applies the laying down effect to the target entity based on the component's behavior.
+/// </summary>
+/// <param name="target">The entity to apply the effect to</param>
+/// <param name="component">The component containing the laying down behavior</param>
 private void ApplyEffects(EntityUid target, LayDownOnCollideComponent component)
 {
     _layingDown.TryLieDown(target, null, null, component.Behavior);
 }

1-33: Consider adding integration tests for collision scenarios.

Given this system's role in the new knockdown feature, it would be valuable to have integration tests covering various collision scenarios (projectiles, thrown objects) and their interaction with different entity types.

Consider testing:

  1. Projectile collisions with different entity types
  2. Thrown object interactions
  3. Behavior parameter variations
  4. Integration with the broader knockdown system

Would you like help creating a test suite for this system?

Resources/Prototypes/status_effects.yml (1)

Line range hint 69-71: Consider adding documentation for BlurryVision effect.

The status effect appears to be related to flashbang mechanics, but consider adding a comment to document its specific purpose and behavior.

Add a descriptive comment:

 - type: statusEffect
   id: BlurryVision
   alwaysAllowed: true
+  # Applied when character's vision is impaired (e.g., by flashbangs if not wearing protective gear)
Content.Shared/Alert/AlertType.cs (1)

20-20: Consider removing "WD EDIT" comments for consistency.

The comments "// WD EDIT" might not follow the codebase conventions. Consider removing them if they're not part of the standard commenting style.

-    KnockedDown, // WD EDIT
+    KnockedDown,
-    RecentlyBlocked, // WD EDIT
+    RecentlyBlocked,

Also applies to: 71-71

Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (2)

50-51: Consider potential race conditions with IsActive flag.

Moving IsActive = true after component addition is safer as it ensures all components are properly initialized. However, there could be a brief window where components exist but IsActive is false. Consider adding a comment explaining this ordering requirement.

 EntityManager.AddComponent(args.Equipee, (Component)temp!);
+// Set active flag after all components are added to ensure consistent state
 component.IsActive = true;

Line range hint 38-46: Consider adding component conflict resolution.

The current implementation skips adding duplicate components but doesn't handle potential conflicts between different components. For example, if an item grants both flash protection and knockdown effects, we should ensure these effects don't interfere with each other.

Consider:

  1. Adding a validation step to check for incompatible component combinations
  2. Implementing a priority system for conflicting effects
  3. Adding debug logging when components are skipped due to duplicates
Resources/Prototypes/Entities/Objects/Weapons/security.yml (1)

37-38: Combat mechanics changes align with PR objectives.

The changes implement the intended combat adjustments:

  • Disabled heavy attacks and reduced attack rate (0.4) balance the weapon's effectiveness
  • Increased stamina damage (55) enhances its stopping power
  • Added knockdown effect as specified in PR objectives

However, consider adding a cooldown to the knockdown effect to prevent stunlock situations.

Consider implementing a knockdown immunity period or diminishing returns mechanism to prevent potential abuse through repeated knockdowns.

Also applies to: 41-41, 88-88

Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (2)

124-124: Add XML documentation for DisarmAnimation property.

The property follows the correct pattern but would benefit from documentation explaining its purpose and usage.

+    /// <summary>
+    /// The animation prototype to play when performing a disarm action.
+    /// </summary>
     [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
     public EntProtoId DisarmAnimation = "WeaponArcDisarm";

Line range hint 183-184: Consider relocating CanBeBlocked property.

While the property is correctly implemented, it would be more maintainable if grouped with other combat-related properties near the ContestArgs field.

-    // WD EDIT START
-    [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
-    public bool CanBeBlocked = true;
-    // WD EDIT END

     /// <summary>
     ///     If true, the weapon must be equipped for it to be used.
     ///     E.g boxing gloves must be equipped to your gloves,
     ///     not just held in your hand to be used.
     /// </summary>
     [DataField, AutoNetworkedField]
     public bool MustBeEquippedToUse = false;
+
+    /// <summary>
+    /// Determines if the weapon's attacks can be blocked by defensive actions.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+    public bool CanBeBlocked = true;
Resources/Prototypes/Alerts/alerts.yml (1)

20-20: Remove unnecessary comment.

The placement of KnockedDown in the alert order is correct, but the comment # WD EDIT is unnecessary and should be removed for consistency with the rest of the file.

-    - alertType: KnockedDown # WD EDIT
+    - alertType: KnockedDown
Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1)

156-158: Consider adding XML documentation for the new parameters.

The method's parameters would benefit from XML documentation explaining the expected units (seconds/milliseconds) for stunTime and knockdownTime.

Add documentation above the method:

+        /// <summary>
+        /// Handles flash trigger events.
+        /// </summary>
+        /// <param name="uid">The entity being triggered</param>
+        /// <param name="component">The flash trigger component</param>
+        /// <param name="args">The trigger event arguments</param>
+        /// <param name="stunTime">Duration of the stun effect in seconds</param>
+        /// <param name="knockdownTime">Duration of the knockdown effect in seconds</param>
         private void HandleFlashTrigger(EntityUid uid, FlashOnTriggerComponent component, TriggerEvent args)
Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (3)

801-804: Document the maxRange parameter.

The Deathsquad helmet is the only one with a maxRange: 0 parameter for FlashSoundSuppression. Consider adding a comment explaining the significance of this parameter and why it's unique to this helmet.


Line range hint 202-804: Consider standardizing flash protection across helmet tiers.

The flash protection components are inconsistently applied:

  • Some helmets have only FlashImmunity and FlashSoundSuppression
  • Others also include EyeProtection
  • Only the Deathsquad helmet has a maxRange parameter

Consider creating a standardized protection scheme based on helmet tiers (e.g., basic, advanced, elite) to make the system more maintainable and easier to understand.


Based on the search results, I can generate the final response as I have comprehensive information about the "brigmedic" references in the codebase.

Rename from "brigmedic" to "corpsman" needs to be completed consistently across the codebase

While some instances have been updated to use "corpsman" (like names and descriptions), there are still many references using "brigmedic" that need to be updated for consistency:

  • Entity IDs still use "brigmedic" (e.g., ClothingHeadHelmetHardsuitBrigmedic, ClothingBackpackBrigmedic)
  • File and directory names contain "brigmedic" (e.g., brigmedic.rsi, brigmedic.yml)
  • Sprite paths and states use "brigmedic" (e.g., Clothing/Head/Hardsuits/brigmedic.rsi)
  • Job-related identifiers use "brigmedic" (e.g., JobBrigmedic, BrigmedicGear)
  • Various prototype IDs contain "brigmedic"

This inconsistency between the display names ("corpsman") and the internal identifiers ("brigmedic") could lead to confusion during future maintenance.

🔗 Analysis chain

Line range hint 205-233: Verify the brigmedic to corpsman rename.

The rename from "brigmedic" to "corpsman" is reflected in the name and description but the entity ID and sprite paths still use "brigmedic". This might cause confusion in the future.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to "brigmedic" in the codebase
# that might need to be updated for consistency.

# Search for "brigmedic" references
rg -i "brigmedic"

# Search for files with "brigmedic" in their name
fd "brigmedic"

Length of output: 25194

Content.Server/_White/Knockdown/KnockdownSystem.cs (2)

10-12: Review the namespace naming convention

The namespace Content.Server._White.Knockdown includes an underscore, which might not align with the project's naming conventions.

Consider renaming the namespace to match the standard convention, such as Content.Server.White.Knockdown, to improve consistency.


41-61: Add XML documentation comments to public methods

The Knockdown method is a critical part of the system but lacks documentation. Adding XML comments would improve code readability and maintainability.

Consider adding summaries to explain the purpose and usage of the method.

/// <summary>
/// Applies knockdown effects to the target entity based on the provided component settings.
/// </summary>
/// <param name="target">The entity to apply knockdown to.</param>
/// <param name="component">The component containing knockdown settings.</param>
private void Knockdown(EntityUid target, BaseKnockdownOnComponent component)
Content.Server/Flash/FlashSystem.cs (1)

223-227: Remove development comments from production code

The comments // WD EDIT START and // WD EDIT END are present in the code. These are likely used during development but should be removed to maintain code cleanliness and professionalism.

Apply this diff to remove the comments:

- // WD EDIT START
var distance = (mapPosition.Position - _transform.GetMapCoordinates(entity).Position).Length();
FlashStun(entity, stunTime, knockdownTime, distance, range);
- // WD EDIT END

After removal:

var distance = (mapPosition.Position - _transform.GetMapCoordinates(entity).Position).Length();
FlashStun(entity, stunTime, knockdownTime, distance, range);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 76634ba and 3b3d6da.

⛔ Files ignored due to path filters (2)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/knockdown.png is excluded by !**/*.png
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/icon.png is excluded by !**/*.png
📒 Files selected for processing (39)
  • Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1 hunks)
  • Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1 hunks)
  • Content.Server/Flash/FlashSystem.cs (3 hunks)
  • Content.Server/Speech/EntitySystems/StutteringSystem.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (1 hunks)
  • Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownSystem.cs (1 hunks)
  • Content.Shared/Alert/AlertType.cs (1 hunks)
  • Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1 hunks)
  • Content.Shared/Flash/SharedFlashSystem.cs (2 hunks)
  • Content.Shared/Inventory/InventorySystem.Relay.cs (2 hunks)
  • Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (2 hunks)
  • Content.Shared/Stunnable/SharedStunSystem.cs (1 hunks)
  • Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs (0 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1 hunks)
  • Resources/Locale/en-US/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/white-shit.ftl (0 hunks)
  • Resources/Prototypes/Alerts/alerts.yml (2 hunks)
  • Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (18 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml (1 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/security.yml (3 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (1 hunks)
  • Resources/Prototypes/status_effects.yml (1 hunks)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json (1 hunks)
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json (1 hunks)
💤 Files with no reviewable changes (2)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs
  • Resources/Locale/ru-RU/_white/white-shit.ftl
✅ Files skipped from review due to trivial changes (4)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs
  • Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json
🧰 Additional context used
🪛 yamllint
Resources/Prototypes/Alerts/alerts.yml

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

[error] 204-204: trailing spaces

(trailing-spaces)

🔇 Additional comments (39)
Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (2)

1-4: LGTM! Clean and well-structured component implementation.

The component follows good practices:

  • Proper namespace organization
  • Correct component registration
  • Clean inheritance from base component
  • Follows ECS pattern

1-4: Verify the knockdown system integration.

Let's verify that the corresponding system properly handles this component.

✅ Verification successful

Component is properly integrated with the knockdown system

The KnockdownSystem correctly handles the KnockdownOnCollideComponent through:

  • Subscription to ProjectileHitEvent and ThrowDoHitEvent
  • Proper implementation of collision handlers that call the shared Knockdown method
  • Integration with the base knockdown functionality via BaseKnockdownOnComponent
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the knockdown system implementation and its handling of KnockdownOnCollideComponent

# Test 1: Find the system that handles this component
echo "Looking for knockdown system implementation..."
ast-grep --pattern 'class $SYSTEM : ISystem
{
  $$$
  KnockdownOnCollideComponent $$$
  $$$
}'

# Test 2: Verify collision event handling
echo "Checking collision event handling..."
rg -l "ICollideEvent.*KnockdownOnCollideComponent"

Length of output: 199


Script:

#!/bin/bash
# Let's try a different approach to find the system implementation

# Search for any system class that might handle KnockdownOnCollideComponent
echo "Searching for system implementations handling KnockdownOnCollideComponent..."
rg -A 5 "KnockdownOnCollideComponent" --type cs

# Search for base class implementation
echo "Searching for base knockdown component implementation..."
rg -A 5 "BaseKnockdownOnComponent" --type cs

# Look for collision-related systems
echo "Searching for collision-related systems..."
fd -e cs | xargs rg "ICollideEvent.*Knockdown"

Length of output: 4524

Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1)

1-8: Verify the suppression range for game balance.

The 2-meter range needs verification to ensure it provides meaningful protection without being overpowered.

Resources/Locale/ru-RU/_white/alerts/alerts.ftl (2)

2-3: LGTM! Clean formatting.

The added newline improves readability and maintains consistent spacing between alert entries.


4-5: Verify localization consistency across language files.

Let's ensure these new alert keys are present in all language files to maintain localization coverage.

✅ Verification successful

Let me verify the content of these files to better understand the localization structure.


Localization structure is correct and consistent

The knockdown alert keys are properly implemented in both English and Russian localization files under the _white/alerts/alerts.ftl path. The other alert files (mood-alerts.ftl, alerts.ftl, and admin-chatalert.ftl) serve different purposes and don't need these keys. The implementation is consistent across both language files with proper color formatting and equivalent translations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if knockdown alert keys exist in all language files
# Expected: The keys should be present in all language files under Resources/Locale

# Find all locale directories and check for the knockdown alert keys
fd -t f "alerts.ftl" "Resources/Locale" -x grep -l "alerts-knockdown-name" {} \; | sort

# Show which files are missing the new keys (if any)
echo "Files missing knockdown alert keys:"
fd -t f "alerts.ftl" "Resources/Locale" -x sh -c 'if ! grep -q "alerts-knockdown-name" "{}"; then echo "{}"; fi' \;

Length of output: 548


Script:

#!/bin/bash
# Check content of files that have the key
echo "=== Content of files with knockdown alerts ==="
fd -t f "alerts.ftl" "Resources/Locale" -x sh -c 'if grep -q "alerts-knockdown-name" "{}"; then echo "=== {} ==="; cat "{}"; fi' \;

# Check if there are other alert-related files
echo -e "\n=== All alert-related files ==="
fd "alerts?.ftl" "Resources/Locale"

Length of output: 1301

Content.Server/_White/Knockdown/KnockComponent.cs (1)

1-2: Query: Is "_White" namespace following project conventions?

The custom "_White" namespace might not align with standard project organization. Consider moving this to a more conventional namespace structure if it's intended to be a core game feature.

Let's check the namespace conventions in the project:

Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

1-16: Review knockdown duration for gameplay balance.

The current implementation has:

  • 5 second knockdown duration which might feel too long and frustrating
  • 2 second delay which might feel unresponsive
  • 15 second jitter/stutter effects which seem excessive

Consider playtesting these values to ensure they provide a balanced and enjoyable gameplay experience.

The overall architecture looks solid with:

  • Good separation of concerns
  • Configurable parameters through data fields
  • Extensible base class design
Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1)

13-20: Verify the integration with other systems.

The changes look good but let's verify the integration with related systems mentioned in the AI summary.

✅ Verification successful

Integration verified and properly implemented

The verification shows that the StunTime and KnockdownTime parameters are correctly integrated:

  1. The parameters are properly passed from TriggerSystem to FlashSystem.FlashArea() method
  2. FlashSystem implements these parameters in its FlashArea method and uses them in FlashStun
  3. The implementation chain is complete:
    • FlashOnTriggerComponent defines the parameters
    • TriggerSystem passes them to FlashSystem
    • FlashSystem applies them via FlashArea and FlashStun
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of StunTime and KnockdownTime fields
# Expected: Find references in TriggerSystem and FlashSystem

# Check for StunTime usage
echo "Checking StunTime usage:"
rg -p "StunTime" --type cs

# Check for KnockdownTime usage
echo "Checking KnockdownTime usage:"
rg -p "KnockdownTime" --type cs

# Check for related system implementations
echo "Checking related systems:"
ast-grep --pattern 'class $_ : EntitySystem {
  $$$
  Flash$_($$$) {
    $$$
  }
  $$$
}'

Length of output: 4035


Script:

#!/bin/bash
# Let's check the FlashSystem implementation and its usage of these parameters

# Check for FlashSystem implementation
echo "Checking FlashSystem implementation:"
ast-grep --pattern 'class $_ {
  $$$
  FlashArea($$$stunTime$$$knockdownTime$$$) {
    $$$
  }
  $$$
}'

# Check for any other Flash-related methods that might use these parameters
echo "Checking other Flash-related methods:"
rg -p "Flash.*stunTime.*knockdownTime" -A 5 --type cs

# Check TriggerSystem's interaction with FlashSystem
echo "Checking TriggerSystem implementation:"
rg -p "class.*TriggerSystem.*:.*EntitySystem" -A 10 --type cs

Length of output: 12802

Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (2)

1-4: LGTM! Clean and focused imports.

The imports are minimal and appropriate for the functionality needed.


6-19: Verify component registration in the component factory.

Let's ensure the FlashSoundSuppressionComponent is properly registered in the component factory.

Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

29-30: ⚠️ Potential issue

Verify the intended behavior: LayDown vs Knockdown

The change from KnockdownOnCollide to LayDownOnCollide with AlwaysDrop behavior seems to diverge from the PR objectives, which specifically mention implementing knockdown mechanics. Please confirm if this is intentional or if it should use the knockdown component instead.

✅ Verification successful

Based on the search results, I can now generate a final response as there's clear evidence about the distinction between LayDownOnCollide and KnockdownOnCollide components in the codebase.

LayDownOnCollide is the correct component to use here

The change from KnockdownOnCollide to LayDownOnCollide is actually consistent with the codebase's design. These are two distinct mechanics:

  • LayDownOnCollide is used for weapons that force targets to lie down (like bolas and energy bolts)
  • KnockdownOnCollide is a separate system with additional effects like jitter time, used by different projectiles

The implementation is correct as it aligns with similar weapons like bolas that use the same component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of LayDownOnCollide vs KnockdownOnCollide
echo "Searching for LayDownOnCollide usage:"
rg "LayDownOnCollide" -A 2

echo -e "\nSearching for KnockdownOnCollide usage:"
rg "KnockdownOnCollide" -A 2

Length of output: 4629

Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (1)

3-4: LGTM! Good abstraction practice.

Converting Bola to BaseBola with abstract: true creates a proper base template for different bola variants, improving code organization and reusability.

Content.Shared/Flash/SharedFlashSystem.cs (1)

22-22: Verify inventory system integration

Let's ensure the inventory system properly handles this new event.

✅ Verification successful

Integration verified successfully

The FlashbangedEvent is properly integrated with the inventory system:

  • It implements IInventoryRelayEvent interface
  • It's subscribed in InventorySystem.Relay.cs using RelayInventoryEvent handler
  • The subscription is part of the standard inventory relay events alongside other vision/eye-related events
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for FlashbangedEvent usage in inventory system
echo "Checking inventory system integration..."
rg -l "FlashbangedEvent" --type cs

# Search for any relay event registrations
echo "Checking event relay registration..."
ast-grep --pattern 'InitializeRelay($$$)' --lang cs

Length of output: 780


Script:

#!/bin/bash
# Let's check the actual implementation of inventory relay for FlashbangedEvent
echo "Checking inventory relay implementation..."
rg -A 10 "FlashbangedEvent" Content.Shared/Inventory/InventorySystem.Relay.cs

# Also check the base inventory system implementation
echo "Checking base inventory system..."
rg "IInventoryRelayEvent" Content.Shared/Inventory/InventorySystem.cs

Length of output: 933


Script:

#!/bin/bash
# Let's verify the RelayInventoryEvent method implementation
echo "Checking RelayInventoryEvent implementation..."
ast-grep --pattern 'RelayInventoryEvent<$_>($$$)' --lang cs

# Also check if there are any other relevant relay methods
echo "Checking other relay methods..."
rg "RelayInventoryEvent" Content.Shared/Inventory/InventorySystem.cs

Length of output: 306

Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (3)

1-5: LGTM! Dependencies and namespace are well-organized.

The imports are minimal and appropriate for the system's functionality.


11-17: LGTM! Event subscriptions are properly configured.

The Initialize method correctly sets up event handlers for both projectile hits and thrown object collisions.


19-27: 🛠️ Refactor suggestion

Consider adding null checks and error handling.

While the current implementation is clean, it might benefit from explicit null checks and error handling for robustness.

Let's verify if there are similar systems in the codebase that implement error handling:

Consider adding checks:

 private void OnEntityHit(Entity<LayDownOnCollideComponent> ent, ref ThrowDoHitEvent args)
 {
+    if (!Resolve(args.Target, ref args.TargetStanding))
+        return;
+
     ApplyEffects(args.Target, ent.Comp);
 }
Resources/Prototypes/status_effects.yml (1)

Line range hint 64-67: Verify the purpose of RecentlyBlocked status effect.

While the implementation looks correct, the purpose and usage of this status effect isn't clear from the PR objectives.

Let's check where this status effect is used:

✅ Verification successful

Based on the code analysis, I can now generate the final response:

RecentlyBlocked status effect is used to prevent rapid blocking in combat

The status effect is applied by the MeleeBlockSystem when a player successfully blocks an attack. It serves as a cooldown mechanism to prevent continuous blocking, making combat more balanced. The implementation is appropriate and aligns with standard combat mechanics.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usage of RecentlyBlocked status effect
# Expected: Find components or systems that apply this status effect

rg -A 5 "RecentlyBlocked" --type-add 'cs:*.cs' --type cs

Length of output: 566


Script:

#!/bin/bash
# Let's check the implementation details of MeleeBlockSystem to understand the purpose
ast-grep --pattern 'class MeleeBlockSystem {
  $$$
}'

Length of output: 55


Script:

#!/bin/bash
# Let's check the content of the MeleeBlockSystem file to understand the purpose
rg -l "MeleeBlockSystem" --type cs | xargs cat

Length of output: 53180

Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (1)

1-32: ⚠️ Potential issue

Review damage thresholds and consider adding knockdown effects

Several concerns with the current implementation:

  1. The damage thresholds (75 and 15) seem disproportionate to the damage dealt (5).
  2. Both damage thresholds result in destruction, making the higher threshold redundant.
  3. Missing knockdown effects that align with the PR objectives.

Let's verify the damage values in similar weapons:

Consider applying these changes:

  - type: Destructible
    thresholds:
    - trigger:
        !type:DamageTrigger
-        damage: 75
+        damage: 25
      behaviors:
        - !type:DoActsBehavior
          acts: [ "Destruction" ]
-    - trigger:
-        !type:DamageTrigger
-        damage: 15
-      behaviors:
-      - !type:PlaySoundBehavior
-        sound:
-          collection: MetalBreak
-      - !type:DoActsBehavior
-        acts: [ "Destruction" ]
+  - type: KnockdownOnCollide
+    knockdownTime: 2
+    jitterTime: 5
+    stutterTime: 5
Content.Shared/Alert/AlertType.cs (3)

20-20: LGTM: KnockedDown placement is logical.

The placement of KnockedDown after Stun and before Handcuffed is logical as it groups related character status effects together. This aligns well with the PR objective of implementing knockdown mechanics.


Line range hint 71-71: LGTM: RecentlyBlocked placement maintains enum ordering.

The placement of RecentlyBlocked at the end of the enum maintains proper value ordering and prevents any serialization issues that could arise from inserting values in the middle.


Line range hint 1-74: Verify enum value count within byte range.

Since this enum is explicitly using byte for compact encoding (0-255 range), let's verify we haven't exceeded the limit with these additions.

✅ Verification successful

Let me try a different approach to count the enum values.


Let me try one more approach using a simpler pattern matching.


Enum value count is well within byte range limits

The enum currently has 62 values, which is well below the byte limit of 255. The compact encoding using byte type is appropriate and has plenty of room for future additions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Count the number of enum values to ensure we're within byte range (0-255)
enum_count=$(rg -U "public enum AlertType[\s\S]*?{([\s\S]*?)}" Content.Shared/Alert/AlertType.cs | rg -c ",")
echo "Number of enum values: $enum_count"
if [ "$enum_count" -gt 255 ]; then
    echo "WARNING: Enum count exceeds byte range!"
fi

Length of output: 424


Script:

#!/bin/bash
# Count non-empty, non-comment lines between the enum declaration and the last shown value
rg -U "public enum AlertType.*\{([^}]+)" Content.Shared/Alert/AlertType.cs | \
  grep -v "^[[:space:]]*//.*$" | \
  grep -v "^[[:space:]]*$" | \
  grep "," | \
  wc -l

Length of output: 153


Script:

#!/bin/bash
# Count enum values by looking for lines ending with comma
cat Content.Shared/Alert/AlertType.cs | \
  sed -n '/public enum AlertType/,/}/p' | \
  grep -c ',$'

Length of output: 97

Content.Server/Speech/EntitySystems/StutteringSystem.cs (1)

Line range hint 28-34: LGTM: Clean integration with knockdown mechanics.

The DoStutter method provides a robust integration point for the knockdown system through the status effects system. The implementation allows for flexible control over the stuttering duration and stacking behavior.

Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (4)

Line range hint 50-61: LGTM: Power cell implementation follows standard patterns.

The power cell slot configuration is well-structured and properly integrated with the visual system.


62-63: Verify knockdown duration consistency across weapons.

The 3-second knockdown duration needs to be verified against other weapons for gameplay balance.

Let's check other knockdown implementations:

✅ Verification successful

Knockdown duration of 3 seconds is inconsistent with other weapons

The stunprod's 3-second knockdown duration falls between other weapon implementations:

  • Bola: 2 seconds
  • Stunprod: 3 seconds
  • Projectiles and grenades: 10 seconds

The duration appears to be a middle ground between less powerful throwables (bolas) and more powerful weapons (projectiles/grenades), which seems reasonable for a melee weapon like the stunprod.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other knockdown configurations to ensure consistent durations
rg "KnockdownOnHit[\s\S]*?knockdownTime:" Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 175


Script:

#!/bin/bash
# Let's try a broader search for knockdown configurations across all resources
rg "knockdownTime:" Resources/Prototypes/

# Also search for any KnockdownOnHit components to see all implementations
rg "type: KnockdownOnHit" Resources/Prototypes/

Length of output: 676


28-28: LGTM: Combat balance changes align with objectives.

The reduced attack rate and disabled heavy attacks appropriately balance the weapon's combat utility.

Let's verify no other stun weapons have conflicting attack rates:

Also applies to: 34-34

✅ Verification successful

These commands should help us find other melee weapons and their attack rate configurations to verify the consistency of the balance changes.


Attack rate change is consistent with similar weapons

Looking at the search results, the 0.4 attack rate for the stun prod aligns with other security/stun weapons:

  • Other stun weapons also use 0.4 attack rate (see Resources/Prototypes/Entities/Objects/Weapons/security.yml)
  • Most combat weapons have higher attack rates (0.75-1.5)
  • The lower attack rate appropriately balances the stun prod's incapacitation utility
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other weapons with attack rates to ensure consistent balancing
rg -U "type: MeleeWeapon[\s\S]*?attackRate:" Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 175


Script:

#!/bin/bash
# Let's try a different approach to find melee weapon configurations
rg -U "- type: MeleeWeapon" -A 5 Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 486


Script:

#!/bin/bash
# Also search specifically in the Melee directory
rg -U "- type: MeleeWeapon" -A 5 "Resources/Prototypes/Entities/Objects/Weapons/Melee/"

Length of output: 492


Script:

#!/bin/bash
# Search for any attackRate configurations in the entire codebase
rg "attackRate:" Resources/Prototypes/

Length of output: 9886


36-36: Verify the combined impact of increased stamina damage and knockdown.

The 59% increase in stamina damage combined with the new knockdown effect might be too powerful. Consider testing this combination in gameplay.

Let's check other weapons' stamina damage for comparison:

✅ Verification successful

The stamina damage increase appears balanced when compared to similar weapons

The stunprod's stamina damage of 35 is actually moderate compared to other security weapons:

  • Security baton has 55 stamina damage
  • Regular cane has only 5 stamina damage
  • Both weapons have the same knockdown duration of 3 seconds

The combination of 35 stamina damage with a 3-second knockdown provides a balanced middle ground between the stronger security baton (55 damage) and weaker weapons, making it an appropriate value for this weapon type.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other weapons with stamina damage to compare balance
rg "StaminaDamageOnHit[\s\S]*?damage:" Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 175


Script:

#!/bin/bash
# Let's try a broader search for stamina damage in weapons
rg -A 2 "StaminaDamageOnHit" Resources/Prototypes/Entities/Objects/Weapons/ --no-heading

# Also search for stamina damage in melee weapons specifically
rg -A 2 "StaminaDamageOnHit" Resources/Prototypes/Entities/Objects/Weapons/Melee/ --no-heading

# Search for any damage components to understand the damage scale
rg -A 2 "damage:" Resources/Prototypes/Entities/Objects/Weapons/Melee/ --no-heading

Length of output: 18484


Script:

#!/bin/bash
# Let's search for knockdown effects to understand the full context
rg -A 2 "KnockdownOnHit" Resources/Prototypes/Entities/Objects/Weapons/ --no-heading

# Also search for any stun-related components
rg -A 2 "Stun" Resources/Prototypes/Entities/Objects/Weapons/ --no-heading

Length of output: 2606

Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (1)

Line range hint 16-16: Verify department naming consistency across codebase.

The department renaming from "Cargo" to "logistics" and "Science" to "mystagogue" should be consistently applied across all related files.

Also applies to: 89-89

✅ Verification successful

Based on the comprehensive search results, I can now provide a final response:

Department renaming changes are consistently applied across the codebase

The renaming changes from "Cargo" to "Logistics" and "Science" to "Epistemics/Mystagogue" have been thoroughly and consistently implemented across the codebase, including:

  • All department references in prototypes, maps, and configurations
  • Job titles (e.g., "Cargo Technician" → "Logistics Technician", "Research Director" → "Mystagogue")
  • Equipment names and descriptions
  • Access levels and security configurations
  • UI elements and department colors
  • Radio channels and communication systems

The changes are properly documented with "DeltaV" comments indicating intentional department replacements.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for potential inconsistencies in department naming
echo "Checking for potential inconsistent department references..."
rg -i "cargo department|science department" --type yaml

echo "Checking for potential missed renames..."
rg -i "\b(cargo|science)\b.*(headset|officer)" --type yaml

Length of output: 340


Script:

#!/bin/bash
# Let's try a broader search to find any remaining references to these departments
echo "Searching for 'cargo' references..."
rg -i "\bcargo\b" --type yaml -A 2 -B 2

echo -e "\nSearching for 'science' references..."
rg -i "\bscience\b" --type yaml -A 2 -B 2

echo -e "\nSearching for new terms to verify consistency..."
rg -i "logistics.*officer|mystagogue" --type yaml -A 2 -B 2

Length of output: 270472

Resources/Prototypes/Entities/Objects/Weapons/security.yml (2)

13-13: Consider the balance impact of doubled energy consumption.

The energy cost per use has been doubled from 50 to 100. This significant increase could severely limit the weapon's utility in extended encounters.

Let's check if this change is consistent with other energy-based weapons:

✅ Verification successful

Let me try another search to find the correct information about energyPerUse configurations:


Energy consumption is in line with similar weapons

The increase to 100 energy per use for the stun baton is balanced, as it sits below the stunprod's 120 energy consumption. This creates a clear hierarchy where the standard security baton is more energy efficient than the makeshift stunprod alternative.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other energyPerUse configurations
rg "energyPerUse:" -A 1

Length of output: 1591


Script:

#!/bin/bash
# Search for energyPerUse configurations in yaml files
rg "energyPerUse:" --type yaml

Length of output: 208


Line range hint 147-149: Flash mechanics updated for consistency.

The changes ensure that:

  • Flash cannot be blocked by default weapons/shields (canBeBlocked: false)
  • Explicitly set to deal no damage, clarifying its intended use as a non-damaging weapon

This aligns with the PR objective regarding flashbang protection mechanics.

Let's verify the flash protection implementation mentioned in PR objectives:

✅ Verification successful

The search results show consistent usage of FlashImmunity component across various protective equipment like welding helmets, hardsuit helmets, glasses, and masks. This aligns with the changes made to the flash entity where canBeBlocked: false was added, ensuring that flash effects can only be prevented by items with explicit FlashImmunity rather than through general blocking mechanics.

Let's verify if there are any other flash-related mechanics we should check:


Let's verify the flash damage system since the changes explicitly set damage to 0:


Flash mechanics changes verified and consistent

The changes align perfectly with the codebase implementation:

  • Setting canBeBlocked: false correctly enforces that only entities with FlashImmunity component can resist flash effects
  • Setting damage: 0 is appropriate as flash damage is handled separately through the DamagedByFlashingComponent, which can be added to specific entities that should take damage from flashes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for flash protection in headphone/helmet definitions
rg -p "type: FlashImmunity|type: FlashProtection" 

Length of output: 1591


Script:

#!/bin/bash
# Search for flash-related components and systems
rg -p "class.*Flash|struct.*Flash" --type-add 'code:*.{cs}' --type code

Length of output: 2950


Script:

#!/bin/bash
# Check flash damage implementation
cat Content.Server/Flash/DamagedByFlashingSystem.cs

Length of output: 808

Content.Shared/Inventory/InventorySystem.Relay.cs (2)

7-7: LGTM!

The using directive for Content.Shared.Flash is appropriately placed and required for the FlashbangedEvent type.


33-33: Verify FlashbangedEvent implementation.

The event subscription follows the established pattern and integrates well with the existing relay system. However, let's verify the FlashbangedEvent implementation to ensure it properly implements IInventoryRelayEvent.

✅ Verification successful

FlashbangedEvent implementation is correctly implemented

The event is properly implemented in Content.Shared/Flash/SharedFlashSystem.cs:

  • Implements IInventoryRelayEvent interface
  • Defines TargetSlots property targeting SlotFlags.EARS | SlotFlags.HEAD
  • Has appropriate constructor and properties
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify FlashbangedEvent implementation
# Expected: FlashbangedEvent should implement IInventoryRelayEvent and define TargetSlots

# Search for FlashbangedEvent definition
ast-grep --pattern 'class FlashbangedEvent : $_ {
  $$$
}'

# Verify IInventoryRelayEvent implementation
rg -l "class FlashbangedEvent.*:.*IInventoryRelayEvent"

# Check TargetSlots property implementation
ast-grep --pattern 'class FlashbangedEvent {
  $$$
  TargetSlots {
    $$$
  }
  $$$
}'

Length of output: 60


Script:

#!/bin/bash
# Let's try a broader search approach to locate FlashbangedEvent

# Search for any mention of FlashbangedEvent
rg "FlashbangedEvent" -A 5 -B 5

# Search for files containing FlashbangedEvent
fd -t f -e cs | xargs grep -l "FlashbangedEvent"

# Try to find the file containing the event definition
rg "class.*FlashbangedEvent" -A 10

Length of output: 6304

Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (1)

125-126: Verify the integration of heavy attack functionality.

The property is well-placed and aligns with the PR objectives. Let's verify its usage across the codebase.

Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1)

119-119: LGTM! Verify weapon compatibility.

The addition of the CanHeavyAttack check is well-integrated into the existing alt-click handling logic.

Let's verify that existing weapons have been properly updated with this property:

✅ Verification successful

Let me analyze the search results:

  1. Looking at the YAML files, I can see that MeleeWeaponComponent is widely used across many entities, and the CanHeavyAttack property is not commonly defined in any of them.

  2. The property appears to be a new addition to the component, which means existing weapons would default to its default value (likely false) unless explicitly set.

Let me verify the component definition to understand the default value:


Based on the search results, I can now provide a definitive response:

The CanHeavyAttack check is safe - it defaults to true

The code shows that CanHeavyAttack is defined in MeleeWeaponComponent with a default value of true. This means all existing weapons will support heavy attacks by default unless explicitly configured otherwise, making this change backward compatible with existing weapons.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for weapon definitions to ensure they specify CanHeavyAttack
ast-grep --pattern 'new MeleeWeaponComponent {
  $$$
}'

Length of output: 57


Script:

#!/bin/bash
# Let's try a different approach to find MeleeWeaponComponent definitions
# First, let's search for files that might contain weapon definitions
fd -e yaml -e yml | xargs rg "MeleeWeapon" -B2 -A2

# Also search in C# files for component definitions
rg "MeleeWeaponComponent" -A 5 -B 2

Length of output: 178704


Script:

#!/bin/bash
# Search for the MeleeWeaponComponent definition to check default value of CanHeavyAttack
rg "CanHeavyAttack" -A 2 -B 2

Length of output: 872

Content.Shared/Stunnable/SharedStunSystem.cs (1)

113-113: LGTM! Consider documenting the behavior change.

The change to AlwaysDrop makes the knockdown behavior more consistent by ensuring items are always dropped when an entity is knocked down, regardless of their standing state. This aligns well with the knockdown mechanics being introduced for energy balls, shock batons, and taser shots.

Let's verify the impact of this change on other systems:

Consider adding a code comment explaining why items should always be dropped during knockdown, as this represents a significant behavior change that future developers should understand.

✅ Verification successful

Let me generate additional scripts to better understand the impact of this change:


Change to AlwaysDrop behavior is safe and consistent with implementation

The verification shows that the change is well-aligned with the system's implementation:

  • The TryLieDown implementation explicitly handles AlwaysDrop behavior by raising a DropHandItemsEvent even when the entity can't be knocked down
  • Only three other locations use this behavior:
    • ShuttleSystem.FasterThanLight.cs uses DropIfStanding
    • LayDownOnCollideComponent.cs defaults to NoDrop
    • SharedLayingDownSystem.cs internal usage with DropIfStanding

The change to AlwaysDrop in SharedStunSystem.cs is appropriate as stun/knockdown should consistently drop items regardless of standing state, while other systems maintain their specific behaviors.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other systems that might be affected by the knockdown behavior

# Test 1: Look for other systems using TryLieDown
echo "Systems using TryLieDown:"
rg "TryLieDown" -A 3

# Test 2: Look for tests related to knockdown behavior
echo "Tests related to knockdown:"
fd -e cs -e yaml ".*test.*" | rg -i "knock|stun|lying"

Length of output: 2447


Script:

#!/bin/bash
# Check the implementation of TryLieDown to understand the behavior differences
echo "=== TryLieDown Implementation ==="
rg -A 20 "public bool TryLieDown" Content.Shared/Standing/SharedLayingDownSystem.cs

# Check for other systems that might be impacted by the DropHeldItemsBehavior enum
echo "=== DropHeldItemsBehavior Usage ==="
rg "DropHeldItemsBehavior\." --type cs -A 2

# Check for any tests related to dropping items during knockdown
echo "=== Knockdown Item Drop Tests ==="
fd -e cs "test" | xargs rg -l "DropHeldItemsBehavior"

Length of output: 3174

Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1)

157-157: Verify time unit consistency for stun and knockdown durations.

The flash duration is being converted from seconds to milliseconds (multiplied by 1000f), but it's unclear if stunTime and knockdownTime also need this conversion. This could lead to inconsistent duration handling.

Let's verify how stun and knockdown durations are handled in the codebase:

✅ Verification successful

Based on the search results, I can now provide a final response:

Time units are correctly handled for stun and knockdown parameters

Looking at the codebase:

  1. The FlashArea method in FlashSystem accepts stunTime and knockdownTime in seconds (no conversion needed)
  2. Only the duration parameter is explicitly converted from seconds to milliseconds (multiplied by 1000f)
  3. The FlashOnTriggerComponent stores StunTime and KnockdownTime in seconds, matching the expected units
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other uses of FlashArea to understand time unit conventions
ast-grep --pattern 'FlashArea($$$stunTime$$$knockdownTime$$$)'

# Search for stun/knockdown time handling patterns
rg -l 'stunTime|knockdownTime' | xargs rg '(\d+(\.\d+)?f?\s*[*]\s*1000|\d+(\.\d+)?f?\s*[/]\s*1000)'

Length of output: 64


Script:

#!/bin/bash
# Let's try a different approach to find FlashArea method definition and usages
ast-grep --pattern 'FlashArea($_)'

# Also search for the FlashOnTriggerComponent to understand how these times are defined
fd -e cs -x rg -l "FlashOnTriggerComponent" {} | xargs cat

# Search for any flash-related time handling
rg "Flash.*Time|.*Time.*Flash" -A 2 -B 2

Length of output: 29103

Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml (1)

214-214: LGTM: Taser knockdown implementation aligns with PR objectives.

The replacement of stun effect with knockdown effect is consistent with the PR's goal of implementing knockdown mechanics.

Content.Server/_White/Knockdown/KnockdownSystem.cs (1)

46-51: Verify that status effects are applied correctly

The methods _jitter.DoJitter and _stutter.DoStutter are called with the statusEffects parameter. Ensure that these status effects are properly applied and that the target entity reflects the intended jittering and stuttering behavior.

Run the following script to check if the status effects are functioning as expected:

✅ Verification successful

Based on the search results, I can now provide a final response as we have found the relevant implementations:

Status effects are properly implemented and applied

The verification shows that both DoJitter and DoStutter methods are correctly implemented and integrated with the status effects system:

  • SharedJitteringSystem.DoJitter properly handles the status effects parameter and applies the effect through the status effects system
  • StutteringSystem.DoStutter correctly implements the status application using _statusEffectsSystem.TryAddStatusEffect
  • Both effects are used consistently across the codebase (e.g., in ElectrocutionSystem, KnockdownSystem) with proper status effect handling
  • The status effects parameter is properly passed through from KnockdownSystem to both methods
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that jitter and stutter effects are correctly applied when Knockdown is triggered.

# Test: Search for implementations of DoJitter and DoStutter to confirm correct usage.

ast-grep --pattern $'DoJitter($_, $_, $_, status: $_)'
ast-grep --pattern $'DoStutter($_, $_, $_, $_)'

Length of output: 104


Script:

#!/bin/bash
# Let's try a broader search to find the implementation and usage of these methods

# Search for JitterSystem and StutterSystem implementations
rg -l "class .*(?:Jitter|Stutter)System" --type cs

# Search for DoJitter and DoStutter method definitions and usages
rg "(?:DoJitter|DoStutter)" --type cs -A 5

# Search for any status effects related code
rg "statusEffects" --type cs -A 3

Length of output: 33392

Content.Server/Flash/FlashSystem.cs (2)

2-2: Confirm the necessity of the new using directive

The addition of using Content.Server._White.Flash; introduces a dependency on the _White namespace. Ensure that this namespace is intended and that the classes or interfaces from Content.Server._White.Flash are required for the new functionality.


203-203: Verify changes to method signature of FlashArea

The method FlashArea has additional parameters float stunTime = 0f and float knockdownTime = 0f. This changes the method signature and may impact all places where FlashArea is called.

Run the following script to find all usages of FlashArea and ensure they are updated accordingly:

Resources/Locale/ru-RU/_white/alerts/alerts.ftl Outdated Show resolved Hide resolved
Resources/Locale/en-US/_white/alerts/alerts.ftl Outdated Show resolved Hide resolved
Content.Server/_White/Knockdown/KnockComponent.cs Outdated Show resolved Hide resolved
Content.Server/_White/Knockdown/KnockdownSystem.cs Outdated Show resolved Hide resolved
Content.Server/_White/Knockdown/KnockdownSystem.cs Outdated Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Outdated Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 21

🧹 Outside diff range and nitpick comments (26)
Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl (1)

1-2: LGTM! Consider hyphenating "энергобола" for consistency.

The translations are grammatically correct and convey the intended meaning well. However, consider using "энерго-бола" instead of "энергобола" to maintain consistency with common Russian tech-related compound words.

Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1)

1-1: Consider standardizing the namespace structure.

The _White namespace prefix appears to be a custom implementation. Consider following more standard C# namespace conventions by removing the underscore prefix, unless this is an established project convention.

Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1)

1-4: LGTM! Consider adding XML documentation.

The component structure and inheritance look good. However, consider adding XML documentation to describe the component's purpose and behavior.

Add documentation like this:

+/// <summary>
+/// A component that triggers knockdown effects when the entity collides with another entity.
+/// Inherits timing parameters from <see cref="BaseKnockdownOnComponent"/>.
+/// </summary>
[RegisterComponent]
public sealed partial class KnockdownOnCollideComponent : BaseKnockdownOnComponent;
Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (2)

4-8: Add XML documentation to improve code maintainability.

The component's purpose and field usage should be documented for better maintainability.

 [RegisterComponent]
+/// <summary>
+/// Component that suppresses flash-related sound effects within a specified range.
+/// Used by headphones and helmets to provide protection against flashbangs.
+/// </summary>
 public sealed partial class FlashSoundSuppressionComponent : Component
 {
     [DataField]
+    /// <summary>
+    /// Maximum range in meters where the flash sound suppression effect is applied.
+    /// </summary>
     public float MaxRange = 2f;
 }

1-8: Consider increasing the default MaxRange value.

The current default of 2 units seems quite small for sound suppression effects, especially in the context of flashbangs which typically have a larger area of effect. Consider:

  1. Making this value configurable through game settings
  2. Increasing the default range to better match realistic sound suppression distances
  3. Adding different ranges for different types of protective gear (headphones vs helmets)
Content.Server/_White/Knockdown/KnockComponent.cs (2)

3-5: Add XML documentation to describe the component's purpose.

Consider adding documentation to explain the component's role in the knockdown system and its relationship with energy balls, shock batons, and taser shots.

 [RegisterComponent]
+/// <summary>
+/// Component that defines knockdown behavior for entities affected by energy balls,
+/// shock batons, and taser shots.
+/// </summary>
 public sealed partial class KnockComponent : Component

1-11: LGTM! The component follows ECS architecture.

The component correctly separates data from behavior and allows for configuration through data fields. This design will work well with the knockdown system and provides flexibility for different knockdown effects (energy balls, shock batons, taser shots).

Consider adding the following features in future iterations:

  1. Events for knockdown start/end to allow other systems to react
  2. Configuration for different knockdown behaviors (e.g., gradual recovery)
  3. Network synchronization attributes if knockdown state needs to be visible to clients
Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

3-4: Add XML documentation for the public abstract class.

Since this is a base component class that will be inherited, please add XML documentation to describe its purpose and usage.

+/// <summary>
+/// Base component for implementing knockdown mechanics on various triggers.
+/// </summary>
 public abstract partial class BaseKnockdownOnComponent : Component
Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1)

14-20: Remove non-standard comments and add XML documentation.

The "WD EDIT" comments should be removed as they don't follow the codebase's documentation standards. Additionally, the new fields should be documented using XML comments to explain their purpose and expected values.

Apply this diff:

-    // WD EDIT START
+    /// <summary>
+    /// The duration in seconds that an entity will be stunned when affected by the flash.
+    /// </summary>
     [DataField]
     public float StunTime;

+    /// <summary>
+    /// The duration in seconds that an entity will be knocked down when affected by the flash.
+    /// </summary>
     [DataField]
     public float KnockdownTime;
-    // WD EDIT END
Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (2)

6-7: Add XML documentation for better code maintainability.

Consider adding XML documentation to describe the system's purpose and responsibilities.

+/// <summary>
+/// Handles the suppression of flash effects based on equipped items with flash protection capabilities.
+/// </summary>
 public sealed class FlashSoundSuppressionSystem : EntitySystem

8-13: Consider adding debug events for monitoring system behavior.

The initialization looks good, but consider adding debug events to track when flash suppression occurs.

 public override void Initialize()
 {
     base.Initialize();
+    
+    // Raised when flash suppression is applied
+    SubscribeLocalEvent<FlashSoundSuppressionComponent, MapInitEvent>(OnMapInit);
 
     SubscribeLocalEvent<FlashSoundSuppressionComponent, InventoryRelayedEvent<FlashbangedEvent>>(OnFlashbanged);
 }
Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

31-31: Consider documenting the BlurOnCollide effect.

The addition of BlurOnCollide introduces a new visual effect. Consider adding a comment or documentation to explain:

  • The duration of the blur effect
  • Whether it stacks with other blur sources
  • If it's intended to complement the knockdown mechanic
   - type: LayDownOnCollide
     behavior: AlwaysDrop
-  - type: BlurOnCollide
+  # Applies a temporary blur effect when the bolt hits a target
+  - type: BlurOnCollide
🧰 Tools
🪛 yamllint

[error] 31-31: no new line character at the end of file

(new-line-at-end-of-file)

Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (1)

3-4: LGTM! Good architectural change.

Converting this to an abstract base entity with the Base prefix is a good practice. This allows for better entity hierarchy and reusability.

Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (2)

7-10: Consider adding runtime checks for the injected dependency.

While dependency injection is correctly used, it would be safer to verify that _layingDown is properly initialized in the Initialize method.

 public override void Initialize()
 {
     base.Initialize();
+    
+    // Verify dependency injection
+    DebugTools.Assert(_layingDown != null, $"{nameof(SharedLayingDownSystem)} was not properly injected");

1-33: Consider integration with related systems.

Given that this is part of a knockdown feature, consider these architectural points:

  1. Integration with damage system for damage-based knockdowns
  2. Potential interaction with stun/status effect systems
  3. Possible need for configuration options (e.g., knockdown resistance)

This would make the system more flexible and maintainable long-term.

Resources/Prototypes/status_effects.yml (1)

Line range hint 47-56: Add documentation for new status effects.

The new status effects lack documentation about their purpose, duration, and triggering conditions. This information would be valuable for future maintenance.

Add comments explaining:

  • When these effects are applied
  • How long they last
  • What gameplay impact they have

Also, consider the following improvements:

  1. For BlurryVision:
 - type: statusEffect
   id: BlurryVision
   alwaysAllowed: true
+  alert: BlurryVision  # Consider adding an alert for visual feedback
  1. For both effects:
 # WD EDIT START
+# Applied when successfully blocking an attack, prevents spam blocking
 - type: statusEffect
   id: RecentlyBlocked
   alwaysAllowed: true
   alert: RecentlyBlocked

+# Applied when affected by flash effects, reduces visibility
 - type: statusEffect
   id: BlurryVision
   alwaysAllowed: true
 # WD EDIT END
Content.Shared/Alert/AlertType.cs (1)

20-20: Enhance documentation for new alert types

The "WD EDIT" comments don't provide context about the purpose or usage of these new alert types. Consider adding XML documentation to explain:

  • When these alerts are triggered
  • Their duration or conditions for removal
  • Related systems/components that manage these states

Example enhancement:

-        KnockedDown, // WD EDIT
+        /// <summary>
+        /// Indicates the entity is knocked down and cannot move.
+        /// Used by energy balls, shock batons, and taser shots.
+        /// </summary>
+        KnockedDown,

         // Later in the file...
-        RecentlyBlocked, // WD EDIT
+        /// <summary>
+        /// Indicates the entity has recently blocked an attack.
+        /// Used for combat mechanics and cooldown tracking.
+        /// </summary>
+        RecentlyBlocked,

Also applies to: 71-71

Content.Server/Speech/EntitySystems/StutteringSystem.cs (1)

16-16: Consider adding a descriptive comment for the regex pattern.

To improve maintainability, consider documenting the purpose and coverage of the regex pattern.

-        private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz-б-вд-к-лмн-прст]", // WD EDIT
+        // Matches consonants in both English [b-df-hj-np-tv-wxyz] and Russian [б-вд-к-лмн-прст] alphabets
+        private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz-б-вд-к-лмн-прст]",
Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (1)

Line range hint 36-41: Consider aligning StaminaDamageOnCollide with StaminaDamageOnHit.

While the increased stamina damage on hit aligns with PR objectives, there's an inconsistency between hit damage (35) and collide damage (22).

Consider applying this change for consistency:

  - type: StaminaDamageOnCollide
-   damage: 22
+   damage: 35
    sound: /Audio/Weapons/egloves.ogg
Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (1)

31-34: Consider adding component validation and documentation.

The increase to 8 components makes sense for supporting multiple protection types (e.g., flashbang protection). However, consider these improvements:

  1. Add XML documentation explaining why 8 components are allowed
  2. Consider adding component type validation to prevent conflicting or duplicate protection types
+    /// <summary>
+    /// Maximum number of components that can be granted by a single clothing item.
+    /// Current limit of 8 supports multiple protection types (e.g., flash protection, knockdown resistance).
+    /// </summary>
+    private const int MaxComponents = 8;
+
     private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent component, GotEquippedEvent args)
     {
         if (!TryComp<ClothingComponent>(uid, out var clothing)) return;
         if (!clothing.Slots.HasFlag(args.SlotFlags)) return;

-        if (component.Components.Count > 8)
+        if (component.Components.Count > MaxComponents)
         {
-            Logger.Error("Although a component registry supports multiple components, we cannot bookkeep more than 8 component for ClothingGrantComponent at this time.");
+            Logger.Error($"ClothingGrantComponent cannot manage more than {MaxComponents} components at this time.");
             return;
         }
Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (3)

125-126: Add XML documentation for the new property.

While the property name is self-explanatory, adding XML documentation would help maintain consistency with other properties in the class and provide clarity about when this flag should be disabled.

+    /// <summary>
+    /// Whether this weapon can perform heavy attacks. Set to false to disable heavy attack capability.
+    /// </summary>
     [DataField, AutoNetworkedField]
     public bool CanHeavyAttack = true;

Line range hint 183-184: Improve property organization and documentation.

  1. The property should be grouped with other combat-related properties near the top of the class.
  2. XML documentation should be added for clarity.
-    [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
-    public bool CanBeBlocked = true;

+    /// <summary>
+    /// Whether attacks from this weapon can be blocked. Set to false for unblockable weapons.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+    public bool CanBeBlocked = true;

Consider moving this property near other combat-related properties (e.g., near CanHeavyAttack) to maintain better code organization.


Line range hint 1-190: Consider splitting the component to address the "bloated" TODO comment.

The existing TODO comment correctly identifies that this component is handling too many responsibilities. Consider splitting it into more focused components:

  • MeleeWeaponStatsComponent for damage, range, and rate properties
  • MeleeWeaponAnimationComponent for animation-related properties
  • MeleeWeaponSoundComponent for sound-related properties
  • MeleeWeaponContestComponent for contest-related properties

This would improve maintainability and make the code more modular.

Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1)

Line range hint 238-242: Consider extracting the "KnockedDown" string to a constants file.

The knockdown check is a good addition that supports the new knockdown mechanics. However, the "KnockedDown" string could be moved to a constants file to improve maintainability.

Consider creating a constants file for status effect names:

+ public static class StatusEffectConstants
+ {
+     public const string KnockedDown = "KnockedDown";
+ }

Then update the code to use the constant:

- if (TryComp<StatusEffectsComponent>(target, out var status) && status.AllowedEffects.Contains("KnockedDown"))
+ if (TryComp<StatusEffectsComponent>(target, out var status) && status.AllowedEffects.Contains(StatusEffectConstants.KnockedDown))
Content.Shared/Stunnable/SharedStunSystem.cs (1)

Line range hint 1-98: Consider documenting the relationship between stun and knockdown mechanics.

The system handles multiple related mechanics (stun, knockdown, slowdown) with good separation of concerns and event-driven architecture. However, it would be beneficial to add documentation explaining:

  • The relationship between these mechanics
  • When to use each mechanic
  • How they interact with each other
    This would help future developers understand the intended usage and make maintenance easier.
Content.Server/Flash/FlashSystem.cs (1)

2-2: Consider renaming the namespace to follow C# naming conventions.

Using underscores in namespace names, such as Content.Server._White.Flash, is unconventional in C#. It's recommended to use PascalCase without underscores for namespaces to enhance readability and maintain consistency.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 76634ba and 3b3d6da.

⛔ Files ignored due to path filters (2)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/knockdown.png is excluded by !**/*.png
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/icon.png is excluded by !**/*.png
📒 Files selected for processing (39)
  • Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (1 hunks)
  • Content.Server/Explosion/EntitySystems/TriggerSystem.cs (1 hunks)
  • Content.Server/Flash/FlashSystem.cs (3 hunks)
  • Content.Server/Speech/EntitySystems/StutteringSystem.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs (1 hunks)
  • Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (1 hunks)
  • Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1 hunks)
  • Content.Server/_White/Knockdown/KnockdownSystem.cs (1 hunks)
  • Content.Shared/Alert/AlertType.cs (1 hunks)
  • Content.Shared/Flash/Components/FlashOnTriggerComponent.cs (1 hunks)
  • Content.Shared/Flash/SharedFlashSystem.cs (2 hunks)
  • Content.Shared/Inventory/InventorySystem.Relay.cs (2 hunks)
  • Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs (2 hunks)
  • Content.Shared/Stunnable/SharedStunSystem.cs (1 hunks)
  • Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs (0 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs (1 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1 hunks)
  • Resources/Locale/en-US/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/prototypes/entities/objects/weapons/throwable/bola.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/white-shit.ftl (0 hunks)
  • Resources/Prototypes/Alerts/alerts.yml (2 hunks)
  • Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (1 hunks)
  • Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (18 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (2 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml (1 hunks)
  • Resources/Prototypes/Entities/Objects/Weapons/security.yml (3 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1 hunks)
  • Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (1 hunks)
  • Resources/Prototypes/status_effects.yml (1 hunks)
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json (1 hunks)
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json (1 hunks)
💤 Files with no reviewable changes (2)
  • Content.Shared/_White/Collision/Knockdown/KnockdownOnCollideSystem.cs
  • Resources/Locale/ru-RU/_white/white-shit.ftl
✅ Files skipped from review due to trivial changes (4)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideComponent.cs
  • Resources/Locale/en-US/_white/alerts/alerts.ftl
  • Resources/Textures/_White/Interface/Alerts/knockdown.rsi/meta.json
  • Resources/Textures/_White/Objects/Weapons/Throwable/energybola.rsi/meta.json
🧰 Additional context used
🪛 yamllint
Resources/Prototypes/Alerts/alerts.yml

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml

[error] 204-204: trailing spaces

(trailing-spaces)

🔇 Additional comments (42)
Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs (1)

3-4: Verify the minimal component implementation.

The component is correctly registered and inherits from BaseKnockdownOnComponent. However, as it's a minimal implementation without any additional properties or methods, verify if:

  1. All required knockdown functionality is indeed covered by the base component
  2. This component doesn't need any specific override behavior for hit-based knockdowns

Let's verify the base component implementation:

✅ Verification successful

The minimal component implementation is appropriate

The base component BaseKnockdownOnComponent provides all necessary knockdown functionality:

  • Configurable delay before knockdown (Delay)
  • Knockdown duration (KnockdownTime)
  • Additional effects like jitter and stutter with configurable durations

The KnockdownSystem handles all the logic for both hit-based (KnockdownOnHitComponent) and collision-based (KnockdownOnCollideComponent) knockdowns using the same base functionality, with no need for component-specific overrides. The system properly subscribes to the relevant events (TakeStaminaDamageEvent for hits) and applies the knockdown effects uniformly.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for BaseKnockdownOnComponent definition and usages
echo "Searching for base component definition..."
ast-grep --pattern 'class BaseKnockdownOnComponent {
  $$$
}'

echo "Searching for other components inheriting from BaseKnockdownOnComponent..."
ast-grep --pattern 'class $_ : BaseKnockdownOnComponent {
  $$$
}'

Length of output: 386


Script:

#!/bin/bash
# Let's try a different approach to find the base component and its implementations

# First, let's find the file containing BaseKnockdownOnComponent
echo "Finding BaseKnockdownOnComponent file..."
fd "BaseKnockdownOnComponent.cs"

# Search for any files containing BaseKnockdownOnComponent string
echo -e "\nSearching for BaseKnockdownOnComponent references..."
rg "BaseKnockdownOnComponent" -l

# Let's also look at the content of these files
echo -e "\nFile contents containing BaseKnockdownOnComponent:"
rg "BaseKnockdownOnComponent" -A 5 -B 5

# Look for any knockdown-related systems that might use these components
echo -e "\nSearching for knockdown-related systems..."
fd "Knockdown.*System.cs"

Length of output: 3333


Script:

#!/bin/bash
# Let's look at the complete content of the base component and system to understand the functionality

echo "Content of BaseKnockdownOnComponent.cs:"
cat "Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs"

echo -e "\nContent of KnockdownSystem.cs:"
cat "Content.Server/_White/Knockdown/KnockdownSystem.cs"

# Let's also check if there are any other knockdown-related components
echo -e "\nSearching for other knockdown-related components:"
fd -e cs -x grep -l "Knockdown" {}

Length of output: 4555

Content.Server/_White/Knockdown/KnockdownOnCollideComponent.cs (1)

3-4: Verify if empty implementation is intentional.

The component has no additional properties or methods beyond what's inherited from BaseKnockdownOnComponent. Let's verify this is the intended design.

✅ Verification successful

Empty implementation is intentional and correct

The base class BaseKnockdownOnComponent contains all the necessary fields (Delay, KnockdownTime, JitterTime, StutterTime) that are used by the KnockdownSystem. Both KnockdownOnCollideComponent and KnockdownOnHitComponent are marker components that inherit this shared functionality, allowing the system to handle different collision/hit scenarios while reusing the same knockdown logic and configuration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if BaseKnockdownOnComponent contains all necessary fields
# and if other knockdown components have additional implementations

# Look for BaseKnockdownOnComponent definition
echo "Checking base component implementation:"
ast-grep --pattern 'class BaseKnockdownOnComponent {
  $$$
}'

# Look for other knockdown component implementations for comparison
echo -e "\nChecking other knockdown component implementations:"
rg -l "KnockdownOn.*Component" | while read -r file; do
  echo "=== $file ==="
  cat "$file"
done

Length of output: 4664

Resources/Locale/ru-RU/_white/alerts/alerts.ftl (1)

2-3: LGTM: Proper formatting with newline separator

The added newline improves readability by properly separating different alert groups.

Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs (1)

5-16: 🛠️ Refactor suggestion

Verify timing values and add value validation.

The timing configuration looks reasonable, but consider the following improvements:

  1. Add XML documentation for each public field
  2. Add validation to prevent negative TimeSpan values
  3. Consider explaining why JitterTime and StutterTime are identical (15s)

Here's a suggested implementation:

+    /// <summary>
+    /// Delay before the knockdown effect is applied.
+    /// </summary>
     [DataField]
-    public TimeSpan Delay = TimeSpan.FromSeconds(2);
+    public TimeSpan Delay
+    {
+        get => _delay;
+        set => _delay = value >= TimeSpan.Zero ? value : TimeSpan.Zero;
+    }
+    private TimeSpan _delay = TimeSpan.FromSeconds(2);

+    /// <summary>
+    /// Duration of the knockdown effect.
+    /// </summary>
     [DataField]
-    public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);
+    public TimeSpan KnockdownTime
+    {
+        get => _knockdownTime;
+        set => _knockdownTime = value >= TimeSpan.Zero ? value : TimeSpan.Zero;
+    }
+    private TimeSpan _knockdownTime = TimeSpan.FromSeconds(5);

+    /// <summary>
+    /// Duration of the jitter effect applied during knockdown.
+    /// </summary>
     [DataField]
-    public TimeSpan JitterTime = TimeSpan.FromSeconds(15);
+    public TimeSpan JitterTime
+    {
+        get => _jitterTime;
+        set => _jitterTime = value >= TimeSpan.Zero ? value : TimeSpan.Zero;
+    }
+    private TimeSpan _jitterTime = TimeSpan.FromSeconds(15);

+    /// <summary>
+    /// Duration of the stutter effect applied during knockdown.
+    /// </summary>
     [DataField]
-    public TimeSpan StutterTime = TimeSpan.FromSeconds(15);
+    public TimeSpan StutterTime
+    {
+        get => _stutterTime;
+        set => _stutterTime = value >= TimeSpan.Zero ? value : TimeSpan.Zero;
+    }
+    private TimeSpan _stutterTime = TimeSpan.FromSeconds(15);

Let's verify these timing values against other similar mechanics in the codebase:

✅ Verification successful

Based on the search results, I can see extensive usage of TimeSpan values across the codebase. Looking specifically at knockdown-related components and systems, I found:

  1. The timing values in BaseKnockdownOnComponent.cs are consistent with other stun/knockdown effects in the codebase:

    • Most knockdown/stun effects range from 2-5 seconds
    • Status effects like jitter/stutter typically last 10-15 seconds
    • The values used (2s delay, 5s knockdown, 15s jitter/stutter) align with these patterns
  2. The values are also consistent with the KnockComponent.cs which uses the same durations:

    public TimeSpan Delay = TimeSpan.FromSeconds(2);
    public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);
  3. The timing values follow similar patterns to other combat/stun mechanics like:

    • Flash effects (1.5-3s stun)
    • Slippery effects (2-5s paralyze)
    • Impact stuns (2-4s)

The timing values are well-aligned with similar mechanics and appear reasonable for gameplay balance.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for similar timing configurations in other components
# to ensure consistency with existing mechanics

# Look for other TimeSpan configurations
rg -A 2 "TimeSpan\.FromSeconds" --type cs

# Look for other knockdown-related components
ast-grep --pattern 'class $_ {
  $$$
  TimeSpan $_ = TimeSpan.FromSeconds($_);
  $$$
}'

Length of output: 150840

Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs (2)

1-4: LGTM! Clean and focused imports.

The imports are minimal and specific to the required functionality.


15-18: Verify integration with inventory system.

The system modifies flash range based on equipped items. Let's verify that the inventory system properly relays these events.

✅ Verification successful

Integration with inventory system is properly implemented

The verification shows that the flash suppression system is correctly integrated with the inventory system:

  1. The FlashbangedEvent is properly relayed through the inventory system via InventoryRelayedEvent (Content.Shared/Inventory/InventorySystem.Relay.cs)
  2. The FlashSoundSuppressionSystem correctly subscribes to the relayed event using SubscribeLocalEvent<FlashSoundSuppressionComponent, InventoryRelayedEvent<FlashbangedEvent>>
  3. This follows the same pattern as other inventory-relayed systems in the codebase (e.g., armor, stamina, fire protection)
  4. The event chain is complete: FlashSystem → InventorySystem.Relay → FlashSoundSuppressionSystem
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if flash suppression is properly integrated with inventory system
# Expected: Find inventory component definitions that use FlashSoundSuppressionComponent

# Look for entity prototypes that might use this component
rg -l "FlashSoundSuppressionComponent|flash_sound_suppression" --type yaml

# Look for other systems that might interact with flash suppression
ast-grep --pattern 'class $_ : IComponent
{
  $$$
  MaxRange
  $$$
}'

Length of output: 148


Script:

#!/bin/bash
# Let's verify the integration from multiple angles

# 1. Find the FlashSoundSuppressionComponent definition
rg -l "FlashSoundSuppressionComponent"

# 2. Look for inventory relay system implementations
ast-grep --pattern 'class $_ : EntitySystem
{
  $$$
  InventoryRelay
  $$$
}'

# 3. Check for FlashbangedEvent usage
rg -l "FlashbangedEvent"

# 4. Look for inventory component references
ast-grep --pattern 'InventoryRelayedEvent<$_>'

Length of output: 6806

Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/bolts..yml (1)

29-30: Verify the behavior of the new LayDownOnCollide component.

The change from KnockdownOnCollide to LayDownOnCollide with AlwaysDrop behavior suggests a more specific implementation of the knockdown mechanic. Please ensure this change:

  1. Maintains backward compatibility with existing game mechanics
  2. Properly integrates with other weapons that can cause knockdown
Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml (1)

23-23: Verify knockdown interaction with existing ensnaring mechanics.

The addition of LayDownOnCollide alongside the existing Ensnaring component creates a dual effect. Please verify:

  1. The knockdown doesn't interfere with the ensnaring breakout mechanics
  2. The stamina damage from ensnaring (55) is appropriate when combined with knockdown

Let's check for similar dual-effect implementations:

✅ Verification successful

Based on the results, I can generate the final response as we have sufficient information to verify the implementation:

Dual-effect mechanics appear to be implemented correctly

The implementation follows established patterns in the codebase:

  • LayDownOnCollide is used in both bolas and bolts, showing it's a standard component for knockdown effects
  • Bola's configuration keeps the ensnaring effects moderate (0.7 speed multiplier, 55 stamina damage) while adding knockdown, which is balanced
  • The components operate independently - LayDownOnCollide handles knockdown while Ensnaring manages movement/breakout mechanics
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other entities that combine LayDownOnCollide with Ensnaring
# to verify this is a consistent pattern

rg -l "type: LayDownOnCollide" | xargs rg "type: Ensnaring" -l

# Also check for any specific configuration patterns
rg -A 5 -B 5 "type: LayDownOnCollide"

Length of output: 1703

Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml (1)

10-10: LGTM! Verify entity definition exists.

The addition of EnergyBola to the security vending machine inventory is well-balanced with other security equipment quantities. The placement and quantity (5) align well with similar security tools.

Let's verify the entity definition exists:

✅ Verification successful

Entity definition verified and properly configured

The EnergyBola entity is correctly defined in Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml with all essential components including proper name, description, item size, sprite configuration, and sound effects. The addition to the security vending machine inventory is valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the EnergyBola entity is properly defined
# Expected: Should find the entity definition in the entities directory

# Search for EnergyBola entity definition
rg -l "id: EnergyBola" "Resources/Prototypes"

Length of output: 117


Script:

#!/bin/bash
# Let's verify the content of the entity definition to ensure it's properly defined
rg -A 10 "id: EnergyBola" "Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml"

Length of output: 398

Content.Shared/Flash/SharedFlashSystem.cs (2)

22-32: The event implementation aligns well with the PR objectives.

The FlashbangedEvent correctly implements IInventoryRelayEvent to handle flashbang protection for both headphones (EARS) and helmets (HEAD), which aligns perfectly with the PR objectives.


26-26: LGTM! Well-structured slot targeting.

The TargetSlots property effectively combines both EARS and HEAD slots using a bitwise OR operation, making it clear which inventory slots are relevant for flashbang protection.

Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1)

1-5: LGTM! Clean and well-organized imports.

The imports are minimal and necessary for the system's functionality.

Resources/Prototypes/status_effects.yml (1)

10-10: LGTM! Verify alert type configuration.

The change from "Stun" to "KnockedDown" alert type properly separates knockdown state from stun effects, aligning with the PR's objective.

Let's verify the alert type is properly configured:

✅ Verification successful

KnockedDown alert type is properly configured

The alert type "KnockedDown" is properly defined in both the status effects and alerts prototypes, and is correctly referenced throughout the codebase:

  • Defined in Resources/Prototypes/status_effects.yml
  • Alert type defined in Resources/Prototypes/Alerts/alerts.yml
  • Properly integrated in the codebase's stun/knockdown systems
  • Used consistently across various systems (sleep, carrying, combat, etc.)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify KnockedDown alert type exists and is properly configured
# Expected: Find corresponding alert definition and enum value

# Check for alert definition
rg -l "type:\s*alert.*id:\s*KnockedDown" "Resources/Prototypes/Alerts"

# Check for enum value
rg "KnockedDown" "Content/Shared/Alert"

Length of output: 169


Script:

#!/bin/bash
# Let's try different paths and patterns to locate alert definitions

# Find all YAML files that might contain alert definitions
fd -e yml -e yaml

# Search for KnockedDown in all YAML files
rg "KnockedDown" -g "*.yml" -g "*.yaml"

# Search for alert type enum in shared code
fd -e cs | xargs rg "AlertType|KnockedDown"

Length of output: 200015

Resources/Prototypes/_White/Entities/Objects/Weapons/Throwable/bola.yml (2)

1-53: Implementation aligns well with PR objectives

The entity definitions successfully implement the new knockdown mechanics and energy-based weapon features described in the PR objectives. The structure is clean and follows the game's established patterns.


29-32: Consider increasing the blunt damage value

5 blunt damage seems low for a weighted throwing weapon. Consider balancing this against other throwable weapons in the game.

Let's check damage values of similar weapons:

✅ Verification successful

Let me try a different approach to find weapon damage values in the codebase. This should help us compare the bola's damage with other weapons.


Let me try to find damage values specifically for throwable weapons to compare with the bola's damage.


Based on the search results showing DamageOnLand configurations across various throwable items, I can now generate a final response:

The bola's blunt damage (5) is appropriately balanced

The bola's 5 blunt damage is consistent with other throwable weapons and items in the game:

  • Most throwable items deal 5 blunt damage (bottles, plates, bowls, etc.)
  • Specialized weapons like clusterbang deal 10 damage
  • The bola also has the additional KnockdownOnCollide effect, making it tactically valuable beyond raw damage
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for DamageOnLand configurations in throwable weapons
rg -U "type: DamageOnLand\s+damage:" --type yaml

Length of output: 330


Script:

#!/bin/bash
# Search for damage configurations in yaml files within weapon directories
rg -U "damage:\n\s+types:" --type yaml Resources/Prototypes/

Length of output: 106827


Script:

#!/bin/bash
# Let's search specifically for throwable weapons and their damage values
rg -U "type: DamageOnLand\s+damage:\n\s+types:" -A 2 --type yaml Resources/Prototypes/

Length of output: 9541

Content.Shared/Alert/AlertType.cs (1)

Line range hint 6-8: Verify enum capacity for future additions

The enum is byte-typed for compact network encoding. With these new additions, let's verify we're not approaching the byte limit (255 values).

✅ Verification successful

No concerns with byte capacity - plenty of room for future additions

The enum currently has 64 values, which is well within the byte limit of 255. With less than 25% capacity used, there's ample room for future expansion while maintaining the compact network encoding.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Count total enum values to ensure we're not approaching byte limit
echo "Total enum values:"
rg -c "^        [A-Za-z]" "Content.Shared/Alert/AlertType.cs"

Length of output: 111

Content.Server/Speech/EntitySystems/StutteringSystem.cs (1)

16-16: LGTM! The regex pattern correctly handles both English and Cyrillic consonants.

The pattern is well-formed and properly includes both English consonants ([b-df-hj-np-tv-wxyz]) and Russian consonants ([б-вд-к-лмн-прст]). The compilation flag ensures optimal performance.

Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml (1)
#!/bin/bash
# Let's try a broader search for power-related configurations in weapons
rg -A 5 "type: PowerCellSlot" "Resources/Prototypes/Entities/Objects/Weapons"

# Also search for any energy-related configurations
rg -i "energy|power" "Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml"
Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml (2)

12-12: 🛠️ Refactor suggestion

Consider adding configuration parameters to FlashSoundSuppression component.

While adding flash protection aligns with the PR objectives, the component might benefit from explicit configuration parameters (e.g., protection range or effectiveness).

- - type: FlashSoundSuppression # WD EDIT
+ - type: FlashSoundSuppression
+   maxRange: 5.0  # Specify the effective range of flash protection
+   effectiveness: 0.75  # Specify the protection effectiveness (0.0 to 1.0)

Likely invalid or redundant comment.


15-15: Verify department name changes across the codebase.

The department name changes from "Cargo" to "Logistics" and "Science" to "Mystagogue" should be consistently applied throughout the codebase to maintain naming conventions.

Also applies to: 89-89

✅ Verification successful

Based on the search results, I can generate the final response as we have comprehensive evidence about the department name changes across the codebase.

Department name changes have been consistently applied across the codebase

The changes from "Cargo" to "Logistics" and "Science" to "Mystagogue" are thoroughly and consistently implemented throughout the codebase, with appropriate comments marking the changes (DeltaV). The changes cover all relevant aspects including:

  • Department names and references
  • Job titles and descriptions
  • Equipment and clothing items
  • Room and area names
  • Access levels and security
  • Interface elements and strings
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to old department names
echo "Checking for old department references..."
rg -i "cargo department|science department" --type yaml

echo "Verifying new department naming consistency..."
rg -i "logistics department|mystagogue" --type yaml

Length of output: 22874

Resources/Prototypes/Entities/Objects/Weapons/security.yml (2)

13-13: LGTM! Changes align with PR objectives and maintain game balance.

The modifications to the stun baton:

  • Increased energy cost (100 vs 50) balances the higher stamina damage
  • Slower attack rate prevents abuse
  • Added knockdown capability as intended

Let's verify these changes don't conflict with other weapon configurations:

Also applies to: 37-38, 41-41, 88-88

✅ Verification successful

Stun baton changes are balanced within the weapon ecosystem

The verification shows the changes are well-balanced within the broader weapon ecosystem:

  • The new 0.4 attack rate matches other stun weapons (stunprod) and is slower than most melee weapons (0.75-2.0)
  • StaminaDamageOnHit is rare, only present on stun weapons and cane
  • KnockdownOnHit is exclusive to stun weapons, maintaining their unique role
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other weapons with similar components to ensure balanced gameplay
rg "StaminaDamageOnHit|attackRate|KnockdownOnHit" Resources/Prototypes/Entities/Objects/Weapons/

Length of output: 4227


Line range hint 144-145: Verify implementation of headgear flash protection.

While setting canBeBlocked: false and damage: 0 clarifies the flash's behavior, the PR mentions protection from flashbangs for full-size headphones and helmets. This protection mechanism isn't visible in the current changes.

Let's check for the headgear protection implementation:

✅ Verification successful

Let me try a different search strategy to locate flash protection implementation.


Based on the search results, I can see that flash protection is implemented through components like FlashImmunity and FlashSoundSuppression in various headgear. Let me search specifically for these components in hardsuit helmets and headphones to verify the implementation.


The search results show that flash protection is properly implemented in the codebase:

  1. Hardsuit helmets have both FlashImmunity and FlashSoundSuppression components
  2. Over-ear headsets have FlashSoundSuppression component
  3. Welding helmets have FlashImmunity component

Let me verify if there are any other relevant head gear with flash protection by searching for eye protection components.


Flash protection is properly implemented for both helmets and headphones

The codebase shows comprehensive flash protection implementation:

  • Hardsuit helmets have both FlashImmunity and FlashSoundSuppression components
  • Over-ear headsets have FlashSoundSuppression component
  • Welding helmets have FlashImmunity and EyeProtection components
  • Various glasses/goggles have FlashImmunity and EyeProtection with configurable protection time

The PR's changes to set canBeBlocked: false on the flash weapon are consistent with this implementation, as the protection is handled by the protective gear components rather than weapon blocking.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for flash protection in headgear configurations
echo "Searching for flash protection in headgear..."
rg -A 5 "FlashProtection|flash" Resources/Prototypes/Entities/Objects/Clothing/Head/

# Search for flash-related components that might handle protection
echo "Searching for flash protection components..."
ast-grep --pattern 'class $_ {
  $$$
  Flash$_
  $$$
}'

Length of output: 437


Script:

#!/bin/bash
# Search for flash protection in all resource files
echo "Searching for flash protection in resource files..."
rg -i "flash.*protection|protection.*flash" Resources/

# Search for flash-related components in all yml files
echo "Searching flash-related components in yml files..."
rg -i "flash" Resources/ --type yaml -A 5

# Find all head gear related files
echo "Finding head gear related files..."
fd "head|helmet|headphones" Resources/Prototypes

Length of output: 207875


Script:

#!/bin/bash
# Search for flash protection in hardsuit helmets and headphones
echo "Searching for flash protection in hardsuit helmets and headphones..."
rg -A 3 "type: (FlashImmunity|FlashSoundSuppression)" Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml Resources/Prototypes/Entities/Clothing/Ears/headsets.yml Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml

# Search for flash protection in other head gear
echo "Searching for flash protection in other head gear..."
rg -A 3 "type: (FlashImmunity|FlashSoundSuppression)" Resources/Prototypes/Entities/Clothing/Head/

Length of output: 17128


Script:

#!/bin/bash
# Search for eye protection in glasses and other head gear
echo "Searching for eye protection components..."
rg -A 3 "type: EyeProtection" Resources/Prototypes/Entities/Clothing/Eyes/ Resources/Prototypes/Entities/Clothing/Head/

# Search for flash protection in glasses
echo "Searching for flash immunity in glasses..."
rg -A 3 "type: FlashImmunity" Resources/Prototypes/Entities/Clothing/Eyes/

Length of output: 8644

Content.Shared/Inventory/InventorySystem.Relay.cs (2)

7-7: LGTM: Required using statement for flash functionality.

The addition of the Flash namespace import is necessary for the new FlashbangedEvent handling.


33-33: Verify flash protection implementation.

The addition of FlashbangedEvent relay aligns with the PR objective of implementing flash protection for headgear. The implementation follows the established pattern of event relaying.

However, let's verify that the flash protection is properly implemented in the corresponding equipment components.

✅ Verification successful

Let me gather more specific information about the flash protection implementation.


Let me gather one final piece of information about the flash sound suppression component.


Flash protection implementation verified and properly integrated

The implementation is correctly structured with:

  • FlashbangedEvent properly relayed through the inventory system targeting HEAD and EARS slots
  • FlashSoundSuppressionComponent handling the protection logic by reducing the flash range to a maximum of 2 units
  • Event relay system following the established pattern for equipment effects

The implementation aligns with the PR objective and is properly integrated into the existing systems.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify flash protection implementation in equipment components

# Check for flash protection-related components and properties
echo "Searching for flash protection implementations..."
rg -l "flash.*protection" --type cs

# Check for FlashbangedEvent handlers
echo "Searching for FlashbangedEvent handlers..."
ast-grep --pattern 'FlashbangedEvent'

# Check for specific headgear configurations
echo "Searching for headgear configurations..."
rg -l "full.*size.*headphones|helmet" --type cs

Length of output: 833


Script:

#!/bin/bash
# Search for FlashbangedEvent related code with context
echo "Searching for FlashbangedEvent related code..."
rg -A 5 "FlashbangedEvent" --type cs

# Search for flash protection in clothing components
echo "Searching for flash protection in clothing components..."
rg -A 10 "class.*ClothingComponent" --type cs

# Search for flash-related systems
echo "Searching for flash-related systems..."
rg -A 5 "Flash(ed|bang|Protection)" --type cs

# Look for equipment slot definitions related to head protection
echo "Searching for head slot definitions..."
rg -A 3 "SlotFlags\..*Head" --type cs

Length of output: 18745


Script:

#!/bin/bash
# Check the FlashSoundSuppressionComponent implementation
echo "Searching for FlashSoundSuppressionComponent..."
rg -A 10 "class.*FlashSoundSuppressionComponent" --type cs

# Check for any flash protection prototypes
echo "Searching for flash protection in prototypes..."
fd -e yml -e yaml | xargs rg "flash.*protection|sound.*suppression"

Length of output: 773

Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs (1)

124-124: LGTM: ViewVariables attribute addition is appropriate.

The addition of ViewVariables with ReadWrite access will help with runtime debugging and testing of the disarm animation behavior.

Content.Client/Weapons/Melee/MeleeWeaponSystem.cs (2)

Line range hint 138-144: LGTM: Proper handling of ranged weapons during alt-attacks.

The addition of ranged weapon checks prevents unintended light attacks when using weapons that are primarily meant for shooting, improving the combat experience.


119-119: LGTM: Defensive check for heavy attack capability.

The addition of weapon.CanHeavyAttack check ensures that heavy attacks are only executed for weapons that support this feature, preventing unintended behavior.

Let's verify that weapons are properly configured with this property:

Content.Shared/Stunnable/SharedStunSystem.cs (2)

Line range hint 76-98: LGTM! Good improvement to stun state management.

The removal of stun effects when an entity enters critical or dead states is a logical improvement that prevents inconsistent state management. This change aligns well with the PR's objective of refining knockdown mechanics.


113-113: Verify edge cases with the new AlwaysDrop behavior.

The change to AlwaysDrop makes the knockdown behavior more consistent, but we should verify it doesn't cause issues in specific scenarios.

Let's check for potential edge cases:

✅ Verification successful

Change to AlwaysDrop behavior is safe and properly implemented

The implementation shows that AlwaysDrop behavior is handled correctly in TryLieDown:

  • It drops items even when the lying down action fails
  • The change is consistent with other knockdown mechanics in the codebase
  • No direct container/inventory system conflicts were found

Key usages found:

  • Shuttle system: Uses DropIfStanding
  • Collision system: Configurable behavior
  • Stun system (this change): Now uses AlwaysDrop

The change makes knockdown behavior more predictable by ensuring items are always dropped during stun, which is a reasonable gameplay mechanic.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for interactions with TryLieDown and container/inventory systems
# that might be affected by the AlwaysDrop change

echo "Checking for TryLieDown usage patterns:"
rg -A 3 "TryLieDown"

echo "\nChecking for container-related knockdown interactions:"
ast-grep --pattern 'class $_ {
  $$$
  TryLieDown($$$) {
    $$$
    container$$$
    $$$
  }
  $$$
}'

echo "\nChecking for inventory-related knockdown interactions:"
ast-grep --pattern 'class $_ {
  $$$
  TryLieDown($$$) {
    $$$
    inventory$$$
    $$$
  }
  $$$
}'

Length of output: 2809


Script:

#!/bin/bash
# Let's examine the implementation of TryLieDown to understand the behavior differences
# and check for any potential issues with inventory/container handling

echo "Checking TryLieDown implementation:"
rg -A 30 "public bool TryLieDown" "Content.Shared/Standing/SharedLayingDownSystem.cs"

echo "\nChecking for other usages of DropHeldItemsBehavior enum:"
rg -A 2 "DropHeldItemsBehavior\." 

echo "\nChecking for related inventory/container systems that might interact:"
rg "DropHeldItems|HandleDrop" "Content.Shared/Standing/SharedLayingDownSystem.cs"

Length of output: 3980

Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml (1)

70-71: LGTM! Please verify flashbang protection mechanics.

The addition of stunTime and knockdownTime properties aligns with the PR objectives for implementing knockdown mechanics. The values (2s stun, 10s knockdown) seem reasonable for gameplay balance.

Let's verify if the flashbang protection mechanics for full-size headphones and helmets are properly implemented:

✅ Verification successful

Let me try a different search strategy to verify the flashbang protection mechanics.


Based on the search results, I can now verify the flashbang protection mechanics. The codebase shows that:

  1. Hardsuit helmets have both FlashImmunity and FlashSoundSuppression components
  2. Several types of eyewear (welding masks, security glasses, etc.) provide flash protection through EyeProtection component
  3. The GrenadeFlashBang entity uses FlashOnTrigger component with the configured stun/knockdown times

The changes to add stunTime: 2 and knockdownTime: 10 to the flashbang are valid, and the protection mechanics are properly implemented through the existing components in helmets and eyewear.

Flashbang protection is properly implemented - the changes are safe to approve

  • Hardsuit helmets provide complete flash immunity
  • Various eyewear provides timed protection against flashes
  • The stun/knockdown time values are reasonable and work with the existing protection system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for flashbang protection implementation in headphones and helmets

# Search for flashbang protection related configurations
echo "Searching for flashbang protection in equipment..."
rg -i "flash.*protect|protect.*flash" Resources/Prototypes/Entities/Objects/Equipment/

# Search for components that might handle flash protection
echo "Searching for flash protection components..."
ast-grep --pattern 'component.*Flash.*Protect'

Length of output: 436


Script:

#!/bin/bash
# Search for any files related to headphones and helmets
echo "Searching for headphone and helmet prototypes..."
fd -e yml -e yaml . Resources/Prototypes | xargs rg -l -i "headphone|helmet"

# Search for flash-related components and systems
echo "Searching for flash-related code..."
rg -i "flash" --type yaml -A 5 Resources/Prototypes

# Search for protection-related components
echo "Searching for protection components..."
rg -i "protect" --type yaml -A 5 Resources/Prototypes

Length of output: 364229

Resources/Prototypes/Alerts/alerts.yml (3)

20-20: LGTM! Alert order placement is logical.

The placement of new alerts in the order list is well-thought-out:

  • KnockedDown is grouped with similar status effects like Stun
  • RecentlyBlocked is placed near other combat-related alerts

632-636: Verify shield sprite asset exists.

The alert definition looks good, but let's ensure the sprite asset exists and is appropriate for this alert.

✅ Verification successful

Let me check the meta.json content to verify if the specific icon state exists.


Sprite asset verification successful

The shield sprite asset exists at the specified path and the "buckler-icon" state is properly defined in the RSI metadata, making it suitable for use in the RecentlyBlocked alert.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the shield sprite
fd -t f "shields.rsi" Resources/Textures/Objects/Weapons/Melee/

# If found, check for the specific icon state
if [ $? -eq 0 ]; then
    rg -l "buckler-icon" Resources/Textures/Objects/Weapons/Melee/shields.rsi
fi

Length of output: 218


Script:

#!/bin/bash
# Check the content of meta.json to verify the icon state
cat Resources/Textures/Objects/Weapons/Melee/shields.rsi/meta.json | jq '.states[] | select(.name == "buckler-icon")'

Length of output: 148


624-630: ⚠️ Potential issue

Fix formatting issues and verify sprite asset.

  1. Remove trailing spaces after icons: on line 626
  2. Fix indentation of the sprite definition to match other alert definitions (4 spaces)
  3. Ensure the sprite asset exists

Apply this diff to fix the formatting:

  id: KnockedDown
  icons: 
-  - sprite: /Textures/_White/Interface/Alerts/knockdown.rsi
+  - sprite: /Textures/_White/Interface/Alerts/knockdown.rsi
    state: knockdown
✅ Verification successful

Let me verify the sprite path with a different approach.


Fix minor formatting issues in alert definition

The sprite asset exists at the correct path. Only formatting issues need to be addressed:

  • Remove trailing spaces after icons:
  • Fix indentation of the sprite definition

Apply this diff:

  id: KnockedDown
  icons: 
-  - sprite: /Textures/_White/Interface/Alerts/knockdown.rsi
+  - sprite: /Textures/_White/Interface/Alerts/knockdown.rsi
    state: knockdown
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the knockdown sprite
fd -t f "knockdown.rsi" Resources/Textures/_White/Interface/Alerts/

Length of output: 218


Script:

#!/bin/bash
# Check if the knockdown.rsi exists in the entire Resources directory
fd -t f "knockdown.rsi" Resources/

# Also check for any files with "knockdown" in their name under Alerts directory
fd "knockdown" Resources/Textures/_White/Interface/Alerts/

# Search for any knockdown-related RSI references in alert definitions
rg -l "knockdown.rsi" Resources/Prototypes/Alerts/

Length of output: 312

🧰 Tools
🪛 yamllint

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml (1)

214-214: LGTM: Taser stun effect replaced with knockdown.

The change aligns with the PR objectives to remove stun effects from tasers in favor of knockdown mechanics.

Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml (2)

202-204: LGTM: Consistent implementation of flash protection.

The addition of FlashImmunity and FlashSoundSuppression components across various hardsuit helmets is consistent with the PR objectives. The implementation follows a uniform pattern across all security-related, military, and special operations hardsuits.

Also applies to: 232-233, 259-260, 279-280, 407-409, 435-437, 467-469, 495-497, 622-624, 640-642, 665-667, 683-685, 708-710, 726-728, 768-770

🧰 Tools
🪛 yamllint

[error] 204-204: trailing spaces

(trailing-spaces)


799-804: Enhanced capabilities for Deathsquad hardsuit.

The Deathsquad hardsuit helmet receives additional high-tier capabilities:

  • Thermal vision
  • Night vision
  • Enhanced flash protection with maxRange: 0

This is appropriate given its role as elite special operations equipment.

Content.Server/_White/Knockdown/KnockdownSystem.cs (4)

14-17: Dependency injections are correctly declared

All required dependencies are appropriately injected and initialized.


19-24: Event subscriptions are properly set up

The Initialize method correctly subscribes to the necessary events for knockdown mechanics.


26-39: Event handlers delegate actions effectively

The OnMeleeHit, OnProjectileHit, and OnThrowDoHit methods correctly invoke the Knockdown method on the target entity.


63-76: Efficient processing of delayed knockdowns

The Update method efficiently iterates over entities with KnockComponent and applies knockdown effects when the delay expires.

Content.Server/Flash/FlashSystem.cs (2)

225-227: Approved: Correct implementation of distance-based stun and knockdown effects.

The calculation of the distance between the flash source and the target entity is accurate. The application of FlashStun ensures that stun and knockdown effects are proportionally applied based on the entity's distance from the flash source, enhancing gameplay mechanics as intended.


203-203: Verify that the addition of new parameters to FlashArea does not impact existing calls.

The method FlashArea now includes additional optional parameters stunTime and knockdownTime. Ensure that all existing calls to FlashArea either explicitly handle these new parameters or correctly rely on the default values to prevent unintended behavior.

Run the following script to locate all usages of FlashArea in the codebase:

✅ Verification successful

Based on the search results, I can generate the final response as we have found all the usages of FlashArea in the codebase.

The addition of optional parameters stunTime and knockdownTime is safe and does not impact existing calls.

The codebase shows only two calls to FlashArea:

  • In TriggerSystem.cs, the call explicitly provides values for both new parameters
  • In FlashSystem.cs, the call uses the original parameter set, which safely relies on the default values (0f) for the new optional parameters
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of the FlashArea method.
# Expected result: Confirm that each call to FlashArea is compatible with the new parameters.

rg 'FlashArea\(' -A 2

Length of output: 1117

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (1)
Resources/Prototypes/Alerts/alerts.yml (1)

632-639: Fix formatting and remove edit block comments.

  1. Fix indentation:
 - type: alert
   id: RecentlyBlocked
   icons:
-  - sprite: /Textures/Objects/Weapons/Melee/shields.rsi
-    state: buckler-icon
+    - sprite: /Textures/Objects/Weapons/Melee/shields.rsi
+      state: buckler-icon
   name: alerts-blocked-name
   description: alerts-blocked-desc
  1. Remove the unnecessary edit block comments (# WD EDIT START and # WD EDIT END).
🧰 Tools
🪛 yamllint

[warning] 635-635: wrong indentation: expected 4 but found 2

(indentation)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3b3d6da and c5c4f0f.

📒 Files selected for processing (5)
  • Content.Server/Flash/FlashSystem.cs (3 hunks)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs (1 hunks)
  • Resources/Locale/en-US/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Locale/ru-RU/_white/alerts/alerts.ftl (1 hunks)
  • Resources/Prototypes/Alerts/alerts.yml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • Content.Shared/_White/Collision/LayDown/LayDownOnCollideSystem.cs
  • Resources/Locale/en-US/_white/alerts/alerts.ftl
  • Resources/Locale/ru-RU/_white/alerts/alerts.ftl
🧰 Additional context used
🪛 yamllint
Resources/Prototypes/Alerts/alerts.yml

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)


[warning] 635-635: wrong indentation: expected 4 but found 2

(indentation)

🔇 Additional comments (3)
Content.Server/Flash/FlashSystem.cs (1)

193-200: 🛠️ Refactor suggestion

Optimize effect application by combining the interpolation calculations.

The current implementation performs separate interpolations and effect applications for knockdown and stun. This can be optimized by combining the calculations.

Consider this optimization:

-var knockdownTime = float.Lerp(knockdownDuration, 0f, distance / range);
-if (knockdownTime > 0f)
-    _stun.TryKnockdown(target, TimeSpan.FromSeconds(knockdownTime), true);
-
-var stunTime = float.Lerp(stunDuration, 0f, distance / range);
-if (stunTime > 0f)
-    _stun.TryStun(target, TimeSpan.FromSeconds(stunTime), true);
+var distanceRatio = distance / range;
+var knockdownTime = float.Lerp(knockdownDuration, 0f, distanceRatio);
+var stunTime = float.Lerp(stunDuration, 0f, distanceRatio);
+
+if (knockdownTime > 0f)
+    _stun.TryKnockdown(target, TimeSpan.FromSeconds(knockdownTime), true);
+if (stunTime > 0f)
+    _stun.TryStun(target, TimeSpan.FromSeconds(stunTime), true);

Likely invalid or redundant comment.

Resources/Prototypes/Alerts/alerts.yml (2)

20-20: LGTM! Alert order changes are well-structured.

The placement of new alerts in the order list is logical:

  • KnockedDown is appropriately grouped with similar status effects like Stun
  • RecentlyBlocked is properly placed with other combat-related alerts

Also applies to: 30-30


624-630: ⚠️ Potential issue

Fix formatting and sprite path issues.

  1. The sprite path should follow the established pattern:
-  icons: 
-  - sprite: /Textures/_White/Interface/Alerts/knockdown.rsi
+  icons:
+    - sprite: /Textures/Interface/Alerts/knockdown.rsi
  1. Consider adding an onClick handler if players should be able to interact with this status effect (e.g., attempt to stand up).
🧰 Tools
🪛 yamllint

[error] 626-626: trailing spaces

(trailing-spaces)


[warning] 627-627: wrong indentation: expected 4 but found 2

(indentation)

Content.Server/Flash/FlashSystem.cs Show resolved Hide resolved
Content.Server/Flash/FlashSystem.cs Outdated Show resolved Hide resolved
@DVOniksWyvern
Copy link
Collaborator

@Remuchi

Сделаешь ревью, или никак?

Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants