]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add craft for bonfire and bonfire with stake (#42211)
authorB_Kirill <153602297+B-Kirill@users.noreply.github.com>
Fri, 9 Jan 2026 04:00:36 +0000 (14:00 +1000)
committerGitHub <noreply@github.com>
Fri, 9 Jan 2026 04:00:36 +0000 (04:00 +0000)
* Add craft for bonfire and bonfire with stake

* review

* review

* nullable MaxFireStacks

* retry

* retry

* review

* I will change it and hope that they will agree with me

* Revert "I will change it and hope that they will agree with me"

This reverts commit 83823692d0116bf9aa9eceb85a10e95c88b51fb9.

* construction

Merged the graphs
Changed the bonfire stake ID to follow the proper naming scheme

* add destroy sound

* planks Instead of logs

* of course I forgot about ftl

* Slarti review + Princess review

Yes I sneaked an admeme abuse change here

* a small fix

* clamp firestacks

* This was on purpose, leave as is

This reverts commit 7d63e38b66cb63e5e50b7fac5030013e2ef508b5.

* irrelevant

* Fixtures

* cleanup

---------

Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Content.Server/Buckle/Systems/IgniteOnBuckleSystem.cs [new file with mode: 0644]
Content.Shared/Buckle/Components/ActiveIgniteOnBuckleComponent.cs [new file with mode: 0644]
Content.Shared/Buckle/Components/IgniteOnBuckleComponent.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml
Resources/Prototypes/Recipes/Construction/structures.yml
Resources/Prototypes/Recipes/Crafting/Graphs/bonfire.yml [new file with mode: 0644]
Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire_extinguished.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/bonfire_stake.rsi/burning.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/bonfire_stake.rsi/legionnaire_bonfire.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/bonfire_stake.rsi/meta.json [new file with mode: 0644]

diff --git a/Content.Server/Buckle/Systems/IgniteOnBuckleSystem.cs b/Content.Server/Buckle/Systems/IgniteOnBuckleSystem.cs
new file mode 100644 (file)
index 0000000..e7d088d
--- /dev/null
@@ -0,0 +1,70 @@
+using Content.Server.Atmos.EntitySystems;
+using Content.Shared.Atmos.Components;
+using Content.Shared.Buckle.Components;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Buckle.Systems;
+
+public sealed class IgniteOnBuckleSystem : EntitySystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly FlammableSystem _flammable = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<IgniteOnBuckleComponent, StrappedEvent>(OnStrapped);
+        SubscribeLocalEvent<IgniteOnBuckleComponent, UnstrappedEvent>(OnUnstrapped);
+
+        SubscribeLocalEvent<ActiveIgniteOnBuckleComponent, MapInitEvent>(ActiveOnInit);
+    }
+
+    private void OnStrapped(Entity<IgniteOnBuckleComponent> ent, ref StrappedEvent args)
+    {
+        // We cache the values here to the other component.
+        // This is done so we have to do less lookups
+        var comp = EnsureComp<ActiveIgniteOnBuckleComponent>(args.Buckle);
+        comp.FireStacks = ent.Comp.FireStacks;
+        comp.MaxFireStacks = ent.Comp.MaxFireStacks;
+        comp.IgniteTime = ent.Comp.IgniteTime;
+    }
+
+    private void ActiveOnInit(Entity<ActiveIgniteOnBuckleComponent> ent, ref MapInitEvent args)
+    {
+        // Handle this via a separate MapInit so the component can be added by itself if need be.
+        ent.Comp.NextIgniteTime = _timing.CurTime + ent.Comp.NextIgniteTime;
+        Dirty(ent);
+    }
+
+    private void OnUnstrapped(Entity<IgniteOnBuckleComponent> ent, ref UnstrappedEvent args)
+    {
+        RemCompDeferred<ActiveIgniteOnBuckleComponent>(args.Buckle);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var curTime = _timing.CurTime;
+
+        var query = EntityQueryEnumerator<ActiveIgniteOnBuckleComponent, FlammableComponent>();
+        while (query.MoveNext(out var uid, out var igniteComponent, out var flammableComponent))
+        {
+            if (curTime < igniteComponent.NextIgniteTime)
+                continue;
+
+            igniteComponent.NextIgniteTime += TimeSpan.FromSeconds(igniteComponent.IgniteTime);
+            Dirty(uid, igniteComponent);
+
+            if (flammableComponent.FireStacks > igniteComponent.MaxFireStacks)
+                continue;
+
+            var stacks = flammableComponent.FireStacks + igniteComponent.FireStacks;
+            if (igniteComponent.MaxFireStacks.HasValue)
+                stacks = Math.Min(stacks, igniteComponent.MaxFireStacks.Value);
+
+            _flammable.SetFireStacks(uid, stacks, flammableComponent, true);
+        }
+    }
+}
diff --git a/Content.Shared/Buckle/Components/ActiveIgniteOnBuckleComponent.cs b/Content.Shared/Buckle/Components/ActiveIgniteOnBuckleComponent.cs
new file mode 100644 (file)
index 0000000..f4fd4f5
--- /dev/null
@@ -0,0 +1,41 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Buckle.Components;
+
+/// <summary>
+/// Component for entities that are currently being ignited by <see cref="IgniteOnBuckleComponent"/>
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+[AutoGenerateComponentPause, AutoGenerateComponentState]
+public sealed partial class ActiveIgniteOnBuckleComponent : Component
+{
+    // We cache data in this component and apply it to those who get buckled to have to do less lookups.
+
+    /// <summary>
+    /// How many fire stacks to add per cycle.
+    /// </summary>
+    [DataField]
+    public float FireStacks = 0.5f;
+
+    /// <summary>
+    /// How frequently the ignition should be applied, in seconds.
+    /// </summary>
+    [DataField]
+    public float IgniteTime = 1f;
+
+    /// <summary>
+    /// Maximum fire stacks that can be added by this source.
+    /// If target already has this many or more fire stacks, no additional stacks will be added.
+    /// Null means unlimited.
+    /// </summary>
+    [DataField]
+    public float? MaxFireStacks = 2.5f;
+
+    /// <summary>
+    /// Next time that fire stacks will be applied.
+    /// </summary>
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+    [AutoPausedField, AutoNetworkedField]
+    public TimeSpan NextIgniteTime = TimeSpan.Zero;
+}
diff --git a/Content.Shared/Buckle/Components/IgniteOnBuckleComponent.cs b/Content.Shared/Buckle/Components/IgniteOnBuckleComponent.cs
new file mode 100644 (file)
index 0000000..61af16f
--- /dev/null
@@ -0,0 +1,31 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Buckle.Components;
+
+/// <summary>
+/// Component that makes an entity ignite entities that are buckled to it.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class IgniteOnBuckleComponent : Component
+{
+    /// <summary>
+    /// How many fire stacks to add per cycle.
+    /// </summary>
+    [DataField]
+    public float FireStacks = 0.5f;
+
+    /// <summary>
+    /// How frequently the ignition should be applied, in seconds.
+    /// </summary>
+    [DataField]
+    public float IgniteTime = 1f;
+
+    /// <summary>
+    /// Maximum fire stacks that can be added by this source.
+    /// If target already has this many or more fire stacks, no additional stacks will be added.
+    /// Null means unlimited.
+    /// </summary>
+    [DataField]
+    public float? MaxFireStacks = 2.5f;
+}
index b60b2bd94359123ee3b4cd92cbc8d8e9329f83f2..d28abb2b6333fc7da3e4a79cadaaaf79e2a3bccb 100644 (file)
@@ -1,15 +1,22 @@
 - type: entity
