]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Added Firebots - Real (#32482)
authorGolinth <amh2023@gmail.com>
Tue, 1 Oct 2024 03:13:16 +0000 (22:13 -0500)
committerGitHub <noreply@github.com>
Tue, 1 Oct 2024 03:13:16 +0000 (20:13 -0700)
* Add Firebots

Had to add OnActivateInWorld to the spray system to get the bot to work. Checks for the flammable component and if the onFire boolean is true.

* Make SpraySystem actually use useDelay

got rid of that TODO

* Added firebot speech

Fire detected!

15 files changed:
Content.Server/Fluids/EntitySystems/SpraySystem.cs
Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs [new file with mode: 0644]
Content.Server/NPC/Systems/NPCUtilitySystem.cs
Resources/Locale/en-US/interaction/interaction-popup-component.ftl
Resources/Locale/en-US/npc/firebot.ftl [new file with mode: 0644]
Resources/Prototypes/Entities/Clothing/Head/helmets.yml
Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml
Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml
Resources/Prototypes/NPCs/firebot.yml [new file with mode: 0644]
Resources/Prototypes/NPCs/utility_queries.yml
Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml [new file with mode: 0644]
Resources/Prototypes/Recipes/Crafting/bots.yml
Resources/Prototypes/tags.yml
Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png [new file with mode: 0644]
Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json [new file with mode: 0644]

index fe179be402f9f501e86cb849b9ee1ac9d328ac3c..a1f195bf43ed8828b7e973b4784106465e3f3a0a 100644 (file)
@@ -14,6 +14,7 @@ using Robust.Shared.Audio.Systems;
 using Robust.Shared.Physics.Components;
 using Robust.Shared.Prototypes;
 using System.Numerics;
+using Robust.Shared.Map;
 
 namespace Content.Server.Fluids.EntitySystems;
 
@@ -35,6 +36,19 @@ public sealed class SpraySystem : EntitySystem
         base.Initialize();
 
         SubscribeLocalEvent<SprayComponent, AfterInteractEvent>(OnAfterInteract);
+        SubscribeLocalEvent<SprayComponent, UserActivateInWorldEvent>(OnActivateInWorld);
+    }
+
+    private void OnActivateInWorld(Entity<SprayComponent> entity, ref UserActivateInWorldEvent args)
+    {
+        if (args.Handled)
+            return;
+
+        args.Handled = true;
+
+        var targetMapPos = _transform.GetMapCoordinates(GetEntityQuery<TransformComponent>().GetComponent(args.Target));
+
+        Spray(entity, args.User, targetMapPos);
     }
 
     private void OnAfterInteract(Entity<SprayComponent> entity, ref AfterInteractEvent args)
@@ -44,29 +58,36 @@ public sealed class SpraySystem : EntitySystem
 
         args.Handled = true;
 
+        var clickPos = _transform.ToMapCoordinates(args.ClickLocation);
+
+        Spray(entity, args.User, clickPos);
+    }
+
+    public void Spray(Entity<SprayComponent> entity, EntityUid user, MapCoordinates mapcoord)
+    {
         if (!_solutionContainer.TryGetSolution(entity.Owner, SprayComponent.SolutionName, out var soln, out var solution))
             return;
 
-        var ev = new SprayAttemptEvent(args.User);
+        var ev = new SprayAttemptEvent(user);
         RaiseLocalEvent(entity, ref ev);
         if (ev.Cancelled)
             return;
 
-        if (!TryComp<UseDelayComponent>(entity, out var useDelay)
-            || _useDelay.IsDelayed((entity, useDelay)))
+        if (TryComp<UseDelayComponent>(entity, out var useDelay)
+            && _useDelay.IsDelayed((entity, useDelay)))
             return;
 
         if (solution.Volume <= 0)
         {
-            _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, args.User);
+            _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, user);
             return;
         }
 
         var xformQuery = GetEntityQuery<TransformComponent>();
-        var userXform = xformQuery.GetComponent(args.User);
+        var userXform = xformQuery.GetComponent(user);
 
         var userMapPos = _transform.GetMapCoordinates(userXform);
