[Antag] Lone Ops (#14647)

* loneops event, prototype stuff, striker shuttle, and nukeops rule changes

* newline

* shuttle attributions

* optimizations and tweaks

* bugfix and mutually exclusive with nukeops

* bugfix but better

* fix nukie planet spawning when defaulting to extended

* remove hypospray protection references

* ghost_roles.yml edit thingy

* remove .orig file
This commit is contained in:
Scribbles0
2023-04-16 23:00:43 -07:00
committed by GitHub
parent 308a64a5c9
commit e24d0b4e44
8 changed files with 3865 additions and 9 deletions

View File

@@ -26,6 +26,24 @@ public sealed class NukeopsRuleConfiguration : GameRuleConfiguration
[DataField("maxOps")]
public int MaxOperatives = 5;
/// <summary>
/// Whether or not all of the nuclear operatives dying will end the round. Used by LoneOpsSpawn event.
/// </summary>
[DataField("endsRound")]
public bool EndsRound = true;
/// <summary>
/// Whether or not to spawn the nuclear operative outpost. Used by LoneOpsSpawn event.
/// </summary>
[DataField("spawnOutpost")]
public bool SpawnOutpost = true;
/// <summary>
/// Whether or not loneops can spawn. Set to false if a normal nukeops round is occurring.
/// </summary>
[DataField("canLoneOpsSpawn")]
public bool CanLoneOpsSpawn = true;
[DataField("randomHumanoidSettings", customTypeSerializer: typeof(PrototypeIdSerializer<RandomHumanoidSettingsPrototype>))]
public string RandomHumanoidSettingsPrototype = "NukeOp";

View File

@@ -234,6 +234,17 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
}
}
public void LoadLoneOpsConfig()
{
_nukeopsRuleConfig.SpawnOutpost = false;
_nukeopsRuleConfig.EndsRound = false;
}
public bool CheckLoneOpsSpawn()
{
return _nukeopsRuleConfig.CanLoneOpsSpawn;
}
private void OnRoundStart()
{
// TODO: This needs to try and target a Nanotrasen station. At the very least,
@@ -383,7 +394,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
private void CheckRoundShouldEnd()
{
if (!RuleAdded || RuleWinType == WinType.CrewMajor || RuleWinType == WinType.OpsMajor)
if (!RuleAdded || !_nukeopsRuleConfig.EndsRound || RuleWinType == WinType.CrewMajor || RuleWinType == WinType.OpsMajor)
return;
// If there are any nuclear bombs that are active, immediately return. We're not over yet.
@@ -456,6 +467,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
if (!RuleAdded)
return;
if (!SpawnMap())
{
Logger.InfoS("nukies", "Failed to load map for nukeops");
return;
}
// Basically copied verbatim from traitor code
var playersPerOperative = _nukeopsRuleConfig.PlayersPerOperative;
var maxOperatives = _nukeopsRuleConfig.MaxOperatives;
@@ -608,6 +625,11 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
if (_nukiePlanet != null)
return true; // Map is already loaded.
if (!_nukeopsRuleConfig.SpawnOutpost)
return true;
_nukeopsRuleConfig.CanLoneOpsSpawn = false;
var path = _nukeopsRuleConfig.NukieOutpostMap;
var shuttlePath = _nukeopsRuleConfig.NukieShuttleMap;
if (path == null)
@@ -785,6 +807,11 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
private void SpawnOperativesForGhostRoles()
{
if (!SpawnMap())
{
Logger.InfoS("nukies", "Failed to load map for nukeops");
return;
}
// Basically copied verbatim from traitor code
var playersPerOperative = _nukeopsRuleConfig.PlayersPerOperative;
var maxOperatives = _nukeopsRuleConfig.MaxOperatives;
@@ -855,13 +882,6 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
_operativeNames.Add(proto, new List<string>(_prototypeManager.Index<DatasetPrototype>(proto).Values));
}
if (!SpawnMap())
{
Logger.InfoS("nukies", "Failed to load map for nukeops");
return;
}
// Add pre-existing nuke operatives to the credit list.
var query = EntityQuery<NukeOperativeComponent, MindComponent>(true);
foreach (var (_, mindComp) in query)
@@ -876,5 +896,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
SpawnOperativesForGhostRoles();
}
public override void Ended() { }
public override void Ended()
{
_nukeopsRuleConfig.EndsRound = true;
_nukeopsRuleConfig.SpawnOutpost = true;
_nukeopsRuleConfig.CanLoneOpsSpawn = true;
}
}

View File

@@ -0,0 +1,44 @@
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Map;
using Content.Server.GameTicking;
using Robust.Shared.Prototypes;
using Content.Server.GameTicking.Rules;
namespace Content.Server.StationEvents.Events;
public sealed class LoneOpsSpawn : StationEventSystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly MapLoaderSystem _map = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly NukeopsRuleSystem _nukeopsRuleSystem = default!;
public override string Prototype => "LoneOps";
public const string LoneOpsShuttlePath = "Maps/Shuttles/striker.yml";
public const string GameRuleProto = "Nukeops";
public override void Started()
{
base.Started();
if (!_nukeopsRuleSystem.CheckLoneOpsSpawn())
return;
var shuttleMap = _mapManager.CreateMap();
var options = new MapLoadOptions()
{
LoadMap = true,
};
_map.TryLoad(shuttleMap, LoneOpsShuttlePath, out var grids, options);
if (!_prototypeManager.TryIndex<GameRulePrototype>(GameRuleProto, out var ruleProto))
return;
_nukeopsRuleSystem.LoadLoneOpsConfig();
_gameTicker.StartGameRule(ruleProto);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -53,3 +53,9 @@
- Chi
- Psi
- Omega
- type: dataset
id: SyndicateNamesPrefix
values:
- Operative
- Agent

View File

@@ -72,3 +72,23 @@
- state: green
- sprite: Structures/Wallmounts/signs.rsi
state: radiation
- type: entity
noSpawn: true
id: SpawnPointLoneNukeOperative
name: ghost role spawn point
suffix: loneops
parent: MarkerBase
components:
- type: GhostRole
name: Lone Operative
description: You are a lone nuclear operative. Destroy the station!
rules: You are a syndicate operative tasked with the destruction of the station. As an antagonist, do whatever is required to complete this task.
- type: GhostRoleMobSpawner
prototype: MobHumanLoneNuclearOperative
- type: Sprite
sprite: markers/jobs.rsi
layers:
- state: green
- sprite: Structures/Wallmounts/signs.rsi
state: radiation

View File

@@ -57,3 +57,23 @@
components:
- type: NukeOperative
- type: RandomHumanoidAppearance
- type: entity
noSpawn: true
parent: MobHuman
id: MobHumanLoneNuclearOperative
name: Lone Operative
components:
- type: RandomHumanoidAppearance
randomizeName: false
- type: NukeOperative
- type: Loadout
prototype: SyndicateOperativeGearFull
prototypes: [SyndicateOperativeGearFull]
- type: RandomMetadata
nameSegments:
- SyndicateNamesPrefix
- SyndicateNamesNormal
- type: Faction
factions:
- Syndicate

View File

@@ -222,3 +222,14 @@
earliestStart: 50
weight: 2.5
endAfter: 1
- type: gameRule
id: LoneOps
config:
!type:StationEventRuleConfiguration
id: LoneOps
earliestStart: 55
weight: 5
minimumPlayers: 20
reoccurrenceDelay: 25
endAfter: 1