* Move Exclamation entity
* Add Whistle Component and Whistle System
* Add BaseWhistle prototype
* Add sound to BaseWhistle
* Add SecurityWhistle prototype
* Add Sprite and Icon to SecurityWhistle
* Add whistleExclamation prototype
* Fix SecurityWhistle prototype
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
* Add whistles to sec vendingMachine
* Revert "Add sound to BaseWhistle"
This reverts commit
0c2eeab1286fb778ed7a845e59c642f667582a4a.
* Add sounds for BaseWhistle
* Make atributions compact
* Remove unnecessary spaces
* Make WhistleSystem class sealed
* Remove possibility to exclamate one person from WhistleComponent
* Remove delay from WhistleSystem
Increase delay
* Remove unnecessary HashSet
* Try replace Resolve
* Refactor sound emmiting
* Rework spawn of exclamation
* Move WhistleComponent from Server to Shared
* Edit WhistleComponent because of moving
* Move WhistleSystem from Server to Client
* Edit WhistleSystem because of moving
* Add new event
* Add server part of WhistleSystem
* Modify system for prediction
* Add documentation to WhistleComponent
* Revert "Modify system for prediction"
This reverts commit
89abb290571ff47deb5491b0f720f6bde079110b.
* Revert "Add server part of WhistleSystem"
This reverts commit
ca52ca081f30fb164f401c1818d08531f02af284.
* Revert "Add new event"
This reverts commit
5ca9694757c94c03ca72d5b2f56f5f23503a3263.
* Move system from client to shared
* Modify whistle system because of moving
* Separate checks and action
* Organize file folders according to conventions
* Make component Networked
* Change trigger component for WhistleSystem
* Put indents betwen methods
* Rework WhistleExclamation prototype
* Change variable name
* Add serializer to WhistleComponent
* Rename one variable
* add predict possibility to Shared
* add Client part of prediction
* Add Server part of prediction
* Increase whistle distance
* Prevent spawn for invisible entities
* WhistleComponent now use file-scoped namespace
* Delete unnecessary part from MakeLoudWhistle
* Add Resolve check
* Delete Server and Client part for prediction
* Make system prediction properly
* Change prediction behaviour
* Fix unexpected error occured
* Avoid using obsolete methods
* Add comments
* Update DataField to make it shorter
* Update size for new size system
* Prevent ping for invisible entities for real now
* Avoid triggering unnecessary debug asserts
---------
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
--- /dev/null
+using Robust.Shared.GameStates;
+using Content.Shared.Humanoid;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Whistle;
+
+/// <summary>
+/// Spawn attached entity for entities in range with <see cref="HumanoidAppearanceComponent"/>.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class WhistleComponent : Component
+{
+ /// <summary>
+ /// Entity prototype to spawn
+ /// </summary>
+ [DataField]
+ public EntProtoId Effect = "WhistleExclamation";
+
+ /// <summary>
+ /// Range value.
+ /// </summary>
+ [DataField]
+ public float Distance = 0;
+}
--- /dev/null
+using Content.Shared.Coordinates;
+using Content.Shared.Humanoid;
+using Content.Shared.Interaction.Events;
+using Content.Shared.Stealth.Components;
+using JetBrains.Annotations;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Whistle;
+
+public sealed class WhistleSystem : EntitySystem
+{
+ [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<WhistleComponent, UseInHandEvent>(OnUseInHand);
+ }
+
+ private void ExclamateTarget(EntityUid target, WhistleComponent component)
+ {
+ SpawnAttachedTo(component.Effect, target.ToCoordinates());
+ }
+
+ public void OnUseInHand(EntityUid uid, WhistleComponent component, UseInHandEvent args)
+ {
+ if (!_timing.IsFirstTimePredicted)
+ return;
+
+ TryMakeLoudWhistle(uid, args.User, component);
+ args.Handled = true;
+ }
+
+ public bool TryMakeLoudWhistle(EntityUid uid, EntityUid owner, WhistleComponent? component = null)
+ {
+ if (!Resolve(uid, ref component, false) || component.Distance <= 0)
+ return false;
+
+ MakeLoudWhistle(uid, owner, component);
+ return true;
+ }
+
+ private void MakeLoudWhistle(EntityUid uid, EntityUid owner, WhistleComponent component)
+ {
+ StealthComponent? stealth = null;
+
+ foreach (var iterator in
+ _entityLookup.GetEntitiesInRange<HumanoidAppearanceComponent>(_transform.GetMapCoordinates(uid), component.Distance))
+ {
+ //Avoid pinging invisible entities
+ if (TryComp(iterator, out stealth) && stealth.Enabled)
+ continue;
+
+ //We don't want to ping user of whistle
+ if (iterator.Owner == owner)
+ continue;
+
+ ExclamateTarget(iterator, component);
+ }
+ }
+}
--- /dev/null
+- files:
+ - "whistle_1.ogg"
+ - "whistle_2.ogg"
+ - "whistle_3.ogg"
+ - "whistle_4.ogg"
+ - "whistle_5.ogg"
+ - "whistle_6.ogg"
+ - "whistle_7.ogg"
+ license: "CC0-1.0"
+ copyright: "User strongbot on freesound.org. Modified by Fahasor on github"
+ source: "https://freesound.org/people/strongbot/sounds/568995/"
\ No newline at end of file
- type: vendingMachineInventory
id: SecTechInventory
startingInventory:
+ SecurityWhistle: 5
Handcuffs: 8
GrenadeFlashBang: 4
TearGasGrenade: 4
--- /dev/null
+- type: entity
+ id: Exclamation
+ name: exclamation
+ noSpawn: true
+ save: false
+ components:
+ - type: Transform
+ noRot: true
+ - type: Sprite
+ sprite: Structures/Storage/closet.rsi
+ drawdepth: Effects
+ noRot: true
+ layers:
+ - state: "cardboard_special"
+ - type: TimedDespawn
+ lifetime: 1
+ - type: Tag
+ tags:
+ - HideContextMenu
+
+
+- type: entity
+ id: WhistleExclamation
+ name: exclamation
+ noSpawn: true
+ components:
+ - type: Sprite
+ sprite: Structures/Storage/closet.rsi
+ state: cardboard_special
+ drawdepth: Effects
+ offset: 0, 1
+ noRot: true
+ - type: Transform
+ noRot: true
+ - type: TimedDespawn
+ lifetime: 0.8
+ - type: Tag
+ tags:
+ - HideContextMenu
\ No newline at end of file
--- /dev/null
+- type: entity
+ abstract: true
+ parent: BaseItem
+ id: BaseWhistle
+ name: whistle
+ description: Someone forgot to turn off kettle?
+ components:
+ - type: Item
+ size: Tiny
+ - type: Clothing
+ quickEquip: false
+ slots: neck
+ - type: UseDelay
+ delay: 3
+ - type: EmitSoundOnUse
+ sound:
+ collection: BaseWhistle
+ - type: Whistle
+ distance: 5
+
+- type: entity
+ parent: BaseWhistle
+ id: SecurityWhistle
+ description: Sound of it make you feel fear.
+ components:
+ - type: Sprite
+ sprite: Objects/Fun/whistle.rsi
+ state: securityWhistle
+ - type: Item
+ sprite: Objects/Fun/whistle.rsi
\ No newline at end of file
- type: EntityStorage
isCollidableWhenOpen: false
openOnMove: false
- airtight: false
-
-#Exclamation effect for box opening
-- type: entity
- id: Exclamation
- name: exclamation
- noSpawn: true
- save: false
- components:
- - type: Transform
- noRot: true
- - type: Sprite
- sprite: Structures/Storage/closet.rsi
- drawdepth: Effects
- noRot: true
- layers:
- - state: "cardboard_special"
- - type: TimedDespawn
- lifetime: 1
- - type: Tag
- tags:
- - HideContextMenu
+ airtight: false
\ No newline at end of file
--- /dev/null
+- type: soundCollection
+ id: BaseWhistle
+ files:
+ - /Audio/Items/Whistle/whistle_1.ogg
+ - /Audio/Items/Whistle/whistle_2.ogg
+ - /Audio/Items/Whistle/whistle_3.ogg
+ - /Audio/Items/Whistle/whistle_4.ogg
+ - /Audio/Items/Whistle/whistle_5.ogg
+ - /Audio/Items/Whistle/whistle_6.ogg
+ - /Audio/Items/Whistle/whistle_7.ogg
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Made by Foleps (discord)",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "securityWhistle"
+ }
+ ]
+}