mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-29 19:47:48 +03:00
Ports Blob from https://github.com/Goob-Station/Goob-Station/pull/975 that was ported from https://github.com/Rxup/space-station-14. Credit to VigersRay for original code, Roudenn and Rxup for maintaining and jorgun for the Goob port. --- - [X] Port https://github.com/Goob-Station/Goob-Station/pull/975; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/1209; - [X] Port Blob related code from https://github.com/Goob-Station/Goob-Station/pull/1262; - [X] Port Blob related code from https://github.com/Goob-Station/Goob-Station/pull/1340; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/1408; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/1419; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/1440; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/1817; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/2077; - [ ] ~Port https://github.com/Goob-Station/Goob-Station/pull/1916~; - [ ] ~Port https://github.com/Goob-Station/Goob-Station/pull/1917~; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/2077; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/2092; - [X] Port https://github.com/Goob-Station/Goob-Station/pull/2546; - [X] Port https://github.com/Rxup/space-station-14/pull/963; - [X] Port https://github.com/Rxup/space-station-14/pull/998; - [ ] ~Port https://github.com/Goob-Station/Goob-Station/pull/2563~. - [X] Enable Blob and Blob gamemode; - [X] Add `StationGlobConfig` to all stations; - [X] Use `AnnouncerSystem` in `BlobRuleSystem.cs`; - [X] Blob language and Hivemind (from https://github.com/Rxup/space-station-14/pull/176); - [x] Change CVars location; - [X] Add media. --- <details><summary><h1>Media</h1></summary> <p> https://youtu.be/-WtMQwRcmrU?si=su3An6RtiCTZg-DV </p> </details> --- 🆑 VigersRay, Roudenn, Rxup, vladospupuos, fishbait and Kyoth25f - add: Added a new antagonist: Blob --------- Co-authored-by: fishbait <gnesse@gmail.com> Co-authored-by: Fishbait <Fishbait@git.ml> Co-authored-by: Aiden <aiden@djkraz.com> Co-authored-by: beck-thompson <107373427+beck-thompson@users.noreply.github.com> Co-authored-by: lanse12 <cloudability.ez@gmail.com> Co-authored-by: BombasterDS <deniskaporoshok@gmail.com> Co-authored-by: Aviu00 <93730715+Aviu00@users.noreply.github.com> Co-authored-by: Piras314 <p1r4s@proton.me> Co-authored-by: shibe <95730644+shibechef@users.noreply.github.com> Co-authored-by: Ilya246 <57039557+Ilya246@users.noreply.github.com> Co-authored-by: JohnOakman <sremy2012@hotmail.fr> Co-authored-by: Fat Engineer Gaming <159075414+Fat-Engineer-Gaming@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Rouden <149893554+Roudenn@users.noreply.github.com>
186 lines
6.3 KiB
C#
186 lines
6.3 KiB
C#
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Content.Shared._Goobstation.Blob.Components;
|
|
using Content.Shared.Destructible;
|
|
using Content.Shared.Mobs.Systems;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Shared.CPUJob.JobQueues;
|
|
using Robust.Shared.CPUJob.JobQueues.Queues;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Player;
|
|
using Robust.Shared.Random;
|
|
|
|
namespace Content.Server._Goobstation.Blob.Systems;
|
|
|
|
public sealed class BlobNodeSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
|
[Dependency] private readonly MapSystem _map = default!;
|
|
[Dependency] private readonly IRobustRandom _random = default!;
|
|
[Dependency] private readonly BlobCoreSystem _blobCoreSystem = default!;
|
|
[Dependency] private readonly MobStateSystem _mob = default!;
|
|
|
|
private EntityQuery<BlobTileComponent> _tileQuery;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<BlobNodeComponent, DestructionEventArgs>(OnDestruction);
|
|
SubscribeLocalEvent<BlobNodeComponent, EntityTerminatingEvent>(OnTerminating);
|
|
SubscribeLocalEvent<BlobNodeComponent, BlobNodePulseEvent>(OnNodePulse);
|
|
|
|
_tileQuery = GetEntityQuery<BlobTileComponent>();
|
|
}
|
|
|
|
private void OnNodePulse(Entity<BlobNodeComponent> ent, ref BlobNodePulseEvent args)
|
|
{
|
|
var xform = Transform(ent);
|
|
|
|
var evSpecial = new BlobSpecialGetPulseEvent();
|
|
foreach (var special in GetSpecialBlobsTiles(ent))
|
|
{
|
|
RaiseLocalEvent(special, evSpecial);
|
|
}
|
|
|
|
foreach (var lookupUid in _lookup.GetEntitiesInRange<BlobMobComponent>(xform.Coordinates, ent.Comp.PulseRadius))
|
|
{
|
|
if(_mob.IsDead(lookupUid))
|
|
continue;
|
|
var evMob = new BlobMobGetPulseEvent
|
|
{
|
|
BlobEntity = GetNetEntity(lookupUid),
|
|
};
|
|
RaiseLocalEvent(lookupUid, evMob);
|
|
RaiseNetworkEvent(evMob, Filter.Pvs(lookupUid));
|
|
}
|
|
}
|
|
|
|
private const double PulseJobTime = 0.005;
|
|
private readonly JobQueue _pulseJobQueue = new(PulseJobTime);
|
|
|
|
public sealed class BlobPulse(
|
|
BlobNodeSystem system,
|
|
Entity<BlobNodeComponent> ent,
|
|
double maxTime,
|
|
CancellationToken cancellation = default)
|
|
: Job<object>(maxTime, cancellation)
|
|
{
|
|
protected override async Task<object?> Process()
|
|
{
|
|
system.Pulse(ent);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void OnTerminating(EntityUid uid, BlobNodeComponent component, ref EntityTerminatingEvent args)
|
|
{
|
|
OnDestruction(uid, component, new DestructionEventArgs());
|
|
}
|
|
|
|
private IEnumerable<Entity<BlobTileComponent>> GetSpecialBlobsTiles(BlobNodeComponent component)
|
|
{
|
|
if (!TerminatingOrDeleted(component.BlobFactory) && _tileQuery.TryComp(component.BlobFactory, out var tileFactoryComponent))
|
|
{
|
|
yield return (component.BlobFactory.Value, tileFactoryComponent);
|
|
}
|
|
if (!TerminatingOrDeleted(component.BlobResource) && _tileQuery.TryComp(component.BlobResource, out var tileResourceComponent))
|
|
{
|
|
yield return (component.BlobResource.Value, tileResourceComponent);
|
|
}
|
|
if (!TerminatingOrDeleted(component.BlobStorage) && _tileQuery.TryComp(component.BlobStorage, out var tileStorageComponent))
|
|
{
|
|
yield return (component.BlobStorage.Value, tileStorageComponent);
|
|
}
|
|
if (!TerminatingOrDeleted(component.BlobTurret) && _tileQuery.TryComp(component.BlobTurret, out var tileTurretComponent))
|
|
{
|
|
yield return (component.BlobTurret.Value, tileTurretComponent);
|
|
}
|
|
}
|
|
|
|
private void OnDestruction(EntityUid uid, BlobNodeComponent component, DestructionEventArgs args)
|
|
{
|
|
if (!_tileQuery.TryGetComponent(uid, out var tileComp) ||
|
|
tileComp.BlobTileType != BlobTileType.Node ||
|
|
tileComp.Core == null)
|
|
return;
|
|
|
|
foreach (var tile in GetSpecialBlobsTiles(component))
|
|
{
|
|
tile.Comp.ReturnCost = false;
|
|
_blobCoreSystem.RemoveTileWithReturnCost(tile, tile.Comp.Core!.Value);
|
|
}
|
|
}
|
|
|
|
private void Pulse(Entity<BlobNodeComponent> ent)
|
|
{
|
|
if (TerminatingOrDeleted(ent) || !EntityManager.TransformQuery.TryComp(ent, out var xform))
|
|
return;
|
|
|
|
var radius = ent.Comp.PulseRadius;
|
|
|
|
var localPos = xform.Coordinates.Position;
|
|
|
|
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_tileQuery.TryGetComponent(ent, out var blobTileComponent) || blobTileComponent.Core == null)
|
|
return;
|
|
|
|
var innerTiles = _map.GetLocalTilesIntersecting(xform.GridUid.Value,
|
|
grid,
|
|
new Box2(localPos + new Vector2(-radius, -radius), localPos + new Vector2(radius, radius)),
|
|
false)
|
|
.ToArray();
|
|
|
|
_random.Shuffle(innerTiles);
|
|
|
|
var explain = true;
|
|
foreach (var tileRef in innerTiles)
|
|
{
|
|
foreach (var tile in _map.GetAnchoredEntities(xform.GridUid.Value, grid, tileRef.GridIndices))
|
|
{
|
|
if (!_tileQuery.HasComponent(tile))
|
|
continue;
|
|
|
|
var ev = new BlobTileGetPulseEvent
|
|
{
|
|
Handled = explain
|
|
};
|
|
RaiseLocalEvent(tile, ev);
|
|
explain = false; // WTF?
|
|
}
|
|
}
|
|
|
|
RaiseLocalEvent(ent, new BlobNodePulseEvent());
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
_pulseJobQueue.Process();
|
|
|
|
var blobNodeQuery = EntityQueryEnumerator<BlobNodeComponent, BlobTileComponent>();
|
|
while (blobNodeQuery.MoveNext(out var ent, out var comp, out var blobTileComponent))
|
|
{
|
|
comp.NextPulse += frameTime;
|
|
if (comp.PulseFrequency > comp.NextPulse)
|
|
continue;
|
|
|
|
comp.NextPulse -= comp.PulseFrequency;
|
|
|
|
if (blobTileComponent.Core == null)
|
|
{
|
|
QueueDel(ent);
|
|
continue;
|
|
}
|
|
_pulseJobQueue.EnqueueJob(new BlobPulse(this,(ent, comp), PulseJobTime));
|
|
}
|
|
}
|
|
}
|