Fireplace (#123)

* bonfire!

* fix

* update torch

* docs

* add audio, fix errors

* loc string + fix errors
This commit is contained in:
Ed
2024-05-01 19:55:48 +03:00
committed by GitHub
parent 0169cb55d8
commit 2c34befbcb
23 changed files with 283 additions and 54 deletions

View File

@@ -77,18 +77,5 @@ namespace Content.Server.Atmos.Components
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float FirestackFade = -0.1f;
/// <summary>
/// Set FirestackFade on Ingite to this value
/// </summary>
[DataField]
public float? FirestackFadeOnIgnite = null;
/// <summary>
/// CrystallPunk moment
/// determines how extinction "FirestackFade" will fade out. it can be used to make "parabolas" of object ignition and decay.
/// </summary>
[DataField]
public float FirestackFadeFade = 0;
}
}

View File

@@ -334,18 +334,13 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Flammable, $"{ToPrettyString(uid):target} set on fire by {ToPrettyString(ignitionSource):actor}");
flammable.OnFire = true;
//CrystallPunk bonfire moment
//CrystallPunk fireplace moment
var ev = new OnFireChangedEvent(flammable.OnFire);
RaiseLocalEvent(uid, ref ev);
//CrystallPunk bonfire moment end
//CrystallPunk fireplace moment end
}
UpdateAppearance(uid, flammable);
//CrystallPunk bonfire moment
if (flammable.FirestackFadeOnIgnite != null)
flammable.FirestackFade = flammable.FirestackFadeOnIgnite.Value;
//CrystallPunk bonfire moment end
}
private void OnDamageChanged(EntityUid uid, IgniteOnHeatDamageComponent component, DamageChangedEvent args)
@@ -458,11 +453,6 @@ namespace Content.Server.Atmos.EntitySystems
_damageableSystem.TryChangeDamage(uid, flammable.Damage * flammable.FireStacks, interruptsDoAfters: false);
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
//CrystallPunk bonfire moment
if (flammable.FirestackFadeFade != 0)
flammable.FirestackFade += flammable.FirestackFadeFade * frameTime;
//CrystallPunk bonfire moment end
}
else
{

View File

@@ -50,12 +50,12 @@ public sealed class EntityHeaterSystem : EntitySystem
//CrystallPunk bonfire
var flammbaleQuery = EntityQueryEnumerator<CP14FlammableEntityHeaterComponent, ItemPlacerComponent, FlammableComponent>();
while (flammbaleQuery.MoveNext(out var uid, out _, out var placer, out var flammable))
while (flammbaleQuery.MoveNext(out var uid, out var heater, out var placer, out var flammable))
{
if (!flammable.OnFire)
return;
var energy = flammable.FireStacks * deltaTime * 300;
var energy = flammable.FireStacks * deltaTime * heater.EnergyPerFireStack;
foreach (var ent in placer.PlacedEntities)
{
_temperature.ChangeHeat(ent, energy);

View File

@@ -8,4 +8,6 @@ namespace Content.Server._CP14.Temperature;
[RegisterComponent, Access(typeof(EntityHeaterSystem))]
public sealed partial class CP14FlammableEntityHeaterComponent : Component
{
[DataField]
public float EnergyPerFireStack = 1000f;
}

View File

@@ -0,0 +1,51 @@
namespace Content.Server._CP14.Temperature.Fireplace;
/// <summary>
/// component for player-controlled fire. Can be fueled.
/// </summary>
[RegisterComponent, Access(typeof(CP14FireplaceSystem))]
public sealed partial class CP14FireplaceComponent : Component
{
/// <summary>
/// The abstract amount of fuel that is used to keep a fire burning
/// </summary>
[DataField]
public float MaxFuelLimit = 100f;
/// <summary>
/// how much the flame grows or dies out with the presence or absence of fuel
/// </summary>
[DataField]
public float FireFadeDelta = 0.2f;
/// <summary>
/// current fuel quantity
/// </summary>
[DataField]
public float CurrentFuel;
/// <summary>
/// how much fuel is wasted every "UpdateFrequency"
/// </summary>
[DataField]
public float FuelDrainingPerUpdate = 1f;
[DataField]
public TimeSpan UpdateFrequency = TimeSpan.FromSeconds(2f);
/// <summary>
/// whether fuel can be added by hand
/// </summary>
[DataField]
public bool CanInsertByHand = true;
/// <summary>
/// whether the fuel can be supplied by contact
/// </summary>
[DataField]
public bool CanInsertByCollide = false;
[DataField]
public TimeSpan NextUpdateTime = TimeSpan.Zero;
}

View File

@@ -0,0 +1,20 @@
using Robust.Shared.Audio;
namespace Content.Server._CP14.Temperature.Fireplace;
/// <summary>
/// Allows this object to be used as fuel for a fireplace
/// </summary>
[RegisterComponent, Access(typeof(CP14FireplaceSystem))]
public sealed partial class CP14FireplaceFuelComponent : Component
{
/// <summary>
/// How much fuel will be added in fireplace
/// </summary>
[DataField]
public float Fuel = 10f;
[DataField]
public SoundSpecifier InsertFuelSound = new SoundPathSpecifier("/Audio/_CP14/Items/campfire_whoosh.ogg");
}

View File

@@ -0,0 +1,128 @@
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Popups;
using Content.Shared._CP14.Temperature;
using Content.Shared.Interaction;
using Content.Shared.Throwing;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Physics.Events;
using Robust.Shared.Timing;
namespace Content.Server._CP14.Temperature.Fireplace;
public sealed partial class CP14FireplaceSystem : EntitySystem
{
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly FlammableSystem _flammable = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14FireplaceComponent, OnFireChangedEvent>(OnFireChanged);
SubscribeLocalEvent<CP14FireplaceComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<CP14FireplaceComponent, StartCollideEvent>(OnCollide);
}
private void OnFireChanged(Entity<CP14FireplaceComponent> fireplace, ref OnFireChangedEvent args)
{
if (!TryComp<FlammableComponent>(fireplace, out var flammable))
return;
if (args.OnFire)
flammable.FirestackFade = 0;
}
private void OnInteractUsing(Entity<CP14FireplaceComponent> fireplace, ref InteractUsingEvent args)
{
if (!fireplace.Comp.CanInsertByHand)
return;
if (!TryComp<CP14FireplaceFuelComponent>(args.Used, out var fuel))
return;
TryInsertFuel(fireplace, args.Used, fuel);
}
private void OnCollide(Entity<CP14FireplaceComponent> fireplace, ref StartCollideEvent args)
{
if (!fireplace.Comp.CanInsertByCollide)
return;
if (!TryComp<CP14FireplaceFuelComponent>(args.OtherEntity, out var fuel))
return;
TryInsertFuel(fireplace, args.OtherEntity, fuel);
}
private bool TryInsertFuel(Entity<CP14FireplaceComponent> fireplace, EntityUid fuelUid, CP14FireplaceFuelComponent fuel)
{
if (fireplace.Comp.CurrentFuel > fireplace.Comp.MaxFuelLimit)
{
_popupSystem.PopupEntity(Loc.GetString("cp14-fireplace-full", ("target", fireplace)), fireplace);
return false;
}
if (!TryComp<FlammableComponent>(fireplace, out var flammable))
return false;
fireplace.Comp.CurrentFuel += fuel.Fuel;
if (flammable.OnFire)
_audio.PlayPvs(fuel.InsertFuelSound, fireplace);
UpdateAppearance(fireplace, fireplace.Comp);
QueueDel(fuelUid);
return true;
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = AllEntityQuery<CP14FireplaceComponent, FlammableComponent>();
while (query.MoveNext(out var uid, out var fireplace, out var flammable))
{
if (!flammable.OnFire)
continue;
if (_timing.CurTime <= fireplace.NextUpdateTime)
continue;
fireplace.NextUpdateTime = _timing.CurTime + fireplace.UpdateFrequency;
if (fireplace.CurrentFuel >= fireplace.FuelDrainingPerUpdate)
{
fireplace.CurrentFuel -= fireplace.FuelDrainingPerUpdate;
UpdateAppearance(uid, fireplace);
flammable.FirestackFade = fireplace.FireFadeDelta;
}
else
{
flammable.FirestackFade = -fireplace.FireFadeDelta;
}
}
}
public void UpdateAppearance(EntityUid uid, CP14FireplaceComponent? fireplace = null, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref fireplace, ref appearance))
return;
if (fireplace.CurrentFuel < fireplace.FuelDrainingPerUpdate)
{
_appearance.SetData(uid, FireplaceFuelVisuals.Status, FireplaceFuelStatus.Empty, appearance);
return;
}
if (fireplace.CurrentFuel < fireplace.MaxFuelLimit / 2)
_appearance.SetData(uid, FireplaceFuelVisuals.Status, FireplaceFuelStatus.Medium, appearance);
else
_appearance.SetData(uid, FireplaceFuelVisuals.Status, FireplaceFuelStatus.Full, appearance);
}
}