Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Content.Server.Ghost.Roles.Components;

[RegisterComponent]
[Access(typeof(GhostRoleSystem))]
//[Access(typeof(GhostRoleSystem))] // Goobstation edit - removed access
public sealed partial class GhostRoleComponent : Component
{
[DataField("name")] private string _roleName = "Unknown";
Expand Down
1 change: 1 addition & 0 deletions Content.Server/Ghost/Roles/GhostRoleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ private void OnSpawnerTakeRole(EntityUid uid, GhostRoleMobSpawnerComponent compo

var spawnedEvent = new GhostRoleSpawnerUsedEvent(uid, mob);
RaiseLocalEvent(mob, spawnedEvent);
RaiseLocalEvent(uid, spawnedEvent); // Goobstation edit

if (ghostRole.MakeSentient)
_mindSystem.MakeSentient(mob, ghostRole.AllowMovement, ghostRole.AllowSpeech);
Expand Down
22 changes: 19 additions & 3 deletions Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Goobstation.Common.Spawner;
using Content.Server.GameTicking;
using Content.Server.Spawners.Components;
using Content.Shared.EntityTable;
Expand Down Expand Up @@ -99,7 +100,12 @@ private void Spawn(EntityUid uid, ConditionalSpawnerComponent component)
var coords = _xform.GetMapCoordinates(uid, xform);
var rotation = _xform.GetWorldRotation(xform);

Spawn(_robustRandom.Pick(component.Prototypes), coords, rotation: rotation);
var spawned = Spawn(_robustRandom.Pick(component.Prototypes), coords, rotation: rotation); // Goobstation edit - saved in variable

// Goobstation edit start
var spawnedEv = new SpawnerActivationEvent(spawned);
RaiseLocalEvent(uid, ref spawnedEv);
// Goobstation edit end
}

private void Spawn(EntityUid uid, RandomSpawnerComponent component)
Expand All @@ -117,7 +123,12 @@ private void Spawn(EntityUid uid, RandomSpawnerComponent component)
var coords = _xform.GetMapCoordinates(uid, xform).Offset(vOffset);
var rotation = _xform.GetWorldRotation(xform);

Spawn(proto, coords, rotation: rotation);
var spawned = Spawn(proto, coords, rotation: rotation); // Goobstation edit - saved in variable

// Goobstation edit start
var spawnedEv = new SpawnerActivationEvent(spawned);
RaiseLocalEvent(uid, ref spawnedEv);
// Goobstation edit end
}

private EntProtoId? GetPrototype(Entity<RandomSpawnerComponent> spawner)
Expand Down Expand Up @@ -168,7 +179,12 @@ private void Spawn(Entity<EntityTableSpawnerComponent> ent)
var vOffset = _robustRandom.NextVector2(-offset, offset);
var trueCoords = coords.Offset(vOffset);

Spawn(proto, trueCoords, rotation: rotation);
var spawned = Spawn(proto, trueCoords, rotation: rotation); // Goobstation edit - saved in variable

