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:
@@ -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);
|
||||||
|
|||||||
13
Resources/Prototypes/Roles/Antags/nukeops.yml
Normal file
13
Resources/Prototypes/Roles/Antags/nukeops.yml
Normal 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."
|
||||||
Reference in New Issue
Block a user