-        var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform);
+        var clickMapPos = mapcoord;
 
         var diffPos = clickMapPos.Position - userMapPos.Position;
         if (diffPos == Vector2.Zero || diffPos == Vector2Helpers.NaN)
@@ -88,8 +109,6 @@ public sealed class SpraySystem : EntitySystem
 
         var amount = Math.Max(Math.Min((solution.Volume / entity.Comp.TransferAmount).Int(), entity.Comp.VaporAmount), 1);
         var spread = entity.Comp.VaporSpread / amount;
-        // TODO: Just use usedelay homie.
-        var cooldownTime = 0f;
 
         for (var i = 0; i < amount; i++)
         {
@@ -131,20 +150,19 @@ public sealed class SpraySystem : EntitySystem
             // impulse direction is defined in world-coordinates, not local coordinates
             var impulseDirection = rotation.ToVec();
             var time = diffLength / entity.Comp.SprayVelocity;
-            cooldownTime = MathF.Max(time, cooldownTime);
 
-            _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, args.User);
+            _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, user);
 
-            if (TryComp<PhysicsComponent>(args.User, out var body))
+            if (TryComp<PhysicsComponent>(user, out var body))
             {
-                if (_gravity.IsWeightless(args.User, body))
-                    _physics.ApplyLinearImpulse(args.User, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body);
+                if (_gravity.IsWeightless(user, body))
+                    _physics.ApplyLinearImpulse(user, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body);
             }
         }
 
         _audio.PlayPvs(entity.Comp.SpraySound, entity, entity.Comp.SpraySound.Params.WithVariation(0.125f));
 
-        _useDelay.SetLength(entity.Owner, TimeSpan.FromSeconds(cooldownTime));
-        _useDelay.TryResetDelay((entity, useDelay));
+        if (useDelay != null)
+            _useDelay.TryResetDelay((entity, useDelay));
     }
 }
diff --git a/Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs b/Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs
new file mode 100644 (file)
index 0000000..d86dbc0
--- /dev/null
@@ -0,0 +1,9 @@
+namespace Content.Server.NPC.Queries.Considerations;
+
+/// <summary>
+/// Returns 1f if the target is on fire or 0f if not.
+/// </summary>
+public sealed partial class TargetOnFireCon : UtilityConsideration
+{
+
+}
index 8dff93648bff86ec1ff237ec5fa290045efd1343..60bc5cdfd8b86f7f846f0ce989b238e468a63001 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Server.Atmos.Components;
 using Content.Server.Fluids.EntitySystems;
 using Content.Server.NPC.Queries;
 using Content.Server.NPC.Queries.Considerations;
@@ -351,6 +352,12 @@ public sealed class NPCUtilitySystem : EntitySystem
 
                 return 0f;
             }
+            case TargetOnFireCon:
+                {
+                    if (TryComp(targetUid, out FlammableComponent? fire) && fire.OnFire)
+                        return 1f;
+                    return 0f;
+                }
             default:
                 throw new NotImplementedException();
         }
index 10773d6de843ad56919acdfba880e308fa58e8c2..a180b698fac9d7275a618a8e40ad3043b0866b28 100644 (file)
@@ -60,6 +60,7 @@ petting-success-honkbot = You pet {THE($target)} on {POSS-ADJ($target)} slippery
 petting-success-mimebot = You pet {THE($target)} on {POSS-ADJ($target)} cold metal head.
 petting-success-cleanbot = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head.
 petting-success-medibot = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head.
+petting-success-firebot = You pet {THE($target)} on {POSS-ADJ($target)} warm metal head. 
 petting-success-generic-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} metal head.
 petting-success-salvage-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dirty metal head.
 petting-success-engineer-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} reflective metal head.
@@ -73,6 +74,7 @@ petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($tar
 petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping!
 petting-failure-mimebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy miming!
 petting-failure-medibot = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} syringe nearly stabs your hand!
+petting-failure-firebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} sprays you in the face before you can get close!
 petting-failure-generic-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy stating laws!
 petting-failure-salvage-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy drilling!
 petting-failure-engineer-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy repairing!