// Goobstation edit start
var spawnedEv = new SpawnerActivationEvent(spawned);
RaiseLocalEvent(ent.Owner, ref spawnedEv);
// Goobstation edit end
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion Content.Server/Spawners/EntitySystems/SpawnerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Goobstation.Common.Spawner;
using Content.Server.Spawners.Components;
using Robust.Shared.Random;
using Robust.Shared.Timing;
Expand Down Expand Up @@ -49,7 +50,12 @@ private void OnTimerFired(EntityUid uid, TimedSpawnerComponent component)
for (var i = 0; i < number; i++)
{
var entity = _random.Pick(component.Prototypes);
SpawnAtPosition(entity, coordinates);
var spawned = SpawnAtPosition(entity, coordinates); // Goobstation edit - saved in variable

// Goobstation edit start
var spawnedEv = new SpawnerActivationEvent(spawned);
RaiseLocalEvent(uid, ref spawnedEv);
// Goobstation edit end
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Shared.EntityTable.EntitySelectors;
using Robust.Shared.Prototypes;

namespace Content.Shared.Ghost.Roles.Components
Expand Down
1 change: 1 addition & 0 deletions Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ private bool CanTrigger(EntityUid uid, EntityUid otherUid, StepTriggerComponent
var msg = new StepTriggerAttemptEvent { Source = uid, Tripper = otherUid };

RaiseLocalEvent(uid, ref msg);
RaiseLocalEvent(otherUid, ref msg); // Goobstation edit

return msg.Continue && !msg.Cancelled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ public bool IsOpen(EntityUid target, EntityStorageComponent? component = null)

public bool CanOpen(EntityUid user, EntityUid target, bool silent = false, EntityStorageComponent? component = null)
{
if (!Resolve(target, ref component))
if (!Resolve(target, ref component, false)) // Goobstation edit - suppress error
return false;

if (!HasComp<HandsComponent>(user))
Expand Down
19 changes: 15 additions & 4 deletions Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Goobstation.Common.Spawner;
using Content.Shared.GameTicking;
using Content.Shared.Trigger.Components.Effects;
using Content.Shared.Trigger.Components.Triggers;
Expand Down Expand Up @@ -68,13 +69,15 @@ private void HandleSpawnTableOnTrigger(Entity<SpawnEntityTableOnTriggerComponent
/// <param name="predicted">Whether to use predicted spawning.</param>
private void SpawnTriggerHelper(Entity<TransformComponent> target, EntProtoId proto, bool useMapCoords, bool predicted)
{
EntityUid? spawned = null; // Goobstation edit - saved in variable

if (useMapCoords)
{
var mapCoords = _transform.GetMapCoordinates(target);
if (predicted)
EntityManager.PredictedSpawn(proto, mapCoords);
spawned = EntityManager.PredictedSpawn(proto, mapCoords); // Goobstation edit - saved in variable
else if (_net.IsServer)
Spawn(proto, mapCoords);
spawned = Spawn(proto, mapCoords); // Goobstation edit - saved in variable
}

else
Expand All @@ -84,10 +87,18 @@ private void SpawnTriggerHelper(Entity<TransformComponent> target, EntProtoId pr
return;

if (predicted)
PredictedSpawnAttachedTo(proto, coords);
spawned = PredictedSpawnAttachedTo(proto, coords); // Goobstation edit - saved in variable
else if (_net.IsServer)
SpawnAttachedTo(proto, coords);
spawned = SpawnAttachedTo(proto, coords); // Goobstation edit - saved in variable
}

// Goobstation edit start
if (spawned == null)
return;

var spawnedEv = new SpawnerActivationEvent(spawned.Value);
RaiseLocalEvent(target.Owner, ref spawnedEv);
// Goobstation edit end
}

private void HandleDeleteOnTrigger(Entity<DeleteOnTriggerComponent> ent, ref TriggerEvent args)
Expand Down
7 changes: 7 additions & 0 deletions Content.Shared/Trigger/Systems/TriggerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Goobstation.Common.Trigger;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.DeviceLinking;
Expand Down Expand Up @@ -78,6 +79,12 @@ public bool Trigger(EntityUid trigger, EntityUid? user = null, string? key = nul

var triggerEvent = new TriggerEvent(user, key, predicted);
RaiseLocalEvent(trigger, ref triggerEvent, true);

// Goobstation edit start
var afterTriggerEvent = new AfterTriggerEvent(user, key, predicted, triggerEvent.Handled);
RaiseLocalEvent(trigger, ref afterTriggerEvent, true);
// Goobstation edit end

return triggerEvent.Handled;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Content.Goobstation.Client.CombatMode;

public enum CombatModeVisuals
{
Combat,
Layer,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Goobstation.Client.CombatMode;

[RegisterComponent]
public sealed partial class CombatModeVisualsComponent : Component;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared.CombatMode;

namespace Content.Goobstation.Client.CombatMode;

public sealed partial class CombatModeVisualsSystem : EntitySystem
{
[Dependency] private SharedAppearanceSystem _appearance = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CombatModeVisualsComponent, ToggleCombatActionEvent>(OnCombatToggle);
SubscribeLocalEvent<CombatModeVisualsComponent, ComponentStartup>(OnCombatStartup);
}

private void OnCombatToggle(Entity<CombatModeVisualsComponent> ent, ref ToggleCombatActionEvent args)
=> UpdateAppearance(ent.Owner);

private void OnCombatStartup(Entity<CombatModeVisualsComponent> ent, ref ComponentStartup args)
=> UpdateAppearance(ent.Owner);

private void UpdateAppearance(EntityUid uid)
{
if (!TryComp<CombatModeComponent>(uid, out var combat))
return;

_appearance.SetData(uid, CombatModeVisuals.Combat, combat.IsInCombatMode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Content.Goobstation.Common.Spawner;

/// <summary>
/// Raised after an entity was spawned from any sort of spawner.
/// </summary>
/// <param name="Spawned"></param>
[ByRefEvent]
public record struct SpawnerActivationEvent(EntityUid Spawned);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Goobstation.Common.Trigger;

[ByRefEvent]
public record struct AfterTriggerEvent(EntityUid? User = null, string? Key = null, bool Predicted = true, bool Handled = false);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Content.Shared.EntityTable.EntitySelectors;

namespace Content.Goobstation.Server.Spawner;

/// <summary>
/// A version of <see cref="GhostRoleTableSpawnerComponent"/> that supports <see cref="EntityTableSelector"/>.
/// </summary>
[RegisterComponent]
public sealed partial class GhostRoleTableSpawnerComponent : Component
{
[DataField]
public EntityTableSelector? Table;

[DataField]
public bool DeleteOnSpawn = true;

[DataField]
public int AvailableTakeovers = 1;

[ViewVariables]
public int CurrentTakeovers = 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System.Linq;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Ghost.Roles.Events;
using Content.Shared.EntityTable;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Content.Shared.Roles;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Goobstation.Server.Spawner;

public sealed partial class GhostRoleTableSpawnerSystem : EntitySystem
{
[Dependency] private EntityTableSystem _table = default!;
[Dependency] private SharedTransformSystem _transform = default!;
[Dependency] private SharedMindSystem _mindSystem = default!;
[Dependency] private SharedRoleSystem _roleSystem = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GhostRoleTableSpawnerComponent, TakeGhostRoleEvent>(OnSpawnerTakeRole);
}

private void OnSpawnerTakeRole(Entity<GhostRoleTableSpawnerComponent> ent, ref TakeGhostRoleEvent args)
{
var (uid, component) = ent;

if (!TryComp(uid, out GhostRoleComponent? ghostRole) ||
!CanTakeGhost(uid, ghostRole))
{
args.TookRole = false;
return;
}

var spawns = _table.GetSpawns(ent.Comp.Table).ToList();
if (spawns.Count == 0)
return;

var proto = spawns[0];

var mob = Spawn(proto, Transform(uid).Coordinates);
_transform.AttachToGridOrMap(mob);

var spawnedEvent = new GhostRoleSpawnerUsedEvent(uid, mob);
RaiseLocalEvent(mob, spawnedEvent);
RaiseLocalEvent(uid, spawnedEvent); // Goobstation edit

if (ghostRole.MakeSentient)
_mindSystem.MakeSentient(mob, ghostRole.AllowMovement, ghostRole.AllowSpeech);

EnsureComp<MindContainerComponent>(mob);

GhostRoleInternalCreateMindAndTransfer(args.Player, uid, mob, ghostRole);

if (++component.CurrentTakeovers < component.AvailableTakeovers)
{
args.TookRole = true;
return;
}

ghostRole.Taken = true;

if (component.DeleteOnSpawn)
QueueDel(uid);

args.TookRole = true;
}

private bool CanTakeGhost(EntityUid uid, GhostRoleComponent? component = null)
{
return Resolve(uid, ref component, false) &&
!component.Taken &&
!MetaData(uid).EntityPaused;
}

public void GhostRoleInternalCreateMindAndTransfer(ICommonSession player, EntityUid roleUid, EntityUid mob, GhostRoleComponent? role = null)
{
if (!Resolve(roleUid, ref role))
return;

DebugTools.AssertNotNull(player.ContentData());

// After taking a ghost role, the player cannot return to the original body, so wipe the player's current mind
// unless it is a visiting mind
if(_mindSystem.TryGetMind(player.UserId, out _, out var mind) && !mind.IsVisitingEntity)
_mindSystem.WipeMind(player);

var newMind = _mindSystem.CreateMind(player.UserId,
Comp<MetaDataComponent>(mob).EntityName);

_mindSystem.SetUserId(newMind, player.UserId);
_mindSystem.TransferTo(newMind, mob);

_roleSystem.MindAddRoles(newMind.Owner, role.MindRoles, newMind.Comp);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Content.Goobstation.Common.Spawner;
using Content.Goobstation.Shared.Spawner;
using Content.Server.Ghost.Roles.Events;
using Content.Shared.Teleportation.Components;
using Content.Shared.Teleportation.Systems;

namespace Content.Goobstation.Server.Spawner;

public sealed partial class SpawnerLinkSystem : EntitySystem
{
[Dependency] private LinkedEntitySystem _link = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SpawnerLinkComponent, SpawnerActivationEvent>(OnSpawnerActivation);
SubscribeLocalEvent<LinkedEntityTransferComponent, SpawnerActivationEvent>(OnLinkTransferActivation);
SubscribeLocalEvent<LinkedEntityTransferComponent, GhostRoleSpawnerUsedEvent>(OnGhostRoleSpawnerUsed);
}

private void OnSpawnerActivation(Entity<SpawnerLinkComponent> ent, ref SpawnerActivationEvent args)
{
_link.TryLink(ent.Owner, args.Spawned);
}

private void OnLinkTransferActivation(Entity<LinkedEntityTransferComponent> ent, ref SpawnerActivationEvent args)
=> TransferLinks(ent.Owner, args.Spawned);

private void OnGhostRoleSpawnerUsed(Entity<LinkedEntityTransferComponent> ent, ref GhostRoleSpawnerUsedEvent args)
=> TransferLinks(ent.Owner, args.Spawned);

private void TransferLinks(Entity<LinkedEntityComponent?> from, EntityUid to)
{
if (!Resolve(from.Owner, ref from.Comp))
return;

foreach (var linked in from.Comp.LinkedEntities)
{
_link.TryLink(to, linked);
}
}
}
Loading
Loading