Opt-in nukies (#8541)

* save changes

* naming rules

* changes

* changes

* last touches

* e

* use default

* better looping

* better prototype ig

* f

* c

* Revert "changes"

This reverts commit 111a7f36

* fuck i'm bad at git

* changes

* mfw

* e

* e
This commit is contained in:
Veritius
2022-06-07 12:43:54 +10:00
committed by GitHub
parent 094baca28a
commit 49ed83b0de
2 changed files with 107 additions and 11 deletions

View File

@@ -1,6 +1,9 @@
using System.Linq; using System.Linq;
using Content.Server.CharacterAppearance.Components;
using Content.Server.Chat.Managers; using Content.Server.Chat.Managers;
using Content.Server.Nuke; using Content.Server.Nuke;
using Content.Server.Players;
using Content.Server.Roles;
using Content.Server.RoundEnd; using Content.Server.RoundEnd;
using Content.Server.Spawners.Components; using Content.Server.Spawners.Components;
using Content.Server.Station.Components; using Content.Server.Station.Components;
@@ -12,7 +15,6 @@ using Robust.Server.Maps;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -36,6 +38,9 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
public override string Prototype => "Nukeops"; public override string Prototype => "Nukeops";
private const string NukeopsPrototypeId = "Nukeops";
private const string NukeopsCommanderPrototypeId = "NukeopsCommander";
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -91,16 +96,93 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
_aliveNukeops.Clear(); _aliveNukeops.Clear();
// Between 1 and <max op count>: needs at least n players per op. // Basically copied verbatim from traitor code
var numOps = Math.Max(1, var playersPerOperative = _cfg.GetCVar(CCVars.NukeopsPlayersPerOp);
(int)Math.Min( var maxOperatives = _cfg.GetCVar(CCVars.NukeopsMaxOps);
Math.Floor((double)ev.PlayerPool.Count / _cfg.GetCVar(CCVars.NukeopsPlayersPerOp)), _cfg.GetCVar(CCVars.NukeopsMaxOps)));
var ops = new IPlayerSession[numOps]; var everyone = new List<IPlayerSession>(ev.PlayerPool);
for (var i = 0; i < numOps; i++) var prefList = new List<IPlayerSession>();
var cmdrPrefList = new List<IPlayerSession>();
var operatives = new List<IPlayerSession>();
// The LINQ expression ReSharper keeps suggesting is completely unintelligible so I'm disabling it
// ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
foreach (var player in everyone)
{ {
ops[i] = _random.PickAndTake(ev.PlayerPool); if(player.ContentData()?.Mind?.AllRoles.All(role => role is not Job {CanBeAntag: false}) ?? false) continue;
if (!ev.Profiles.ContainsKey(player.UserId))
{
continue;
}
var profile = ev.Profiles[player.UserId];
if (profile.AntagPreferences.Contains(NukeopsPrototypeId))
{
prefList.Add(player);
}
if (profile.AntagPreferences.Contains(NukeopsCommanderPrototypeId))
{
cmdrPrefList.Add(player);
}
} }
var numNukies = MathHelper.Clamp(ev.PlayerPool.Count / playersPerOperative, 1, maxOperatives);
for (var i = 0; i < numNukies; i++)
{
IPlayerSession nukeOp;
// Only one commander, so we do it at the start
if (i == 0)
{
if (cmdrPrefList.Count == 0)
{
if (prefList.Count == 0)
{
if (everyone.Count == 0)
{
Logger.InfoS("preset", "Insufficient ready players to fill up with nukeops, stopping the selection");
break;
}
nukeOp = _random.PickAndTake(everyone);
Logger.InfoS("preset", "Insufficient preferred nukeop commanders or nukies, picking at random.");
}
else
{
nukeOp = _random.PickAndTake(prefList);
everyone.Remove(nukeOp);
Logger.InfoS("preset", "Insufficient preferred nukeop commanders, picking at random from regular op list.");
}
}
else
{
nukeOp = _random.PickAndTake(cmdrPrefList);
everyone.Remove(nukeOp);
prefList.Remove(nukeOp);
Logger.InfoS("preset", "Selected a preferred nukeop commander.");
}
}
else
{
if (prefList.Count == 0)
{
if (everyone.Count == 0)
{
Logger.InfoS("preset", "Insufficient ready players to fill up with nukeops, stopping the selection");
break;
}
nukeOp = _random.PickAndTake(everyone);
Logger.InfoS("preset", "Insufficient preferred nukeops, picking at random.");
}
else
{
nukeOp = _random.PickAndTake(prefList);
everyone.Remove(nukeOp);
Logger.InfoS("preset", "Selected a preferred nukeop.");
}
}
operatives.Add(nukeOp);
}
// TODO: Make this a prototype
var map = "/Maps/infiltrator.yml"; var map = "/Maps/infiltrator.yml";
var aabbs = _stationSystem.Stations.SelectMany(x => var aabbs = _stationSystem.Stations.SelectMany(x =>
@@ -119,7 +201,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
if (!gridId.HasValue) if (!gridId.HasValue)
{ {
Logger.ErrorS("NUKEOPS", $"Gridid was null when loading \"{map}\", aborting."); Logger.ErrorS("NUKEOPS", $"Gridid was null when loading \"{map}\", aborting.");
foreach (var session in ops) foreach (var session in operatives)
{ {
ev.PlayerPool.Add(session); ev.PlayerPool.Add(session);
} }
@@ -149,7 +231,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
} }
// TODO: This should spawn the nukies in regardless and transfer if possible; rest should go to shot roles. // TODO: This should spawn the nukies in regardless and transfer if possible; rest should go to shot roles.
for (var i = 0; i < ops.Length; i++) for (var i = 0; i < operatives.Count; i++)
{ {
string name; string name;
StartingGearPrototype gear; StartingGearPrototype gear;
@@ -170,7 +252,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
break; break;
} }
var session = ops[i]; var session = operatives[i];
var newMind = new Mind.Mind(session.UserId) var newMind = new Mind.Mind(session.UserId)
{ {
CharacterName = name CharacterName = name
@@ -179,6 +261,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
var mob = EntityManager.SpawnEntity("MobHuman", _random.Pick(spawns)); var mob = EntityManager.SpawnEntity("MobHuman", _random.Pick(spawns));
EntityManager.GetComponent<MetaDataComponent>(mob).EntityName = name; EntityManager.GetComponent<MetaDataComponent>(mob).EntityName = name;
EntityManager.AddComponent<RandomHumanoidAppearanceComponent>(mob);
newMind.TransferTo(mob); newMind.TransferTo(mob);
_stationSpawningSystem.EquipStartingGear(mob, gear, null); _stationSpawningSystem.EquipStartingGear(mob, gear, null);

View File

@@ -0,0 +1,13 @@
- type: antag
id: Nukeops
name: "Nuclear Operative"
antagonist: true
setPreference: true
objective: "Find the nuke disk and blow up the station."
- type: antag
id: NukeopsCommander
name: "Nuclear Operative Commander"
antagonist: true
setPreference: true
objective: "Lead your team to the destruction of the station."