using Content.Server.Maps; using Content.Server.NPC.Components; using Content.Server.RoundEnd; using Content.Server.StationEvents.Events; using Content.Shared.Dataset; using Content.Shared.Roles; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Utility; namespace Content.Server.GameTicking.Rules.Components; [RegisterComponent, Access(typeof(NukeopsRuleSystem), typeof(LoneOpsSpawnRule))] public sealed partial class NukeopsRuleComponent : Component { /// /// This INCLUDES the operatives. So a value of 3 is satisfied by 2 players & 1 operative /// [DataField] public int PlayersPerOperative = 10; [DataField] public int MaxOps = 5; /// /// What will happen if all of the nuclear operatives will die. Used by LoneOpsSpawn event. /// [DataField] public RoundEndBehavior RoundEndBehavior = RoundEndBehavior.ShuttleCall; /// /// Text for shuttle call if RoundEndBehavior is ShuttleCall. /// [DataField] public string RoundEndTextSender = "comms-console-announcement-title-centcom"; /// /// Text for shuttle call if RoundEndBehavior is ShuttleCall. /// [DataField] public string RoundEndTextShuttleCall = "nuke-ops-no-more-threat-announcement-shuttle-call"; /// /// Text for announcement if RoundEndBehavior is ShuttleCall. Used if shuttle is already called /// [DataField] public string RoundEndTextAnnouncement = "nuke-ops-no-more-threat-announcement"; /// /// Time to emergency shuttle to arrive if RoundEndBehavior is ShuttleCall. /// [DataField] public TimeSpan EvacShuttleTime = TimeSpan.FromMinutes(3); /// /// Whether or not to spawn the nuclear operative outpost. Used by LoneOpsSpawn event. /// [DataField] public bool SpawnOutpost = true; /// /// Whether or not nukie left their outpost /// [DataField] public bool LeftOutpost; /// /// Enables opportunity to get extra TC for war declaration /// [DataField] public bool CanEnableWarOps = true; /// /// Indicates time when war has been declared, null if not declared /// [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan? WarDeclaredTime; /// /// This amount of TC will be given to each nukie /// [DataField] public int WarTCAmountPerNukie = 40; /// /// Delay between war declaration and nuke ops arrival on station map. Gives crew time to prepare /// [DataField] public TimeSpan WarNukieArriveDelay = TimeSpan.FromMinutes(15); /// /// Minimal operatives count for war declaration /// [DataField] public int WarDeclarationMinOps = 4; [DataField] public EntProtoId SpawnPointProto = "SpawnPointNukies"; [DataField] public EntProtoId GhostSpawnPointProto = "SpawnPointGhostNukeOperative"; [DataField] public string OperationName = "Test Operation"; [DataField] public ProtoId OutpostMapPrototype = "NukieOutpost"; [DataField] public WinType WinType = WinType.Neutral; [DataField] public List WinConditions = new (); public MapId? NukiePlanet; // TODO: use components, don't just cache entity UIDs // There have been (and probably still are) bugs where these refer to deleted entities from old rounds. public EntityUid? NukieOutpost; public EntityUid? NukieShuttle; public EntityUid? TargetStation; /// /// Data to be used in for an operative once the Mind has been added. /// [DataField] public Dictionary OperativeMindPendingData = new(); [DataField(required: true)] public ProtoId Faction = default!; [DataField] public NukeopSpawnPreset CommanderSpawnDetails = new() { AntagRoleProto = "NukeopsCommander", GearProto = "SyndicateCommanderGearFull", NamePrefix = "nukeops-role-commander", NameList = "SyndicateNamesElite" }; [DataField] public NukeopSpawnPreset AgentSpawnDetails = new() { AntagRoleProto = "NukeopsMedic", GearProto = "SyndicateOperativeMedicFull", NamePrefix = "nukeops-role-agent", NameList = "SyndicateNamesNormal" }; [DataField] public NukeopSpawnPreset OperativeSpawnDetails = new(); } /// /// Stores the presets for each operative type /// Ie Commander, Agent and Operative /// [DataDefinition, Serializable] public sealed partial class NukeopSpawnPreset { [DataField] public ProtoId AntagRoleProto = "Nukeops"; /// /// The equipment set this operative will be given when spawned /// [DataField] public ProtoId GearProto = "SyndicateOperativeGearFull"; /// /// The name prefix, ie "Agent" /// [DataField] public LocId NamePrefix = "nukeops-role-operator"; /// /// The entity name suffix will be chosen from this list randomly /// [DataField] public ProtoId NameList = "SyndicateNamesNormal"; } public enum WinType : byte { /// /// Operative major win. This means they nuked the station. /// OpsMajor, /// /// Minor win. All nukies were alive at the end of the round. /// Alternatively, some nukies were alive, but the disk was left behind. /// OpsMinor, /// /// Neutral win. The nuke exploded, but on the wrong station. /// Neutral, /// /// Crew minor win. The nuclear authentication disk escaped on the shuttle, /// but some nukies were alive. /// CrewMinor, /// /// Crew major win. This means they either killed all nukies, /// or the bomb exploded too far away from the station, or on the nukie moon. /// CrewMajor } public enum WinCondition : byte { NukeExplodedOnCorrectStation, NukeExplodedOnNukieOutpost, NukeExplodedOnIncorrectLocation, NukeActiveInStation, NukeActiveAtCentCom, NukeDiskOnCentCom, NukeDiskNotOnCentCom, NukiesAbandoned, AllNukiesDead, SomeNukiesAlive, AllNukiesAlive }