-  id: Bonfire
+  abstract: true
   parent: BaseStructure
-  name: bonfire
-  description: What can be better than a late evening under the sky with guitar and friends?
+  id: BaseBonfire
   components:
+  - type: Fixtures
+    fixtures:
+      fix1:
+        shape:
+          !type:PhysShapeCircle
+          radius: 0.4
+        mask:
+        - Impassable
+        layer:
+        - Opaque
+        - BulletImpassable
   - type: Sprite
     noRot: true
     sprite: Structures/Decoration/bonfire.rsi
-    layers:
-      - state: bonfire
-      - state: burning
   - type: PointLight
     radius: 5
     energy: 3
@@ -23,6 +30,9 @@
           !type:DamageTrigger
           damage: 50
         behaviors:
+        - !type:PlaySoundBehavior
+          sound:
+            collection: WoodDestroy
         - !type:DoActsBehavior
           acts: [ "Destruction" ]
   - type: AmbientSound
     sound:
       path: /Audio/Ambience/Objects/fireplace.ogg
   - type: AlwaysHot
+  - type: IgnitionSource
+    temperature: 700
+    ignited: true
+
+- type: entity
+  parent: BaseBonfire
+  id: Bonfire
+  name: bonfire
+  description: What can be better than a late evening under the sky with guitar and friends?
+  components:
+  - type: Sprite
+    layers:
+    - state: burning
+  - type: Construction
+    graph: Bonfire
+    node: bonfire
+
+- type: entity
+  parent: BaseBonfire
+  id: BonfireStake
+  name: bonfire with stake
+  description: A sinister bonfire with a stake for... ceremonial purposes. Best not to ask.
+  components:
+  - type: Sprite
+    sprite: Structures/Decoration/bonfire_stake.rsi
+    layers:
+    - state: burning
+    offset: "0, 0.5"
+  - type: Strap
+    position: Stand
+    buckleOffset: "0, 0.5"
+    buckleDoafterTime: 5
+  - type: IgniteOnBuckle
+  - type: Construction
+    graph: Bonfire
+    node: bonfireStake
 
 - type: entity