diff --git a/Resources/Locale/en-US/npc/firebot.ftl b/Resources/Locale/en-US/npc/firebot.ftl
new file mode 100644 (file)
index 0000000..758874c
--- /dev/null
@@ -0,0 +1 @@
+firebot-fire-detected = Fire detected!
index 625ef7a0561a7b9bd2e278b0cfc94c5b1bd61f41..11643c076d84cc70e6da70a3a207863a5fd6a07c 100644 (file)
   - type: Tag
     tags:
     - WhitelistChameleon
+    - FireHelmet
   - type: HideLayerClothing
     slots:
     - Hair
   - type: Tag
     tags:
     - WhitelistChameleon
+    - FireHelmet
   - type: HideLayerClothing
     slots:
     - Hair
index d5b4366e2baea9c49270c20b262e005182ece850..7d988c6fe95c93967218255ab01a3e09daf4da92 100644 (file)
   - type: NoSlip
   - type: Insulated
 
+- type: entity
+  parent: MobSiliconBase
+  id: MobFireBot
+  name: firebot
+  description: A little fire extinguishing bot. He looks rather anxious.
+  components:
+  - type: Sprite
+    sprite: Mobs/Silicon/Bots/firebot.rsi
+    state: firebot
+  - type: Construction
+    graph: FireBot
+    node: bot
+  - type: SentienceTarget
+    flavorKind: station-event-random-sentience-flavor-mechanical
+  - type: HTN
+    rootTask:
+      task: FirebotCompound
+  - type: SolutionContainerManager
+    solutions:
+      spray:
+        maxVol: 10
+        reagents:
+        - ReagentId: Water
+          Quantity: 10
+  - type: SolutionRegeneration
+    solution: spray
+    generated:
+      reagents:
+        - ReagentId: Water
+          Quantity: 10
+  - type: Spray
+    transferAmount: 10
+    pushbackAmount: 60
+    spraySound:
+      path: /Audio/Effects/extinguish.ogg
+    sprayedPrototype: ExtinguisherSpray
+    vaporAmount: 1
+    vaporSpread: 90
+    sprayVelocity: 3.0
+  - type: UseDelay
+    delay: 4
+  - type: InteractionPopup
+    interactSuccessString: petting-success-firebot
+    interactFailureString: petting-failure-firebot
+    interactSuccessSound:
+      path: /Audio/Ambience/Objects/periodic_beep.ogg
+
 - type: entity
   parent: MobSiliconBase
   id: MobHonkBot
index 0389db27ea03650a81dadfde1374532baeb2e60d..b306da644212025e0954fba04760c6a9bd25ca1a 100644 (file)
@@ -62,6 +62,9 @@
     - Rolling
     speedModifier: 0.5 # its very big, awkward to use
   - type: Appearance
+  - type: Tag
+    tags:
+      - FireExtinguisher
   - type: GenericVisualizer
     visuals:
       enum.ToggleVisuals.Toggled:
diff --git a/Resources/Prototypes/NPCs/firebot.yml b/Resources/Prototypes/NPCs/firebot.yml
new file mode 100644 (file)
index 0000000..acea649
--- /dev/null
@@ -0,0 +1,44 @@
+- type: htnCompound
+  id: FirebotCompound
+  branches:
+    - tasks:
+        - !type:HTNCompoundTask
+          task: DouseFireTargetCompound
+    - tasks:
+        - !type:HTNCompoundTask
+          task: IdleCompound    
+          
+- type: htnCompound
+  id: DouseFireTargetCompound
+  branches:
+    - tasks:
+        - !type:HTNPrimitiveTask
+          operator: !type:UtilityOperator
+            proto: NearbyOnFire
+
+        - !type:HTNPrimitiveTask
+          operator: !type:SpeakOperator
+            speech: firebot-fire-detected
+            hidden: true  
+
+        - !type:HTNPrimitiveTask
+          operator: !type:MoveToOperator
+            pathfindInPlanning: true
+            removeKeyOnFinish: false
+            targetKey: TargetCoordinates
+            pathfindKey: TargetPathfind
+            rangeKey: InteractRange
+
+        - !type:HTNPrimitiveTask
+          preconditions:
+            - !type:TargetInRangePrecondition
+              targetKey: Target
+              rangeKey: InteractRange
+          operator: !type:InteractWithOperator
+            targetKey: Target
+          services:
+            - !type:UtilityService
+              id: FireService
+              proto: NearbyOnFire
+              key: Target
+
index 06bc0a9a9ebe6f2b7ee3c4c07aef66bca76b8477..e10a0ed30cd8f31dfc32859ad2ac403b4389bb5d 100644 (file)
     - !type:TargetAccessibleCon
       curve: !type:BoolCurve
 
