Skip to content

Commit

Permalink
saves for later
Browse files Browse the repository at this point in the history
  • Loading branch information
M1and1B committed Jan 2, 2025
1 parent dba4b34 commit 7d168b1
Show file tree
Hide file tree
Showing 12 changed files with 610 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Content.Server.ADT.Spreader;

/// <summary>
/// Added to entities being considered for spreading via <see cref="SupermatterSpreaderSystem"/>.
/// This needs to be manually added and removed.
/// </summary>
[RegisterComponent]
public sealed partial class ActiveEdgeSupermatterSpreaderComponent : Component
{
}
14 changes: 14 additions & 0 deletions Content.Server/ADT/Spreader/EdgeSupermatterSpreaderComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Content.Shared.ADT.Spreader;
using Robust.Shared.Prototypes;

namespace Content.Server.ADT.Spreader;

/// <summary>
/// Entity capable of becoming cloning and replicating itself to adjacent edges. See <see cref="SupermatterSpreaderSystem"/>
/// </summary>
[RegisterComponent, Access(typeof(SupermatterSpreaderSystem))]
public sealed partial class EdgeSupermatterSpreaderComponent : Component
{
[DataField(required:true)]
public ProtoId<EdgeSupermatterSpreaderPrototype> Id;
}
14 changes: 14 additions & 0 deletions Content.Server/ADT/Spreader/GrowingSupermatterKudzuComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server.ADT.Spreader;

[RegisterComponent, Access(typeof(SupermatterKudzuSystem)), AutoGenerateComponentPause]
public sealed partial class GrowingSupermatterKudzuComponent : Component
{
/// <summary>
/// The next time kudzu will try to tick its growth level.
/// </summary>
[DataField("nextTick", customTypeSerializer:typeof(TimeOffsetSerializer))]
[AutoPausedField]
public TimeSpan NextTick = TimeSpan.Zero;
}
29 changes: 29 additions & 0 deletions Content.Server/ADT/Spreader/SupermatterKudzuComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Content.Server.ADT.Spreader;

/// <summary>
/// Handles entities that spread out when they reach the relevant growth level.
/// </summary>
[RegisterComponent]
public sealed partial class SupermatterKudzuComponent : Component
{
/// <summary>
/// At level 3 spreading can occur; prior to that we have a chance of increasing our growth level and changing our sprite.
/// </summary>
[DataField]
public int GrowthLevel = 1;

/// <summary>
/// Chance to spread whenever an edge spread is possible.
/// </summary>
[DataField]
public float SpreadChance = 1f;

[DataField]
public float GrowthTickChance = 1f;

/// <summary>
/// number of sprite variations for kudzu
/// </summary>
[DataField]
public int SpriteVariants = 3;
}
111 changes: 111 additions & 0 deletions Content.Server/ADT/Spreader/SupermatterKudzuSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Content.Shared.Damage;
using Content.Shared.ADT.Spreader;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Server.ADT.Spreader;

public sealed class SupermatterKudzuSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;

[ValidatePrototypeId<EdgeSupermatterSpreaderPrototype>]
private const string SupermatterKudzuGroup = "SupermatterKudzu";

/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<SupermatterKudzuComponent, ComponentStartup>(SetupKudzu);
SubscribeLocalEvent<SupermatterKudzuComponent, SupermatterSpreadNeighborsEvent>(OnKudzuSpread);
}

private void OnKudzuSpread(EntityUid uid, SupermatterKudzuComponent component, ref SupermatterSpreadNeighborsEvent args)
{
if (component.GrowthLevel < 3)
return;

if (args.NeighborFreeTiles.Count == 0)
{
RemCompDeferred<ActiveEdgeSupermatterSpreaderComponent>(uid);
return;
}

if (!_robustRandom.Prob(component.SpreadChance))
return;

var prototype = MetaData(uid).EntityPrototype?.ID;

if (prototype == null)
{
RemCompDeferred<ActiveEdgeSupermatterSpreaderComponent>(uid);
return;
}

foreach (var neighbor in args.NeighborFreeTiles)
{
var neighborUid = Spawn(prototype, _map.GridTileToLocal(neighbor.Tile.GridUid, neighbor.Grid, neighbor.Tile.GridIndices));
DebugTools.Assert(HasComp<EdgeSupermatterSpreaderComponent>(neighborUid));
DebugTools.Assert(HasComp<ActiveEdgeSupermatterSpreaderComponent>(neighborUid));
DebugTools.Assert(Comp<EdgeSupermatterSpreaderComponent>(neighborUid).Id == SupermatterKudzuGroup);
args.Updates--;
if (args.Updates <= 0)
return;
}
}

private void SetupKudzu(EntityUid uid, SupermatterKudzuComponent component, ComponentStartup args)
{
if (!EntityManager.TryGetComponent<AppearanceComponent>(uid, out var appearance))
{
return;
}

_appearance.SetData(uid, SupermatterKudzuVisuals.Variant, _robustRandom.Next(1, component.SpriteVariants), appearance);
_appearance.SetData(uid, SupermatterKudzuVisuals.GrowthLevel, 1, appearance);
}

/// <inheritdoc/>
public override void Update(float frameTime)
{
var appearanceQuery = GetEntityQuery<AppearanceComponent>();
var query = EntityQueryEnumerator<GrowingSupermatterKudzuComponent>();
var kudzuQuery = GetEntityQuery<SupermatterKudzuComponent>();
var curTime = _timing.CurTime;

while (query.MoveNext(out var uid, out var grow))
{
if (grow.NextTick > curTime)
continue;

grow.NextTick = curTime + TimeSpan.FromSeconds(0.5);

if (!kudzuQuery.TryGetComponent(uid, out var kudzu))
{
RemCompDeferred(uid, grow);
continue;
}

if (!_robustRandom.Prob(kudzu.GrowthTickChance))
{
continue;
}

kudzu.GrowthLevel += 1;

if (kudzu.GrowthLevel >= 3)
{
// why cache when you can simply cease to be? Also saves a bit of memory/time.
RemCompDeferred(uid, grow);
}

if (appearanceQuery.TryGetComponent(uid, out var appearance))
{
_appearance.SetData(uid, SupermatterKudzuVisuals.GrowthLevel, kudzu.GrowthLevel, appearance);
}
}
}
}
22 changes: 22 additions & 0 deletions Content.Server/ADT/Spreader/SupermatterSpreadNeighborsEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Robust.Shared.Collections;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;

namespace Content.Server.ADT.Spreader;

/// <summary>
/// Raised when trying to spread to neighboring tiles.
/// If the spread is no longer able to happen you MUST cancel this event!
/// </summary>
[ByRefEvent]
public record struct SupermatterSpreadNeighborsEvent
{
public ValueList<(MapGridComponent Grid, TileRef Tile)> NeighborFreeTiles;
public ValueList<EntityUid> Neighbors;

/// <summary>
/// How many updates allowed are remaining.
/// Subscribers can handle as they wish.
/// </summary>
public int Updates;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Content.Server.ADT.Spreader;

[RegisterComponent]
public sealed partial class SupermatterSpreaderGridComponent : Component
{
[DataField]
public float UpdateAccumulator = SupermatterSpreaderSystem.SpreadCooldownSeconds;
}
Loading

0 comments on commit 7d168b1

Please sign in to comment.