diff --git a/Content.Client/Atmos/Components/FireVisualsComponent.cs b/Content.Client/Atmos/Components/FireVisualsComponent.cs index 02278e9479..36e58438f3 100644 --- a/Content.Client/Atmos/Components/FireVisualsComponent.cs +++ b/Content.Client/Atmos/Components/FireVisualsComponent.cs @@ -32,7 +32,7 @@ public sealed partial class FireVisualsComponent : Component public float MaxLightRadius = 4f; [DataField("lightColor")] - public Color LightColor = Color.Orange; + public Color LightColor = Color.FromSrgb( new Color(239, 181, 20)); //CP14 fire color in art style pallette /// /// Client side point-light entity. We use this instead of directly adding a light to diff --git a/Content.Server/_CP14/Temperature/CP14AutoIgniteComponent.cs b/Content.Server/_CP14/Temperature/CP14AutoIgniteComponent.cs new file mode 100644 index 0000000000..2f23c840be --- /dev/null +++ b/Content.Server/_CP14/Temperature/CP14AutoIgniteComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server._CP14.Temperature; + +[RegisterComponent, Access(typeof(CP14FireSpreadSystem))] +public sealed partial class CP14AutoIgniteComponent : Component +{ + [DataField] + public float StartStack = 1f; +} diff --git a/Content.Server/_CP14/Temperature/CP14DespawnOnExtinguishComponent.cs b/Content.Server/_CP14/Temperature/CP14DespawnOnExtinguishComponent.cs new file mode 100644 index 0000000000..0b101b0d42 --- /dev/null +++ b/Content.Server/_CP14/Temperature/CP14DespawnOnExtinguishComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server._CP14.Temperature; + +[RegisterComponent, Access(typeof(CP14FireSpreadSystem))] +public sealed partial class CP14DespawnOnExtinguishComponent : Component +{ +} diff --git a/Content.Server/_CP14/Temperature/CP14FireSpreadComponent.cs b/Content.Server/_CP14/Temperature/CP14FireSpreadComponent.cs index 786511b498..31a7301bb2 100644 --- a/Content.Server/_CP14/Temperature/CP14FireSpreadComponent.cs +++ b/Content.Server/_CP14/Temperature/CP14FireSpreadComponent.cs @@ -19,6 +19,12 @@ public sealed partial class CP14FireSpreadComponent : Component [DataField] public float Prob = 0.5f; + /// + /// chance of tile spreading to neighboring properties + /// + [DataField] + public float ProbTile = 0.15f; + /// /// how often objects will try to set the neighbors on fire. In Seconds /// diff --git a/Content.Server/_CP14/Temperature/CP14FireSpreadSystem.cs b/Content.Server/_CP14/Temperature/CP14FireSpreadSystem.cs index d570f5ed3a..64ab303ada 100644 --- a/Content.Server/_CP14/Temperature/CP14FireSpreadSystem.cs +++ b/Content.Server/_CP14/Temperature/CP14FireSpreadSystem.cs @@ -1,5 +1,11 @@ +using System.Linq; +using System.Numerics; using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; +using Content.Shared.Maps; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -7,17 +13,35 @@ namespace Content.Server._CP14.Temperature; public sealed partial class CP14FireSpreadSystem : EntitySystem { - [Dependency] private readonly FlammableSystem _flammable = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; + [Dependency] private readonly TileSystem _tile = default!; + [Dependency] private readonly ITileDefinitionManager _tiledef = default!; - + private EntProtoId _fireProto = "CP14Fire"; public override void Initialize() { - SubscribeLocalEvent (OnCompInit); + SubscribeLocalEvent(OnCompInit); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnFireChanged); + } + + private void OnFireChanged(Entity ent, ref OnFireChangedEvent args) + { + if (!args.OnFire) + QueueDel(ent); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (!TryComp(ent, out var flammable)) + return; + _flammable.AdjustFireStacks(ent, ent.Comp.StartStack, flammable); + _flammable.Ignite(ent, ent, flammable); } private void OnCompInit(Entity ent, ref OnFireChangedEvent args) @@ -33,27 +57,68 @@ public sealed partial class CP14FireSpreadSystem : EntitySystem { base.Update(frameTime); + List> spreadUids = new(); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var spread, out var flammable)) { if (!flammable.OnFire) continue; - if (spread.NextSpreadTime < _gameTiming.CurTime) // Spread - { - var targets = _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(uid), spread.Radius); + if (spread.NextSpreadTime >= _gameTiming.CurTime) + continue; - foreach (var target in targets) - { - if (!_random.Prob(spread.Prob)) - continue; + var cooldown = _random.NextFloat(spread.SpreadCooldownMin, spread.SpreadCooldownMax); + spread.NextSpreadTime = _gameTiming.CurTime + TimeSpan.FromSeconds(cooldown); - _flammable.Ignite(target, uid); + spreadUids.Add(new Entity(uid, spread)); + } - var cooldown = _random.NextFloat(spread.SpreadCooldownMin, spread.SpreadCooldownMax); - spread.NextSpreadTime = _gameTiming.CurTime + TimeSpan.FromSeconds(cooldown); - } - } + foreach (var uid in spreadUids) + { + IgniteEntities(uid, uid.Comp); + IgniteTiles(uid, uid.Comp); + } + } + + private void IgniteEntities(EntityUid uid, CP14FireSpreadComponent spread) + { + var targets = _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(uid), spread.Radius); + foreach (var target in targets) + { + if (!_random.Prob(spread.Prob)) + continue; + + _flammable.Ignite(target, uid); + } + } + + private void IgniteTiles(EntityUid uid, CP14FireSpreadComponent spread) + { + var xform = Transform(uid); + if (!TryComp(xform.GridUid, out var grid)) + return; + + var localPos = xform.Coordinates.Position; + var tileRefs = _mapSystem.GetLocalTilesIntersecting(grid.Owner, + grid, + new Box2( + localPos + new Vector2(-spread.Radius, -spread.Radius), + localPos + new Vector2(spread.Radius, spread.Radius))) + .ToList(); + + + foreach (var tileref in tileRefs) + { + if (!_random.Prob(spread.ProbTile)) + continue; + + var tile = tileref.Tile.GetContentTileDefinition(); + + if (tile.BurnedTile == string.Empty) + continue; + + Spawn(_fireProto, _mapSystem.ToCenterCoordinates(tileref, grid)); + _tile.ReplaceTile(tileref, (ContentTileDefinition) _tiledef[tile.BurnedTile]); } } } diff --git a/Content.Shared/Maps/ContentTileDefinition.cs b/Content.Shared/Maps/ContentTileDefinition.cs index c6485d2461..fea4384db3 100644 --- a/Content.Shared/Maps/ContentTileDefinition.cs +++ b/Content.Shared/Maps/ContentTileDefinition.cs @@ -119,9 +119,15 @@ namespace Content.Shared.Maps } /// - /// CrystallPunk Tile filtering + /// CP14 - Tile filtering /// [DataField] public bool EditorHidden { get; private set; } = true; + + /// + /// CP14 - If not empty, the tile can burn from fires, and will turn into the specified tile after burning. + /// + [DataField] + public string BurnedTile { get; private set; } = string.Empty; } } diff --git a/Resources/Locale/en-US/_CP14/tiles/tiles.ftl b/Resources/Locale/en-US/_CP14/tiles/tiles.ftl index e3fa1afc02..8bfa01495b 100644 --- a/Resources/Locale/en-US/_CP14/tiles/tiles.ftl +++ b/Resources/Locale/en-US/_CP14/tiles/tiles.ftl @@ -10,7 +10,11 @@ cp14-tiles-sand = sand cp14-tiles-foundation = foundation cp14-tiles-woodplanks = wood plank floor +cp14-tiles-woodplanks-broken = broken wood plank floor +cp14-tiles-woodplanks-burned = burned wood plank floor cp14-tiles-woodplanks-big = large wood plank floor +cp14-tiles-woodplanks-big-broken = broken large wood plank floor +cp14-tiles-woodplanks-big-burned = burned large wood plank floor cp14-tiles-stonebricks = stone brick floor cp14-tiles-stonebricks-small-carved1 = carved brick floor cp14-tiles-stonebricks-small-carved2 = carved brick floor diff --git a/Resources/Locale/ru-RU/_CP14/tiles/tiles.ftl b/Resources/Locale/ru-RU/_CP14/tiles/tiles.ftl index 3d441acf11..ff60e53ae3 100644 --- a/Resources/Locale/ru-RU/_CP14/tiles/tiles.ftl +++ b/Resources/Locale/ru-RU/_CP14/tiles/tiles.ftl @@ -9,9 +9,13 @@ cp14-tiles-sand = песок # Produced cp14-tiles-foundation = фундамент -cp14-tiles-woodplanks = пол из деревянных досок -cp14-tiles-woodplanks-big = пол из больших деревянных досок -cp14-tiles-stonebricks = каменный кирпичынй пол +cp14-tiles-woodplanks = деревянные доски +cp14-tiles-woodplanks-broken = сломанные деревянные доски +cp14-tiles-woodplanks-burned = сгоревшие деревянные доски +cp14-tiles-woodplanks-big = большие деревянные доски +cp14-tiles-woodplanks-big-broken = сломанные большие деревянные доски +cp14-tiles-woodplanks-big-burned = сгоревшие большие деревянные доски +cp14-tiles-stonebricks = каменный кирпичный пол cp14-tiles-stonebricks-small-carved1 = пол из резного кирпича cp14-tiles-stonebricks-small-carved2 = пол из резного кирпича cp14-tiles-stonebricks-square-carved = пол из резного кирпича \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Decorations/wallmount.yml b/Resources/Prototypes/_CP14/Entities/Structures/Decorations/wallmount.yml index 962b6e0215..34494604d4 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Decorations/wallmount.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Decorations/wallmount.yml @@ -17,6 +17,17 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 25 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Fixtures fixtures: fix1: @@ -56,6 +67,17 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 25 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Fixtures fixtures: fix1: @@ -94,6 +116,17 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 25 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/bonfire.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/bonfire.yml index abad860d8f..4fcf0f725a 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/bonfire.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/bonfire.yml @@ -38,3 +38,5 @@ whitelist: tags: - CP14FireplaceFuel + - type: CP14FireSpread + radius: 0.25 diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml index 2a8544e3a9..f4c87ee8d2 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml @@ -63,19 +63,19 @@ - type: entity id: CP14AlchemyFurnaceDebug parent: CP14AlchemyFurnace - suffix: DEBUG + categories: + - Debug components: - type: CP14Fireplace fuel: 100 fuelDrainingPerUpdate: 0 + - type: CP14AutoIgnite - type: entity id: CP14AlchemyFurnace name: alchemy furnace parent: CP14BaseFireplace description: A furnace fueled by wood, coal, or any other burning material. Handy for heating your alchemical potions. - categories: - - Debug components: - type: Sprite sprite: _CP14/Structures/Specific/Alchemy/alchemy_furnace.rsi diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml index ca73f852e7..422e9ba177 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml @@ -24,7 +24,6 @@ id: CP14WallStonebrick name: stone brick wall parent: CP14BaseWall - description: Bruh components: - type: Sprite sprite: _CP14/Structures/Walls/bricks_stone_wall.rsi @@ -37,7 +36,6 @@ id: CP14WallWhitebrick name: white brick wall parent: CP14BaseWall - description: Bruh components: - type: Sprite sprite: _CP14/Structures/Walls/whitebricks_stone_wall.rsi @@ -50,7 +48,6 @@ id: CP14WallBrownbrick name: brick wall parent: CP14BaseWall - description: Bruh components: - type: Sprite sprite: _CP14/Structures/Walls/bricks_wall.rsi @@ -62,8 +59,9 @@ - type: entity id: CP14WallWooden name: wooden wall - parent: CP14BaseWall - description: Bruh + parent: + - CP14BaseWall + - CP14BaseWooden components: - type: Sprite sprite: _CP14/Structures/Walls/wooden_wall.rsi @@ -71,6 +69,20 @@ sprite: _CP14/Structures/Walls/wooden_wall.rsi - type: IconSmooth base: wood + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: CP14WallCardboard diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Walls/wooden_fence.yml b/Resources/Prototypes/_CP14/Entities/Structures/Walls/wooden_fence.yml index ac80259f2f..d7227c5dc9 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Walls/wooden_fence.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Walls/wooden_fence.yml @@ -1,5 +1,7 @@ - type: entity - parent: BaseStructure + parent: + - BaseStructure + - CP14BaseWooden id: CP14BaseFenceWood name: wooden fence description: Wooden piece of fencing. I hope there is babushka's garden behind it. diff --git a/Resources/Prototypes/_CP14/Entities/fire.yml b/Resources/Prototypes/_CP14/Entities/fire.yml new file mode 100644 index 0000000000..80e2e10eca --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/fire.yml @@ -0,0 +1,63 @@ +- type: entity + id: CP14Fire + name: fire + suffix: cp14 + placement: + mode: SnapgridCenter + components: + - type: Sprite + drawDepth: Mobs + sprite: _CP14/Effects/fire.rsi + layers: + - state: full + - type: FireVisuals + sprite: _CP14/Effects/fire.rsi + normalState: full + alternateState: full2 + fireStackAlternateState: 5 + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - SlipLayer + mask: + - ItemMask + density: 1000 + hard: false + - type: Lava + fireStacks: 0.2 + - type: StepTrigger + requiredTriggeredSpeed: 0 + intersectRatio: 0.1 + - type: AmbientSound + enabled: true + volume: -5 + range: 5 + sound: + path: /Audio/Ambience/Objects/fireplace.ogg #TODO more aggressive sound + - type: Appearance + - type: Reactive + groups: + Flammable: [ Touch ] + Extinguish: [ Touch ] + - type: Flammable + fireSpread: false #Lava comp kostыль + canResistFire: false + alwaysCombustible: true + canExtinguish: true + firestacksOnIgnite: 0.5 + damage: + types: + Heat: 0 + - type: CP14FlammableEntityHeater + - type: CP14FlammableSolutionHeater + - type: CP14Fireplace + fuel: 15 + - type: CP14AutoIgnite + - type: CP14FireSpread + - type: CP14DespawnOnExtinguish \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Tiles/produced.yml b/Resources/Prototypes/_CP14/Tiles/produced.yml index 50d4a903ff..60e0f413d5 100644 --- a/Resources/Prototypes/_CP14/Tiles/produced.yml +++ b/Resources/Prototypes/_CP14/Tiles/produced.yml @@ -33,6 +33,43 @@ collection: FootstepWood heatCapacity: 10000 weather: false + burnedTile: CP14FloorWoodPlanksBurned + +- type: tile + editorHidden: false + id: CP14FloorWoodPlanksBroken + name: cp14-tiles-woodplanks-broken + sprite: /Textures/_CP14/Tiles/woodplanks_broken.png + variants: 4 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: CP14FloorFoundation + isSubfloor: false + footstepSounds: + collection: FootstepWood + heatCapacity: 10000 + weather: false + burnedTile: CP14FloorWoodPlanksBurned + +- type: tile + editorHidden: false + id: CP14FloorWoodPlanksBurned + name: cp14-tiles-woodplanks-burned + sprite: /Textures/_CP14/Tiles/woodplanks_burned.png + variants: 4 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: CP14FloorFoundation + isSubfloor: false + footstepSounds: + collection: FootstepWood + heatCapacity: 10000 - type: tile editorHidden: false @@ -51,6 +88,44 @@ collection: FootstepWood heatCapacity: 10000 weather: false + burnedTile: CP14FloorWoodPlanksBigBurned + +- type: tile + editorHidden: false + id: CP14FloorWoodPlanksBigBroken + name: cp14-tiles-woodplanks-big-broken + sprite: /Textures/_CP14/Tiles/woodplanks_big_broken.png + variants: 4 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: CP14FloorFoundation + isSubfloor: false + footstepSounds: + collection: FootstepWood + heatCapacity: 10000 + weather: false + burnedTile: CP14FloorWoodPlanksBigBurned + +- type: tile + editorHidden: false + id: CP14FloorWoodPlanksBigBurned + name: cp14-tiles-woodplanks-big-burned + sprite: /Textures/_CP14/Tiles/woodplanks_big_burned.png + variants: 4 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: CP14FloorFoundation + isSubfloor: false + footstepSounds: + collection: FootstepWood + heatCapacity: 10000 + weather: false - type: tile editorHidden: false diff --git a/Resources/Textures/_CP14/Effects/fire.rsi/full2.png b/Resources/Textures/_CP14/Effects/fire.rsi/full2.png new file mode 100644 index 0000000000..0164ffa8e9 Binary files /dev/null and b/Resources/Textures/_CP14/Effects/fire.rsi/full2.png differ diff --git a/Resources/Textures/_CP14/Effects/fire.rsi/meta.json b/Resources/Textures/_CP14/Effects/fire.rsi/meta.json index 676afa22ff..898190e400 100644 --- a/Resources/Textures/_CP14/Effects/fire.rsi/meta.json +++ b/Resources/Textures/_CP14/Effects/fire.rsi/meta.json @@ -18,6 +18,17 @@ ] ] }, + { + "name": "full2", + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, { "name": "small", "delays": [ diff --git a/Resources/Textures/_CP14/Tiles/attributions.yml b/Resources/Textures/_CP14/Tiles/attributions.yml index 9623a0283c..117b0d3598 100644 --- a/Resources/Textures/_CP14/Tiles/attributions.yml +++ b/Resources/Textures/_CP14/Tiles/attributions.yml @@ -16,12 +16,7 @@ copyright: "Created by Jaraten for CrystallPunk14" source: "https://github.com/crystallpunk-14/crystall-punk-14/" -- files: ["woodplanks.png"] - license: "CC-BY-SA-3.0" - copyright: "Space Station 14, recolored by TheShuEd" - source: "https://github.com/crystallpunk-14/crystall-punk-14/" - -- files: ["woodplanks_big.png"] +- files: ["woodplanks.png", "woodplanks_big.png", "woodplanks_broken.png", "woodplanks_burned.png", "woodplanks_big_burned.png", "woodplanks_big_broken.png"] license: "CC-BY-SA-3.0" copyright: "Space Station 14, recolored by TheShuEd" source: "https://github.com/crystallpunk-14/crystall-punk-14/" \ No newline at end of file diff --git a/Resources/Textures/_CP14/Tiles/woodplanks_big_broken.png b/Resources/Textures/_CP14/Tiles/woodplanks_big_broken.png new file mode 100644 index 0000000000..b8b9a8c771 Binary files /dev/null and b/Resources/Textures/_CP14/Tiles/woodplanks_big_broken.png differ diff --git a/Resources/Textures/_CP14/Tiles/woodplanks_big_burned.png b/Resources/Textures/_CP14/Tiles/woodplanks_big_burned.png new file mode 100644 index 0000000000..345d6e7381 Binary files /dev/null and b/Resources/Textures/_CP14/Tiles/woodplanks_big_burned.png differ diff --git a/Resources/Textures/_CP14/Tiles/woodplanks_broken.png b/Resources/Textures/_CP14/Tiles/woodplanks_broken.png new file mode 100644 index 0000000000..e4ffc01e9d Binary files /dev/null and b/Resources/Textures/_CP14/Tiles/woodplanks_broken.png differ diff --git a/Resources/Textures/_CP14/Tiles/woodplanks_burned.png b/Resources/Textures/_CP14/Tiles/woodplanks_burned.png new file mode 100644 index 0000000000..f3b05539ed Binary files /dev/null and b/Resources/Textures/_CP14/Tiles/woodplanks_burned.png differ