+- type: utilityQuery
+  id: NearbyOnFire
+  query:
+    - !type:ComponentQuery
+      components:
+        - type: Flammable
+          # why does Flammable even have a required damage
+          damage:
+            types:
+              burn: 0
+  considerations:
+    - !type:TargetDistanceCon
+      curve: !type:PresetCurve
+        preset: TargetDistance
+    - !type:TargetAccessibleCon
+      curve: !type:BoolCurve
+    - !type:TargetInLOSOrCurrentCon
+      curve: !type:BoolCurve
+    - !type:TargetOnFireCon
+      curve: !type:BoolCurve
+
 - type: utilityQuery
   id: NearbyPuddles
   query:
diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml
new file mode 100644 (file)
index 0000000..977ffd4
--- /dev/null
@@ -0,0 +1,33 @@
+- type: constructionGraph
+  id: FireBot
+  start: start
+  graph:
+  - node: start
+    edges:
+    - to: bot
+      steps:
+      - tag: FireExtinguisher
+        icon:
+          sprite: Objects/Misc/fire_extinguisher.rsi
+          state: fire_extinguisher_open
+        name: fire extinguisher
+      - tag: FireHelmet
+        icon: 
+          sprite: Clothing/Head/Helmets/firehelmet.rsi
+          state: icon
+        name: fire helmet
+        doAfter: 2
+      - tag: ProximitySensor
+        icon:
+          sprite: Objects/Misc/proximity_sensor.rsi
+          state: icon
+        name: proximity sensor
+        doAfter: 2
+      - tag: BorgArm
+        icon:
+          sprite: Mobs/Silicon/drone.rsi
+          state: l_hand
+        name: borg arm
+        doAfter: 2
+  - node: bot
+    entity: MobFireBot
index 3031f4a7803599613bc29041cbf26e22fad26c1a..21b524a060956a312f15c58b0f0098f7eb349b4f 100644 (file)
     sprite: Mobs/Silicon/Bots/cleanbot.rsi
     state: cleanbot
 
+- type: construction
+  name: firebot
+  id: firebot
+  graph: FireBot
+  startNode: start
+  targetNode: bot
+  category: construction-category-utilities
+  objectType: Item
+  description: This bot puts out fires wherever it goes.
+  icon:
+    sprite: Mobs/Silicon/Bots/firebot.rsi
+    state: firebot
+
 - type: construction
   name: honkbot
   id: honkbot
index 2a07d061d3aa390558860512e32e0eff75905e00..86ade97d4ea57cb8ad52ee2764b5e6c91da7c398 100644 (file)
 - type: Tag
   id: FirelockElectronics
 
+- type: Tag
+  id: FireExtinguisher
+
+- type: Tag
+  id: FireHelmet
+
 - type: Tag
   id: Flare
 
diff --git a/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png
new file mode 100644 (file)
index 0000000..70ee931
Binary files /dev/null and b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png differ
diff --git a/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json
new file mode 100644 (file)
index 0000000..e13b42d
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "version": 1,
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "license": "CC-BY-SA-3.0",
+  "copyright": "Taken from https://github.com/tgstation/tgstation/commit/eba0d62005e7754dd8b1c88e45cd949c360774d5",
+  "states": [
+    {
+      "name": "firebot",
+      "delays": [
+        [
+          0.5,
+          0.2
+        ]
+      ]
+    }
+  ]
+}