+  parent: BaseBonfire
   id: LegionnaireBonfire
-  parent: Bonfire
   name: legionnaire bonfire
   description: There, in the land of lava and ash, place to to cook marshmallow and potato.
   components:
   - type: Sprite
     layers:
-      - state: legionnaire_bonfire
+    - state: legionnaire_bonfire
   - type: PointLight
     color: "#FF5601"
index 1f568a16294efbdbed4e4bb44c9e8d22a07c0e05..5d60a5fc04a7d123deae5a968102b19ae9034cd5 100644 (file)
   canRotate: false
   canBuildInImpassable: false
   conditions:
-    - !type:TileNotBlocked
\ No newline at end of file
+    - !type:TileNotBlocked
+
+- type: construction
+  id: Bonfire
+  graph: Bonfire
+  startNode: start
+  targetNode: bonfire
+  category: construction-category-structures
+  objectType: Structure
+  placementMode: SnapgridCenter
+  canRotate: false
+  canBuildInImpassable: false
+  conditions:
+  - !type:TileNotBlocked
+
+- type: construction
+  id: BonfireStake
+  graph: Bonfire
+  startNode: start
+  targetNode: bonfireStake
+  category: construction-category-structures
+  objectType: Structure
+  placementMode: SnapgridCenter
+  canRotate: false
+  canBuildInImpassable: false
+  conditions:
+  - !type:TileNotBlocked
diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/bonfire.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/bonfire.yml
new file mode 100644 (file)
index 0000000..98ec98d
--- /dev/null
@@ -0,0 +1,42 @@
+- type: constructionGraph
+  id: Bonfire
+  start: start
+  graph:
+
+  - node: start
+    edges:
+    - to: bonfire
+      steps:
+      - material: WoodPlank
+        amount: 10
+        doAfter: 4
+
+  - node: bonfire
+    entity: Bonfire
+    edges:
+    - to: start
+      completed:
+      - !type:SpawnPrototype
+        prototype: MaterialWoodPlank1
+        amount: 10
+      - !type:DeleteEntity { }
+      steps:
+      - tool: Prying
+        doAfter: 4
+    - to: bonfireStake
+      steps:
+      - material: WoodPlank
+        amount: 2
+        doAfter: 2
+
+  - node: bonfireStake
+    entity: BonfireStake
+    edges:
+    - to: bonfire
+      completed:
+      - !type:SpawnPrototype
+        prototype: MaterialWoodPlank1
+        amount: 2
+      steps:
+      - tool: Prying
+        doAfter: 1
diff --git a/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire.png b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire.png
new file mode 100644 (file)
index 0000000..f197142
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire.png differ
diff --git a/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire_extinguished.png b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire_extinguished.png
new file mode 100644 (file)
index 0000000..c2e629e
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/bonfire_extinguished.png differ
diff --git a/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/burning.png b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/burning.png
new file mode 100644 (file)
index 0000000..cd5ccf1
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/burning.png differ
diff --git a/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/legionnaire_bonfire.png b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/legionnaire_bonfire.png
new file mode 100644 (file)
index 0000000..d130f96
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/legionnaire_bonfire.png differ
diff --git a/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/meta.json b/Resources/Textures/Structures/Decoration/bonfire_stake.rsi/meta.json
new file mode 100644 (file)
index 0000000..666b40d
--- /dev/null
@@ -0,0 +1,37 @@
+{
+    "version": 1,
+    "license": "CC-BY-SA-3.0",
+    "copyright": "Taken from /tg/station at commit 28b476ab6d17014e6f9e18a748d7c96be28de9a1, modified by B_Kirill",
+    "size": {
+        "x": 32,
+        "y": 64
+    },
+    "states": [
+        {
+            "name": "bonfire"
+        },
+        {
+            "name": "bonfire_extinguished"
+        },
+        {
+            "name": "burning",
+            "delays": [
+                [
+                    0.3,
+                    0.3,
+                    0.3
+                ]
+            ]
+        },
+        {
+            "name": "legionnaire_bonfire",
+            "delays": [
+                [
+                    0.3,
+                    0.3,
+                    0.3
+                ]
+            ]
+        }
+    ]
+}