Skip to content

Commit

Permalink
Spider queen antag v0.3 (SerbiaStrong-220#2162)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirus59 authored Nov 25, 2024
1 parent f0ef91a commit 4f8c7d8
Show file tree
Hide file tree
Showing 29 changed files with 634 additions and 252 deletions.
51 changes: 51 additions & 0 deletions Content.Server/SS220/Atmos/ItemGasSpawnerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Atmos;

namespace Content.Server.SS220.Atmos;

[RegisterComponent, Access(typeof(ItemGasSpawnerSystem))]
public sealed partial class ItemGasSpawnerComponent : Component
{
/// <summary>
/// If the number of moles in the external environment exceeds this number, no gas will be spawned.
/// </summary>
[DataField]
public float MaxExternalAmount = float.PositiveInfinity;

/// <summary>
/// If the pressure (in kPA) of the external environment exceeds this number, no gas will be spawned.
/// </summary>
[DataField]
public float MaxExternalPressure = 101.325f;

/// <summary>
/// Gas to spawn.
/// </summary>
[DataField(required: true)]
public Gas SpawnGas;

/// <summary>
/// Temperature in Kelvin.
/// </summary>
[DataField]
public float SpawnTemperature = Atmospherics.T20C;

/// <summary>
/// Number of moles created per second.
/// </summary>
[DataField]
public float SpawnAmount = Atmospherics.MolesCellStandard * 20f;

/// <summary>
/// Is spawn limited?
/// </summary>
[DataField]
public bool LimitedSpawn = false;

/// <summary>
/// How much moles of gas can be spawned.
/// Didn't decrease if <see cref="LimitedSpawn"/> is false.
/// </summary>
[DataField("amountToSpawn")]
public float RemainingAmountToSpawn = 500f;
}
71 changes: 71 additions & 0 deletions Content.Server/SS220/Atmos/ItemGasSpawnerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Robust.Server.GameObjects;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;

namespace Content.Server.SS220.Atmos;

public sealed partial class ItemGasSpawnerSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly TransformSystem _transform = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<ItemGasSpawnerComponent>();
while (query.MoveNext(out var uid, out var comp))
{
var isLimitReached = comp.LimitedSpawn && comp.RemainingAmountToSpawn <= 0;
if (isLimitReached ||
!GetValidEnvironment(uid, comp, out var environment))
continue;

var toSpawn = CapSpawnAmount(uid, comp, comp.SpawnAmount * frameTime, environment);
if (toSpawn <= 0)
continue;

var merger = new GasMixture(1) { Temperature = comp.SpawnTemperature };
merger.SetMoles(comp.SpawnGas, toSpawn);
_atmosphere.Merge(environment, merger);

if (comp.LimitedSpawn)
comp.RemainingAmountToSpawn = MathF.Max(0, comp.RemainingAmountToSpawn - toSpawn);
}
}

private bool GetValidEnvironment(EntityUid uid, ItemGasSpawnerComponent component, [NotNullWhen(true)] out GasMixture? environment)
{
var transform = Transform(uid);
var position = _transform.GetGridOrMapTilePosition(uid, transform);

// Treat space as an invalid environment
if (_atmosphere.IsTileSpace(transform.GridUid, transform.MapUid, position))
{
environment = null;
return false;
}

environment = _atmosphere.GetContainingMixture((uid, transform), true, true);
return environment != null;
}

private float CapSpawnAmount(EntityUid uid, ItemGasSpawnerComponent component, float toSpawnTarget, GasMixture environment)
{
// How many moles could we theoretically spawn. Cap by pressure and amount.
var allowableMoles = Math.Min(
(component.MaxExternalPressure - environment.Pressure) * environment.Volume / (component.SpawnTemperature * Atmospherics.R),
component.MaxExternalAmount - environment.TotalMoles);

var toSpawnReal = Math.Clamp(allowableMoles, 0f, toSpawnTarget);

if (toSpawnReal < Atmospherics.GasMinMoles)
return 0f;

return toSpawnReal;
}
}
26 changes: 26 additions & 0 deletions Content.Server/SS220/SpiderQueen/Components/SpiderEggComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Storage;

namespace Content.Server.SS220.SpiderQueen.Components;

[RegisterComponent]
public sealed partial class SpiderEggComponent : Component
{
/// <summary>
/// The entity that spawned egg
/// </summary>
[DataField]
public EntityUid? EggOwner;

/// <summary>
/// Egg incubation time
/// </summary>
[DataField(required: true)]
public float IncubationTime;

/// <summary>
/// A list of prototypes that will be spawn after the incubation time
/// </summary>
[DataField(required: true)]
public List<EntitySpawnEntry> SpawnProtos;
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,10 @@ private void OnExtractBloodPoints(Entity<SpiderCocoonComponent> entity, ref Coco
var amountToMax = spiderQueen.MaxBloodPoints - spiderQueen.CurrentBloodPoints;
var extractedValue = MathF.Min((float)amountToMax, (float)entity.Comp.BloodPointsAmount);
entity.Comp.BloodPointsAmount -= extractedValue;
spiderQueen.CurrentBloodPoints += extractedValue;
_spiderQueen.ChangeBloodPointsAmount(args.User, spiderQueen, extractedValue);

_hunger.ModifyHunger(args.User, extractedValue * spiderQueen.HungerExtractCoefficient);

Dirty(args.User, spiderQueen);
Dirty(entity);
_spiderQueen.UpdateAlert((args.User, spiderQueen));
}

/// <summary>
Expand Down
45 changes: 45 additions & 0 deletions Content.Server/SS220/SpiderQueen/Systems/SpiderEggSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Server.NPC;
using Content.Server.NPC.Systems;
using Content.Server.SS220.SpiderQueen.Components;
using Content.Shared.Storage;
using Robust.Shared.Map;
using Robust.Shared.Random;
using System.Numerics;

namespace Content.Server.SS220.SpiderQueen.Systems;

public sealed partial class SpiderEggSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly NPCSystem _npc = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<SpiderEggComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.IncubationTime -= frameTime;
if (comp.IncubationTime > 0)
continue;

SpawnProtos(uid, comp);
QueueDel(uid);
}
}

private void SpawnProtos(EntityUid uid, SpiderEggComponent component)
{
var protos = EntitySpawnCollection.GetSpawns(component.SpawnProtos, _random);
var coordinates = Transform(uid).Coordinates;

foreach (var proto in protos)
{
var ent = Spawn(proto, coordinates);
if (component.EggOwner is { } owner)
_npc.SetBlackboard(ent, NPCBlackboard.FollowTarget, new EntityCoordinates(owner, Vector2.Zero));
}
}
}
Loading

0 comments on commit 4f8c7d8

Please sign in to comment.