admin demiplanes catcher (#835)

This commit is contained in:
Ed
2025-02-02 15:24:34 +03:00
committed by GitHub
parent 445fd1e1b9
commit 3437830a78
3 changed files with 71 additions and 10 deletions

View File

@@ -110,11 +110,11 @@ public sealed partial class CP14DemiplaneSystem
/// <summary>
/// Generates a new random demiplane based on the specified parameters
/// </summary>
public void SpawnRandomDemiplane(ProtoId<CP14DemiplaneLocationPrototype> location, List<ProtoId<CP14DemiplaneModifierPrototype>> modifiers, out Entity<CP14DemiplaneComponent> demiplan, out MapId mapId)
public void SpawnRandomDemiplane(ProtoId<CP14DemiplaneLocationPrototype> location, List<ProtoId<CP14DemiplaneModifierPrototype>> modifiers, out Entity<CP14DemiplaneComponent>? demiplane, out MapId mapId)
{
var mapUid = _mapSystem.CreateMap(out mapId, runMapInit: false);
var demiComp = EntityManager.EnsureComponent<CP14DemiplaneComponent>(mapUid);
demiplan = (mapUid, demiComp);
demiplane = (mapUid, demiComp);
var cancelToken = new CancellationTokenSource();
var job = new CP14SpawnRandomDemiplaneJob(
@@ -139,27 +139,43 @@ public sealed partial class CP14DemiplaneSystem
private void GeneratorUsedInHand(Entity<CP14DemiplaneGeneratorDataComponent> generator, ref UseInHandEvent args)
{
if (generator.Comp.Location is null)
return;
//block the opening of demiplanes after the end of a round
if (_gameTicker.RunLevel != GameRunLevel.InRound)
{
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open-end-round"), generator, args.User);
return;
}
//We cant open demiplan in another demiplan or if parent is not Map
//We cant open demiplane in another demiplane or if parent is not Map
if (HasComp<CP14DemiplaneComponent>(Transform(generator).MapUid) || !HasComp<MapGridComponent>(_transform.GetParentUid(args.User)))
{
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open", ("name", MetaData(generator).EntityName)), generator, args.User);
return;
}
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.SelectedModifiers, out var demiplane, out var mapId);
if (generator.Comp.Location is null)
return;
//an attempt to open demiplanes can be intercepted by other systems that substitute a map instead of generating the planned demiplane.
Entity<CP14DemiplaneComponent>? demiplane = null;
var ev = new CP14DemiplaneGenerationCatchAttemptEvent();
RaiseLocalEvent(ev);
if (ev.Demiplane is null)
{
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.SelectedModifiers, out demiplane, out var mapId);
}
else
{
demiplane = ev.Demiplane;
}
_statistic.TrackAdd(generator.Comp.Statistic, 1);
if (demiplane is null)
return;
//Admin log needed
EnsureComp<CP14DemiplaneDestroyWithoutStabilizationComponent>(demiplane);
EnsureComp<CP14DemiplaneDestroyWithoutStabilizationComponent>(demiplane.Value);
//Ура, щиткод и магические переменные!
var tempRift = EntityManager.Spawn("CP14DemiplaneTimedRadiusPassway");
@@ -169,8 +185,8 @@ public sealed partial class CP14DemiplaneSystem
var connection = EnsureComp<CP14DemiplaneRiftComponent>(tempRift);
var connection2 = EnsureComp<CP14DemiplaneRiftComponent>(tempRift2);
AddDemiplanRandomExitPoint(demiplane, (tempRift, connection));
AddDemiplanRandomExitPoint(demiplane, (tempRift2, connection2));
AddDemiplanRandomExitPoint(demiplane.Value, (tempRift, connection));
AddDemiplanRandomExitPoint(demiplane.Value, (tempRift2, connection2));
#if !DEBUG
QueueDel(generator); //wtf its crash debug build!
@@ -370,3 +386,9 @@ public sealed partial class CP14DemiplaneSystem
throw new InvalidOperationException($"Invalid weighted pick in CP14DemiplanSystem.Generation!");
}
}
public sealed class CP14DemiplaneGenerationCatchAttemptEvent : EntityEventArgs
{
public bool Handled = false;
public Entity<CP14DemiplaneComponent>? Demiplane;
}

View File

@@ -0,0 +1,30 @@
using Content.Server._CP14.Demiplane;
using Content.Shared._CP14.Demiplane.Components;
using Robust.Shared.Map.Components;
namespace Content.Server._CP14.DemiplaneAdmin;
public sealed partial class CP14DemiplaneAdminSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14DemiplaneGenerationCatchAttemptEvent>(OnAdminDemiplaneCatch);
}
private void OnAdminDemiplaneCatch(CP14DemiplaneGenerationCatchAttemptEvent ev)
{
if (ev.Handled)
return;
var query = EntityQueryEnumerator<CP14DemiplaneRiftCatcherComponent, MapComponent, CP14DemiplaneComponent>();
while (query.MoveNext(out var uid, out var catcher, out var map, out var demiplane))
{
ev.Demiplane = (uid, demiplane);
ev.Handled = true;
RemCompDeferred(uid, catcher);
return;
}
}
}

View File

@@ -0,0 +1,9 @@
namespace Content.Server._CP14.DemiplaneAdmin;
/// <summary>
/// This demiplane can be added to a map by the admins, which will redirect the next opened demiplane key to that map
/// </summary>
[RegisterComponent]
public sealed partial class CP14DemiplaneRiftCatcherComponent : Component
{
}