Hijack shuttle objective (#19621)
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
using Content.Server.Objectives.Systems;
|
||||||
|
|
||||||
|
namespace Content.Server.Objectives.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, Access(typeof(HijackShuttleConditionSystem))]
|
||||||
|
public sealed partial class HijackShuttleComponent : Component
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using Content.Server.Objectives.Components;
|
||||||
|
using Content.Server.Shuttles.Components;
|
||||||
|
using Content.Server.Shuttles.Systems;
|
||||||
|
using Content.Shared.Cuffs.Components;
|
||||||
|
using Content.Shared.Humanoid;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.Mobs.Components;
|
||||||
|
using Content.Shared.Mobs.Systems;
|
||||||
|
using Content.Shared.Objectives.Components;
|
||||||
|
using Content.Shared.Roles;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Server.Objectives.Systems;
|
||||||
|
|
||||||
|
public sealed class HijackShuttleConditionSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;
|
||||||
|
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||||
|
[Dependency] private readonly SharedRoleSystem _role = default!;
|
||||||
|
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<HijackShuttleComponent, ObjectiveGetProgressEvent>(OnGetProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetProgress(EntityUid uid, HijackShuttleComponent comp, ref ObjectiveGetProgressEvent args)
|
||||||
|
{
|
||||||
|
args.Progress = GetProgress(args.MindId, args.Mind);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetProgress(EntityUid mindId, MindComponent mind)
|
||||||
|
{
|
||||||
|
// not escaping alive if you're deleted/dead
|
||||||
|
if (mind.OwnedEntity == null || _mind.IsCharacterDeadIc(mind))
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
// You're not escaping if you're restrained!
|
||||||
|
if (TryComp<CuffableComponent>(mind.OwnedEntity, out var cuffed) && cuffed.CuffedHandCount > 0)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
// There no emergency shuttles
|
||||||
|
if (!_emergencyShuttle.EmergencyShuttleArrived)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
// Check hijack for each emergency shuttle
|
||||||
|
foreach (var stationData in EntityQuery<StationEmergencyShuttleComponent>())
|
||||||
|
{
|
||||||
|
if (stationData.EmergencyShuttle == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (IsShuttleHijacked(stationData.EmergencyShuttle.Value, mindId))
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsShuttleHijacked(EntityUid shuttleGridId, EntityUid mindId)
|
||||||
|
{
|
||||||
|
var gridPlayers = Filter.BroadcastGrid(shuttleGridId).Recipients;
|
||||||
|
var humanoids = GetEntityQuery<HumanoidAppearanceComponent>();
|
||||||
|
var cuffable = GetEntityQuery<CuffableComponent>();
|
||||||
|
EntityQuery<MobStateComponent>();
|
||||||
|
|
||||||
|
var agentOnShuttle = false;
|
||||||
|
foreach (var player in gridPlayers)
|
||||||
|
{
|
||||||
|
if (player.AttachedEntity == null ||
|
||||||
|
!_mind.TryGetMind(player.AttachedEntity.Value, out var crewMindId, out _))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mindId == crewMindId)
|
||||||
|
{
|
||||||
|
agentOnShuttle = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isHumanoid = humanoids.HasComponent(player.AttachedEntity.Value);
|
||||||
|
if (!isHumanoid) // Only humanoids count as enemies
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var isAntagonist = _role.MindIsAntagonist(mindId);
|
||||||
|
if (isAntagonist) // Allow antagonist
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var isPersonIncapacitated = _mobState.IsIncapacitated(player.AttachedEntity.Value);
|
||||||
|
if (isPersonIncapacitated) // Allow dead and crit
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var isPersonCuffed =
|
||||||
|
cuffable.TryGetComponent(player.AttachedEntity.Value, out var cuffed)
|
||||||
|
&& cuffed.CuffedHandCount > 0;
|
||||||
|
if (isPersonCuffed) // Allow handcuffed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return agentOnShuttle;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using Content.Server.UserInterface;
|
|||||||
using Content.Shared.Access;
|
using Content.Shared.Access;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Shuttles.BUIStates;
|
using Content.Shared.Shuttles.BUIStates;
|
||||||
using Content.Shared.Shuttles.Events;
|
using Content.Shared.Shuttles.Events;
|
||||||
@@ -89,6 +90,7 @@ public sealed partial class EmergencyShuttleSystem
|
|||||||
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, EmergencyShuttleRepealMessage>(OnEmergencyRepeal);
|
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, EmergencyShuttleRepealMessage>(OnEmergencyRepeal);
|
||||||
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, EmergencyShuttleRepealAllMessage>(OnEmergencyRepealAll);
|
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, EmergencyShuttleRepealAllMessage>(OnEmergencyRepealAll);
|
||||||
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, ActivatableUIOpenAttemptEvent>(OnEmergencyOpenAttempt);
|
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, ActivatableUIOpenAttemptEvent>(OnEmergencyOpenAttempt);
|
||||||
|
SubscribeLocalEvent<EmergencyShuttleConsoleComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
|
|
||||||
SubscribeLocalEvent<EscapePodComponent, EntityUnpausedEvent>(OnEscapeUnpaused);
|
SubscribeLocalEvent<EscapePodComponent, EntityUnpausedEvent>(OnEscapeUnpaused);
|
||||||
}
|
}
|
||||||
@@ -103,6 +105,12 @@ public sealed partial class EmergencyShuttleSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnEmagged(EntityUid uid, EmergencyShuttleConsoleComponent component, ref GotEmaggedEvent args)
|
||||||
|
{
|
||||||
|
_logger.Add(LogType.EmergencyShuttle, LogImpact.Extreme, $"{ToPrettyString(args.UserUid):player} emagged shuttle console for early launch");
|
||||||
|
EarlyLaunch();
|
||||||
|
}
|
||||||
|
|
||||||
private void SetAuthorizeTime(float obj)
|
private void SetAuthorizeTime(float obj)
|
||||||
{
|
{
|
||||||
_authorizeTime = obj;
|
_authorizeTime = obj;
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
objective-condition-hijack-shuttle-title = Hijack emergency shuttle
|
||||||
|
objective-condition-hijack-shuttle-description = Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent.
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
weights:
|
weights:
|
||||||
EscapeShuttleObjective: 1
|
EscapeShuttleObjective: 1
|
||||||
DieObjective: 0.05
|
DieObjective: 0.05
|
||||||
|
HijackShuttleObjective: 0.02
|
||||||
|
|
||||||
- type: weightedRandom
|
- type: weightedRandom
|
||||||
id: TraitorObjectiveGroupSocial
|
id: TraitorObjectiveGroupSocial
|
||||||
|
|||||||
Reference in New Issue
Block a user