diff --git a/Content.Client/_Harmony/Conspirators/EntitySystems/ConspiratorSystem.cs b/Content.Client/_Harmony/Conspirators/EntitySystems/ConspiratorSystem.cs index d1f5d60c099..a37640384c3 100644 --- a/Content.Client/_Harmony/Conspirators/EntitySystems/ConspiratorSystem.cs +++ b/Content.Client/_Harmony/Conspirators/EntitySystems/ConspiratorSystem.cs @@ -18,19 +18,36 @@ public sealed class ConspiratorSystem : SharedConspiratorSystem base.Initialize(); SubscribeLocalEvent(OnConspiratorGetIcons); + SubscribeLocalEvent(OnConspiratorLeaderGetIcons); } private void OnConspiratorGetIcons(Entity entity, ref GetStatusIconsEvent args) { if (_playerManager.LocalSession?.AttachedEntity is { } playerEntity) { - if (!HasComp(playerEntity) && + if ((!HasComp(playerEntity) && !HasComp(playerEntity) && - !HasComp(playerEntity)) // DeltaV - add GhostComponent + !HasComp(playerEntity) )) // DeltaV - add GhostComponent and conspirators v2 return; } if (_prototypeManager.TryIndex(entity.Comp.ConspiratorIcon, out var iconPrototype)) args.StatusIcons.Add(iconPrototype); } + + //DV conspirators v2 addtions start + private void OnConspiratorLeaderGetIcons(Entity entity, ref GetStatusIconsEvent args) + { + if (_playerManager.LocalSession?.AttachedEntity is { } playerEntity) + { + if (!HasComp(playerEntity) && + !HasComp(playerEntity) && + !HasComp(playerEntity)) + return; + } + + if (_prototypeManager.TryIndex(entity.Comp.ConspiratorIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } + //DV conspirators v2 addtions end } diff --git a/Content.Server/Voting/Managers/VoteManager.cs b/Content.Server/Voting/Managers/VoteManager.cs index 74ce71b07ed..4ffa65587fe 100644 --- a/Content.Server/Voting/Managers/VoteManager.cs +++ b/Content.Server/Voting/Managers/VoteManager.cs @@ -9,6 +9,7 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Server.Maps; using Content.Shared._DV.CosmicCult.Components; // DeltaV - Cosmic Cult +using Content.Shared._Harmony.Conspirators.Components; //deltaV conspirators v2 using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Database; @@ -461,6 +462,13 @@ namespace Content.Server.Voting.Managers return false; } // End DeltaV - Cosmic Cult + //begin deltaV conspirators v2 + if (eligibility == VoterEligibility.Conspirators) + { + if (!_entityManager.HasComponent(player.AttachedEntity)) + return false; + } + //end deltaV conspirators v2 return true; } @@ -561,6 +569,7 @@ namespace Content.Server.Voting.Managers GhostMinimumPlaytime, // Player needs to be a ghost, with a minimum playtime and deathtime as defined by votekick CCvars. MinimumPlaytime, //Player needs to have a minimum playtime and deathtime as defined by votekick CCvars. CosmicCult, // DeltaV - Player needs to be a cosmic cultist. Used by the cosmic cult gamemode. + Conspirators // DeltaV - Player needs to be a Conspirators. Used by the Conspirators subgamemode. } #endregion diff --git a/Content.Server/_Harmony/GameTicking/Rules/Components/ConspiratorRuleComponent.cs b/Content.Server/_Harmony/GameTicking/Rules/Components/ConspiratorRuleComponent.cs index aec29f36c03..032206fd08f 100644 --- a/Content.Server/_Harmony/GameTicking/Rules/Components/ConspiratorRuleComponent.cs +++ b/Content.Server/_Harmony/GameTicking/Rules/Components/ConspiratorRuleComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Random; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Server._Harmony.GameTicking.Rules.Components; @@ -7,11 +8,15 @@ namespace Content.Server._Harmony.GameTicking.Rules.Components; /// Game rule for conspirators. Handles their shared objective. /// [RegisterComponent, Access(typeof(ConspiratorRuleSystem))] +[AutoGenerateComponentPause] public sealed partial class ConspiratorRuleComponent : Component { [DataField] public EntProtoId? Objective = null; - - [DataField] - public ProtoId ObjectiveGroup = "ConspiratorObjectiveGroup"; + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan? ConspiratorLeaderVoteTimer; + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan? ConspiratorObjectiveVoteTimer; } diff --git a/Content.Server/_Harmony/GameTicking/Rules/ConspiratorRuleSystem.cs b/Content.Server/_Harmony/GameTicking/Rules/ConspiratorRuleSystem.cs index f81b4eb50f7..01f505bd9d6 100644 --- a/Content.Server/_Harmony/GameTicking/Rules/ConspiratorRuleSystem.cs +++ b/Content.Server/_Harmony/GameTicking/Rules/ConspiratorRuleSystem.cs @@ -3,24 +3,48 @@ using Content.Server.Antag; using Content.Server.GameTicking; using Content.Server.GameTicking.Rules; using Content.Server.Roles; +using Content.Server.Administration.Logs; +using Content.Server.Voting.Managers; +using Content.Server.Voting; +using Content.Server.Objectives; +using Content.Server.Polymorph.Components; using Content.Shared._Harmony.Conspirators.Components; using Content.Shared._Harmony.Roles.Components; using Content.Shared.GameTicking.Components; using Content.Shared.Mind; +using Content.Shared.IdentityManagement; using Content.Shared.Random.Helpers; +using Content.Shared._DV.CCVars; +using Content.Shared.Database; +using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; +using Robust.Shared.Timing; +using Robust.Shared.Enums; +using Robust.Shared.Configuration; using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace Content.Server._Harmony.GameTicking.Rules; public sealed class ConspiratorRuleSystem : GameRuleSystem { // [Dependency] private readonly AntagSelectionSystem _antag = default!; // Delta V - Never used + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly IConfigurationManager _config = default!; [Dependency] private readonly SharedMindSystem _mind = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IVoteManager _votes = default!; + + + private TimeSpan _objectiveVoteTimer = default!; + private TimeSpan _objectiveVoteDelay = default!; + private TimeSpan _leaderVoteTimer = default!; + private TimeSpan _leaderVoteDelay = default!; + + private readonly SoundSpecifier _conspiratorBriefing = new SoundPathSpecifier("/Audio/_Harmony/Misc/conspirator_greeting.ogg"); public override void Initialize() { @@ -28,14 +52,31 @@ public sealed class ConspiratorRuleSystem : GameRuleSystem(OnGetBriefing); SubscribeLocalEvent(OnAntagSelected); - } + // deltav additions, conspirators v2 + Subs.CVar(_config, + DCCVars.ConspiratorObjectiveVoteTimer, + value => _objectiveVoteTimer = TimeSpan.FromSeconds(value), + true); + Subs.CVar(_config, + DCCVars.ConspiratorObjectiveVoteDelayTimer, + value => _objectiveVoteDelay = TimeSpan.FromSeconds(value), + true); + Subs.CVar(_config, + DCCVars.ConspiratorLeaderVoteTimer, + value => _leaderVoteTimer = TimeSpan.FromSeconds(value), + true); + Subs.CVar(_config, + DCCVars.ConspiratorLeaderVoteDelayTimer, + value => _leaderVoteDelay = TimeSpan.FromSeconds(value), + true); + // deltav additions, conspirators v2 + } + + /* DeltaV - removed custom round end text in favor of individually displayed objective summaries - protected override void AppendRoundEndText(EntityUid uid, - ConspiratorRuleComponent component, - GameRuleComponent gameRule, - ref RoundEndTextAppendEvent args) + protected override void AppendRoundEndText(EntityUid uid, ConspiratorRuleComponent component,GameRuleComponent gameRule,ref RoundEndTextAppendEvent args) { base.AppendRoundEndText(uid, component, gameRule, ref args); @@ -68,21 +109,26 @@ public sealed class ConspiratorRuleSystem : GameRuleSystem ent, ref AfterAntagEntitySelectedEvent args) { if (!_mind.TryGetMind(args.Session, out var mindId, out var mind)) return; - - if (ent.Comp.Objective is null) - { + + /* + if (ent.Comp.Objective is null){ if (GetRandomObjectivePrototype(ent.Comp, out var objectiveProtoId)) - ent.Comp.Objective = objectiveProtoId; + ent.Comp.Objective = objectiveProtoId; } - + */ + if (ent.Comp.Objective is not null) _mind.TryAddObjective(mindId, mind, ent.Comp.Objective); - } + } + + + /* deltaV conspirators v2, now uneeded so. private bool GetRandomObjectivePrototype(ConspiratorRuleComponent comp, [NotNullWhen(true)] out EntProtoId? objectiveProto) { objectiveProto = null; @@ -98,5 +144,178 @@ public sealed class ConspiratorRuleSystem : GameRuleSystem= _objectiveVoteTimer) + { + component.ConspiratorLeaderVoteTimer = null; + ConspiratorObjectiveVote(component); + } else if (component.ConspiratorObjectiveVoteTimer is { } _leaderVoteTimer && _timing.CurTime >= _leaderVoteTimer) + { + component.ConspiratorObjectiveVoteTimer = null; + ConspiratorLeaderVote(); + } + } + + private void ConspiratorLeaderVote() + { + // If there's already an entity with ConspiratorLeader, don't hold a vote. This allows admins to add the conspirators rule a 2nd time + // in the case that there is only one cultist and they've been chosen as the leader already. + if (EntityQuery().Any()) + { + _adminLogger.Add(LogType.Vote, LogImpact.Medium, + $"conspirator leader already exists. Cancelling leader vote."); + return; + } + + var conspirators = new List<(string, EntityUid)>(); + var conspiratorsQuery = EntityQueryEnumerator(); + + while (conspiratorsQuery.MoveNext(out var conspirator, out _, out var metadata)) + { + var playerInfo = metadata.EntityName; + if (TryComp(conspirator, out var polyComp) && polyComp.Parent.HasValue) // If the cultist is polymorphed, we use the original entity instead and hope that they'll polymorph back eventually + conspirators.Add((playerInfo, polyComp.Parent.Value)); + else + conspirators.Add((playerInfo, conspirator)); + } + + var options = new VoteOptions + { + Title = Loc.GetString("conspirator-vote-leader-title"), + InitiatorText = Loc.GetString("conspirators-vote-leader-initiator"), + Duration = _leaderVoteTimer, + VoterEligibility = VoteManager.VoterEligibility.Conspirators + }; + + // If there are no conspirators, don't hold a vote, or the server will crash. + if (conspirators.Count == 0) + { + Log.Warning($"There are no conspirators present for the leader vote. Voting is cancelled to prevent the server crashing."); + _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"There are no conspirators for the leader vote. Leader vote is cancelled to prevent the server crashing."); + return; + } + + foreach (var (name, ent) in conspirators) + { + options.Options.Add((Loc.GetString(name), ent)); + } + + // If somehow there are conspirators but no options, still don't hold a vote. + // Holding a vote with zero options crashes the server. + if (options.Options.Count == 0) + { + Log.Warning($"There are {conspirators.Count} conspirators but no options for the leader vote. Voting is cancelled to prevent the server crashing."); + _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"There are {conspirators.Count} conspirators but no options for the leader vote. Steward vote is cancelled to prevent the server crashing."); + return; + } + + var vote = _votes.CreateVote(options); + + vote.OnFinished += (_, args) => + { + EntityUid picked; + if (args.Winner == null) + { + picked = (EntityUid)_random.Pick(args.Winners); + } + else + { + picked = (EntityUid)args.Winner; + } + //changing the icon of the head conspirator + EnsureComp(picked); + _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"conspirators leadership vote finished: {Identity.Entity(picked, EntityManager)} is now leader."); + }; + } + + //summary -> voting system for the conspirators objective + private void ConspiratorObjectiveVote(ConspiratorRuleComponent component) + { + //getting all conspirators and checking if they already have a objective + var conspirators = new List(); + var conspiratorsQuery = EntityQueryEnumerator(); + + while (conspiratorsQuery.MoveNext(out var conspirator, out _)) + { + if (TryComp(conspirator, out var polyComp) && polyComp.Parent.HasValue) // If the cultist is polymorphed, we use the original entity instead and hope that they'll polymorph back eventually + conspirators.Add((polyComp.Parent.Value)); + else + conspirators.Add((conspirator)); + } + + // If there are no conspirators, don't hold a vote, or the server will crash. + if (conspirators.Count == 0) + { + Log.Warning($"There are no conspirators present for the objective vote. Voting is cancelled"); + _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"There are no conspirators for the objective vote. objective vote is cancelled"); + return; + } + + var options = new VoteOptions + { + Title = Loc.GetString("conspirator-vote-objective-title"), + InitiatorText = Loc.GetString("conspirators-vote-leader-initiator"), + Duration = _objectiveVoteTimer, + VoterEligibility = VoteManager.VoterEligibility.Conspirators + }; + + //dumb array go! from here use it to add the options, will have to add the new objectives to this. + int ObjectiveArrayNumber = 0; + string[] ConspiratorObjectiveIds = ["ConspiratorBusinessObjective","ConspiratorUsurpObjective","ConspiratorHordeObjective","ConspiratorDistrustObjective","ConspiratorVigilanteObjective","ConspiratorFreedomObjective","ConspiratorNukeObjective","ConspiratorDangerObjective","ConspiratorFreeObjective"]; + string[] ConspiratorObjectiveNames = ["Set up a business outside Nanotrasen.","Become the true leaders of the station.","Build a horde of valuables.","Brew distrust and hatred.","Enforce the laws secuirty can not.","Free the station of access.","Steal the nuke disk","Arm yourselves","Make your own conspiracy."]; + + foreach (string objective in ConspiratorObjectiveNames) + { + options.Options.Add((Loc.GetString(objective),ConspiratorObjectiveIds[ObjectiveArrayNumber])); + ObjectiveArrayNumber++; + } + + // If somehow there are cultists but no options, still don't hold a vote. + // Holding a vote with zero options crashes the server. + if (options.Options.Count == 0) + { + Log.Warning($"There are {conspirators.Count} conspirators but no options for the leader vote. Voting is cancelled to prevent the server crashing."); + _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"There are {conspirators.Count} conspirators but no options for the leader vote. Steward vote is cancelled to prevent the server crashing."); + return; + } + + var vote = _votes.CreateVote(options); + + vote.OnFinished += (_, args) => + { + string picked; + if (args.Winner == null) + { + picked = (string)_random.Pick(args.Winners); + } + else + { + picked = (string)args.Winner; + } + + //add an objective for each member of the conspiracy, skip if it cant get them + foreach (EntityUid ent in conspirators){ + _mind.TryGetMind(ent, out var mindId, out var mind); + if (mind == null){ + continue; + } + _mind.TryAddObjective(mindId, mind, picked); + } + component.Objective = picked; + _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"conspirators objective vote finished: {picked} is the objective."); + }; + } + + // deltav additions, conspirators v2 } diff --git a/Content.Shared/_DV/CCVars/DCCVars.cs b/Content.Shared/_DV/CCVars/DCCVars.cs index 5b8fd35967c..473bd79e293 100644 --- a/Content.Shared/_DV/CCVars/DCCVars.cs +++ b/Content.Shared/_DV/CCVars/DCCVars.cs @@ -343,4 +343,28 @@ public sealed partial class DCCVars /// public static readonly CVarDef RoundEndIsOOCVote = CVarDef.Create("deltav.round_end_is_ooc_vote", false, CVar.SERVER); + + /// + /// How long the timer for the Conspirator leader vote lasts. + /// + public static readonly CVarDef ConspiratorLeaderVoteTimer = + CVarDef.Create("conspirator.leader_vote_timer", 60, CVar.SERVER); + + /// + /// How long we wait before starting the Conspirator leader vote. + /// + public static readonly CVarDef ConspiratorLeaderVoteDelayTimer = + CVarDef.Create("conspirator.leader_vote_delay", 150, CVar.SERVER); + + /// + /// How long the timer for the Conspirator objective vote lasts. + /// + public static readonly CVarDef ConspiratorObjectiveVoteTimer = + CVarDef.Create("conspirator.objective_vote_timer", 120, CVar.SERVER); + + /// + /// How long we wait before starting the Conspirator objective vote. + /// + public static readonly CVarDef ConspiratorObjectiveVoteDelayTimer = + CVarDef.Create("conspirator.objective_vote_delay", 25, CVar.SERVER); } diff --git a/Content.Shared/_Harmony/Conspirators/Components/ConspiratorLeaderComponent.cs b/Content.Shared/_Harmony/Conspirators/Components/ConspiratorLeaderComponent.cs new file mode 100644 index 00000000000..1f4ea8e9321 --- /dev/null +++ b/Content.Shared/_Harmony/Conspirators/Components/ConspiratorLeaderComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._Harmony.Conspirators.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class ConspiratorLeaderComponent : Component +{ + [DataField] + public ProtoId ConspiratorIcon = "ConspiratorLeaderFaction"; + + public override bool SessionSpecific => true; +} diff --git a/Resources/Locale/en-US/_DV/conspirators/Conspirator-package.ftl b/Resources/Locale/en-US/_DV/conspirators/Conspirator-package.ftl new file mode 100644 index 00000000000..5dcb185f086 --- /dev/null +++ b/Resources/Locale/en-US/_DV/conspirators/Conspirator-package.ftl @@ -0,0 +1,31 @@ +conspirator-generic-kit-name = Generic +conspirator-generic-kit-description = + A kit for the basics. + Contains 90 sheets of glass, steel and plastic. + Also grants a full toolbelt and insulated gloves. + +conspirator-premium-kit-name = Premium +conspirator-premium-kit-description = + A kit for the finer stuff. + Contains 30 ingots of silvar, gold, plasma, plasteel and uranium. + Also grants 10,000 spesos. + +conspirator-weapons-kit-name = weapons +conspirator-weapons-kit-description = + A kit for arming yourselves. + Contains 30 wood, Cloth, and gunpowder. + also gives a Utility Knife, and 3 Igniters. + +conspirator-electronics-kit-name = Electronics +conspirator-electronics-kit-description = + A kit for making machines. + Contains 30 of each wire type, and 10 modular machine parts. + Also grants a Circuit Imprinter board. + +conspirator-maintenance-kit-name = Maintenance +conspirator-maintenance-kit-description = + A kit for gamblers. + contains an entire locker full of random items from the maintenance tunnels. + +conspirator-package-window-title = Conspirator Package +conspirator-package-window-description = What did you bring to the table? diff --git a/Resources/Locale/en-US/_DV/conspirators/conspirators-voting.ftl b/Resources/Locale/en-US/_DV/conspirators/conspirators-voting.ftl new file mode 100644 index 00000000000..9f7d007a470 --- /dev/null +++ b/Resources/Locale/en-US/_DV/conspirators/conspirators-voting.ftl @@ -0,0 +1,5 @@ +conspirator-vote-leader-title = Who should lead the Conspiracy +conspirators-vote-leader-initiator = The Conspiracy +conspirators-vote-leader-briefing = The leader of the Conspiracy is + +conspirator-vote-objective-title = what is the Conspiracys objective. diff --git a/Resources/Locale/en-US/_Harmony/game-ticking/game-presets/preset-conspirator.ftl b/Resources/Locale/en-US/_Harmony/game-ticking/game-presets/preset-conspirator.ftl index 60f8359757f..c65f68d018f 100644 --- a/Resources/Locale/en-US/_Harmony/game-ticking/game-presets/preset-conspirator.ftl +++ b/Resources/Locale/en-US/_Harmony/game-ticking/game-presets/preset-conspirator.ftl @@ -1,4 +1,4 @@ -conspirator-objective-issuer = [color=#724F29]Conspiracy[/color] +conspirator-objective-issuer = [color=#746694]Criminal[/color] conspirator-role-greeting = You are a conspirator. diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 085629169fa..2dc3c2ec3c6 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -30,10 +30,12 @@ #- id: Xenoborgs # prob: 0.05 # End DeltaV additions - Disable Xenoborgs - #begin DeltaV additions - add hitman + #begin DeltaV additions - add hitman (now add conspirators) - id: Hitman prob: 0.2 #as requested - # end deltaV additions - add hitman + - id: Conspirators + prob: 0.2 + # end deltaV additions - add hitman (now add conspirators) - type: entity parent: BaseGameRule @@ -49,10 +51,12 @@ #- id: Xenoborgs # prob: 0.05 # End DeltaV additions - Disable Xenoborgs - #begin DeltaV additions - add hitman + #begin DeltaV additions - add hitman (now add conspirators) - id: Hitman prob: 0.2 #as requested - # end deltaV additions - add hitman + - id: Conspirators + prob: 0.2 + # end deltaV additions - add hitman (now add conspirators) - type: entity parent: BaseGameRule @@ -64,10 +68,12 @@ prob: 0.5 - id: SubWizard prob: 0.05 - #begin DeltaV additions - add hitman + #begin DeltaV additions - add hitman (now add conspirators) - id: Hitman prob: 0.2 #as requested - # end deltaV additions - add hitman + - id: Conspirators + prob: 0.2 + # end deltaV additions - add hitman (now add conspirators) - type: entity parent: BaseGameRule @@ -77,10 +83,12 @@ rules: - id: Thief prob: 0.5 - #begin DeltaV additions - add hitman + #begin DeltaV additions - add hitman (now add conspirators) - id: Hitman prob: 0.2 #as requested - # end deltaV additions - add hitman + - id: Conspirators + prob: 0.2 + # end deltaV additions - add hitman (now add conspirators) - type: entity parent: BaseGameRule diff --git a/Resources/Prototypes/_DV/Catalog/Fills/Lockers/conspirators_locker.yml b/Resources/Prototypes/_DV/Catalog/Fills/Lockers/conspirators_locker.yml new file mode 100644 index 00000000000..b191e0bad4b --- /dev/null +++ b/Resources/Prototypes/_DV/Catalog/Fills/Lockers/conspirators_locker.yml @@ -0,0 +1,51 @@ +- type: entity + parent: LockerBaseSecureDeltaV + id: LockerConspiratorFilledRandom + suffix: conspirator + components: + - type: EntityTableContainerFill + containers: + entity_storage: !type:NestedSelector + tableId: conspiratorLockerLoot + + +- type: entityTable + id: conspiratorLockerLoot + table: !type:AllSelector + children: + #Weapons + # fluff + - !type:NestedSelector + tableId: MaintToolsTable + prob: 1 + - !type:NestedSelector + tableId: MaintFluffTable + prob: 1 + #tools + - !type:NestedSelector + tableId: ToiletCisternCommonToolsTable + prob: 1 + - !type:NestedSelector + tableId: ToiletCisternRareToolsTable + prob: 1 + - !type:NestedSelector + tableId: ToiletCisternUtilityTable + prob: 1 + #Weapons + - !type:NestedSelector + tableId: MaintWeaponTable + prob: 1 + - !type:NestedSelector + tableId: ToiletCisternWeaponsTable + prob: 1 + # Syndie Loot + - !type:NestedSelector + tableId: SyndieMaintLoot + prob: 1 + - !type:NestedSelector + tableId: ToiletCisternSyndicateTable + prob: 1 + # Recursive + - !type:NestedSelector + tableId: conspiratorLockerLoot + prob: 0.25 diff --git a/Resources/Prototypes/_DV/Catalog/conspirators_package_catalog.yml b/Resources/Prototypes/_DV/Catalog/conspirators_package_catalog.yml new file mode 100644 index 00000000000..7b7098c4a52 --- /dev/null +++ b/Resources/Prototypes/_DV/Catalog/conspirators_package_catalog.yml @@ -0,0 +1,74 @@ +- type: thiefBackpackSet + id: ConspiratorGenericKit + name: conspirator-generic-kit-name + description: conspirator-generic-kit-description + sprite: + sprite: Objects/Materials/Sheets/metal.rsi + state: steel + content: + - SheetSteel + - SheetSteel + - SheetSteel + - SheetGlass + - SheetGlass + - SheetGlass + - SheetPlastic + - SheetPlastic + - SheetPlastic + - ClothingBeltUtilityFilled + - ClothingHandsGlovesColorYellow + +- type: thiefBackpackSet + id: ConspiratorPremiumKit + name: conspirator-premium-kit-name + description: conspirator-premium-kit-description + sprite: + sprite: Objects/Materials/ingots.rsi + state: gold + content: + - SheetPlasma + - SheetUranium + - SheetPlasteel + - IngotGold + - IngotSilver + - SpaceCash10000 + +- type: thiefBackpackSet + id: ConspiratorWeaponsKit + name: conspirator-weapons-kit-name + description: conspirator-weapons-kit-description + sprite: + sprite: _DV/Objects/Weapons/Guns/Rifles/musket.rsi + state: base + content: + - MaterialWoodPlank + - MaterialCloth + - MaterialGunpowder30 + - UtilityKnife + - Igniter + - Igniter + - Igniter + +- type: thiefBackpackSet + id: ConspiratorElectronicsKit + name: conspirator-electronics-kit-name + description: conspirator-electronics-kit-description + sprite: + sprite: Objects/Tools/cable-coils.rsi + state: coil-30 + content: + - CableHVStack + - CableMVStack + - CableApcStack + - CircuitImprinterMachineCircuitboard + - MicroManipulatorStockPart10 + +- type: thiefBackpackSet + id: ConspiratorMaintenanceKit + name: conspirator-maintenance-kit-name + description: conspirator-maintenance-kit-description + sprite: + sprite: Structures/Storage/wall_locker.rsi + state: generic_icon + content: + - LockerConspiratorFilledRandom diff --git a/Resources/Prototypes/_DV/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/_DV/Entities/Objects/Materials/materials.yml index 1c37f6e5bfe..08a151e0c06 100644 --- a/Resources/Prototypes/_DV/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/_DV/Entities/Objects/Materials/materials.yml @@ -244,3 +244,19 @@ componentsToAdd: - type: PyrokinesisPower - type: Psionic + +- type: entity + parent: MicroManipulatorStockPart + id: MicroManipulatorStockPart10 + suffix: 10 + components: + - type: Stack + count: 10 + +- type: entity + parent: MaterialGunpowder + id: MaterialGunpowder30 + suffix: 30 + components: + - type: Stack + count: 30 diff --git a/Resources/Prototypes/_DV/Entities/Objects/Specific/conspirator-package.yml b/Resources/Prototypes/_DV/Entities/Objects/Specific/conspirator-package.yml new file mode 100644 index 00000000000..50549f6a3a3 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Specific/conspirator-package.yml @@ -0,0 +1,19 @@ +- type: entity + id: ConspiratorsPackage + name: conspirators package + description: A unopened package with everything you've prepared. + parent: ToolboxThief + components: + - type: Sprite + sprite: _DV/Objects/Misc/conspirators_package.rsi + state: icon + - type: ThiefUndeterminedBackpack + maxSelectedSets: 1 + toolName: conspirator-package-window-title + toolDesc: conspirator-package-window-description + possibleSets: + - ConspiratorGenericKit + - ConspiratorPremiumKit + - ConspiratorWeaponsKit + - ConspiratorElectronicsKit + - ConspiratorMaintenanceKit diff --git a/Resources/Prototypes/_DV/GameRules/subgamemodes.yml b/Resources/Prototypes/_DV/GameRules/subgamemodes.yml index 34e2ba7d5ad..215fc367184 100644 --- a/Resources/Prototypes/_DV/GameRules/subgamemodes.yml +++ b/Resources/Prototypes/_DV/GameRules/subgamemodes.yml @@ -25,3 +25,39 @@ sound: "/Audio/_DV/Ambience/Antag/hitman_briefing_piano_between.ogg" - type: DynamicRuleCost cost: 100 # bit more than thief + +- type: entity + id: Conspirators + components: + - type: GameRule + minPlayers: 30 + - type: AntagObjectives + objectives: + - ConspiratorPrepareObjective + - type: ConspiratorRule + - type: AntagSelection + selectionTime: IntraPlayerSpawn + agentName: conspirator-round-end-agent-name # DeltaV - previously unset + definitions: + - prefRoles: [ Conspirator ] + min: 3 + max: 6 + playerRatio: 10 + departmentDistribution: true # DeltaV - previously unset + startingGear: ConspiratorGear + blacklist: # DeltaV - Blacklist AntagImmune + components: + - AntagImmune + briefing: + text: conspirator-role-greeting + color: "#724F29" + sound: /Audio/_Harmony/Misc/conspirator_greeting.ogg + components: + - type: Conspirator + - type: AutoImplant + implants: + - RadioImplantConspiracy + mindRoles: + - MindRoleConspirator + - type: DynamicRuleCost + cost: 150 # more than hitman by a lot diff --git a/Resources/Prototypes/_Harmony/GameRules/roundstart.yml b/Resources/Prototypes/_Harmony/GameRules/roundstart.yml index c591d5b49c4..2e0bb113a30 100644 --- a/Resources/Prototypes/_Harmony/GameRules/roundstart.yml +++ b/Resources/Prototypes/_Harmony/GameRules/roundstart.yml @@ -6,38 +6,3 @@ rules: - id: Thief prob: 0.5 - -- type: entity - parent: BaseGameRule - id: Conspirators - components: - - type: GameRule - minPlayers: 15 # DeltaV - changed from 28 to 15 - minTotalPlayers: 40 # DeltaV - added attribute - delay: # DeltaV - add delay to make sure as many people as possible join the round - min: 600 - max: 900 - - type: ConspiratorRule - - type: AntagSelection - selectionTime: PostPlayerSpawn # DeltaV - previously IntraPlayerSpawn - agentName: conspirator-round-end-agent-name # DeltaV - previously unset - definitions: - - prefRoles: [ Conspirator ] - min: 4 - max: 7 - playerRatio: 7 - departmentDistribution: true # DeltaV - previously unset - blacklist: # DeltaV - Blacklist AntagImmune - components: - - AntagImmune - briefing: - text: conspirator-role-greeting - color: "#724F29" - sound: /Audio/_Harmony/Misc/conspirator_greeting.ogg - components: - - type: Conspirator - - type: AutoImplant - implants: - - RadioImplantConspiracy - mindRoles: - - MindRoleConspirator diff --git a/Resources/Prototypes/_Harmony/Objectives/conspirator.yml b/Resources/Prototypes/_Harmony/Objectives/conspirator.yml index d63b97b5214..fb988ea8e63 100644 --- a/Resources/Prototypes/_Harmony/Objectives/conspirator.yml +++ b/Resources/Prototypes/_Harmony/Objectives/conspirator.yml @@ -98,3 +98,115 @@ icon: sprite: Mobs/Silicon/station_ai.rsi state: ai_camera + + +# dv addtions - dv conspirators v2 +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorPrepareObjective + name: Plan and prepare. + description: Gather with your other Conspirators and prepare your conspiracy. + components: + - type: Objective + icon: + sprite: Objects/Weapons/Melee/stunprod.rsi + state: stunprod_off + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorBusinessObjective + name: Set up a business outside Nanotrasen. + description: You dont wanna work for nt anymore. Get a shuttle and whatever else would let you set up a profitable business of your own. + components: + - type: Objective + icon: + sprite: Structures/Machines/computers.rsi + state: avionics-systems + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorUsurpObjective + name: Become the true leaders of the station. + description: You want to be the top dogs. Through violence, blackmail, or popularity become the true captains. + components: + - type: Objective + icon: + sprite: Clothing/Head/Hats/captain.rsi + state: icon + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorHordeObjective + name: Build a horde of valuables. + description: You want it all. gather everything valuable on this station into a hidden location. + components: + - type: Objective + icon: + sprite: Objects/Materials/ingots.rsi + state: gold + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorDistrustObjective + name: Brew distrust and hatred. + description: A angry people is a controlable people. Try and get everyone isolated and angry at everyone else. + components: + - type: Objective + icon: + sprite: Structures/Machines/computers.rsi + state: television + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorVigilanteObjective + name: Enforce the laws secuirty can not. + description: Trespassing, minor theft, contraband, demolish these criminals so secuirty can focus on the real problems. + components: + - type: Objective + icon: + sprite: Objects/Weapons/Melee/baseball_bat.rsi + state: icon + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorFreedomObjective + name: Free the station of access. + description: The people are constrained by access and departments. Give the people the power to go anywhere. + components: + - type: Objective + icon: + sprite: Structures/Doors/Airlocks/Glass/basic.rsi + state: closed + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorNukeObjective + name: Steal the nuke disk + description: You know the nuclear operatives are coming. If you dont have the disk this station is doomed! + components: + - type: Objective + icon: + sprite: Objects/Misc/nukedisk.rsi + state: icon + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorDangerObjective + name: Arm yourselves + description: You're all in danger, get as many weapons and armor as you can to protect yourself. + components: + - type: Objective + icon: + sprite: Objects/Weapons/Guns/Pistols/mk58.rsi + state: icon + +- type: entity + parent: BaseConspiratorObjective + id: ConspiratorFreeObjective + name: Make your own conspiracy. + description: you know what you want to do. + components: + - type: Objective + icon: + sprite: _ST/Effects/interaction.rsi + state: hand \ No newline at end of file diff --git a/Resources/Prototypes/_Harmony/Objectives/objectiveGroups.yml b/Resources/Prototypes/_Harmony/Objectives/objectiveGroups.yml index c2615dc845a..6d733c5e453 100644 --- a/Resources/Prototypes/_Harmony/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/_Harmony/Objectives/objectiveGroups.yml @@ -2,12 +2,12 @@ - type: weightedRandom id: ConspiratorObjectiveGroup # if you want to add another objective, feel free weights: - ConspiratorUnionObjective: 1 - ConspiratorGameshowObjective: 1 - ConspiratorTechnologyObjective: 1 - ConspiratorArmsObjective: 1 - ConspiratorThiefObjective: 1 - ConspiratorMafiaObjective: 1 - ConspiratorArrestObjective: 1 -# ConspiratorCameraObjective: 1 -- DeltaV - remove from pool - ConspiratorSiliconObjective: 1 # DeltaV + ConspiratorUnionObjective: 1 #deltaV conspirators v2 + #ConspiratorGameshowObjective: 1 + #ConspiratorTechnologyObjective: 1 + #ConspiratorArmsObjective: 1 + #ConspiratorThiefObjective: 1 + #ConspiratorMafiaObjective: 1 + #ConspiratorArrestObjective: 1 + #ConspiratorCameraObjective: 1 -- DeltaV - remove from pool + #ConspiratorSiliconObjective: 1 # DeltaV \ No newline at end of file diff --git a/Resources/Prototypes/_Harmony/Roles/Antags/conspirator.yml b/Resources/Prototypes/_Harmony/Roles/Antags/conspirator.yml index 3eac690a412..c6c342139c4 100644 --- a/Resources/Prototypes/_Harmony/Roles/Antags/conspirator.yml +++ b/Resources/Prototypes/_Harmony/Roles/Antags/conspirator.yml @@ -1,10 +1,16 @@ - type: antag id: Conspirator name: roles-antag-conspirator-name + objective: roles-antag-conspirator-objective antagonist: true setPreference: true - objective: roles-antag-conspirator-objective guides: [ Conspirators ] requirements: - !type:OverallPlaytimeRequirement - time: 86400 # DeltaV - 24h + time: 24h # DeltaV - 24h + +- type: startingGear + id: ConspiratorGear + storage: + back: + - ConspiratorsPackage diff --git a/Resources/Prototypes/_Harmony/StatusIcon/faction.yml b/Resources/Prototypes/_Harmony/StatusIcon/faction.yml index c6165bb5dde..c5384d16df8 100644 --- a/Resources/Prototypes/_Harmony/StatusIcon/faction.yml +++ b/Resources/Prototypes/_Harmony/StatusIcon/faction.yml @@ -9,3 +9,16 @@ icon: sprite: /Textures/_Harmony/Interface/Misc/job_icons.rsi state: Conspirator + +## conspirators v2 +- type: factionIcon + id: ConspiratorLeaderFaction + isShaded: true + priority: 11 + showTo: + components: + - ShowAntagIcons + - Conspirator + icon: + sprite: /Textures/_Harmony/Interface/Misc/job_icons.rsi + state: ConspiratorLead \ No newline at end of file diff --git a/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/icon.png b/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/icon.png new file mode 100644 index 00000000000..14ba906c45d Binary files /dev/null and b/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/icon.png differ diff --git a/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/meta.json b/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/meta.json new file mode 100644 index 00000000000..714df498c13 --- /dev/null +++ b/Resources/Textures/_DV/Objects/Misc/conspirators_package.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "modifed mail capsuler from Frontier by erhardsteinhauer (discord). modifed by storymatt on github", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/ConspiratorLead.png b/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/ConspiratorLead.png new file mode 100644 index 00000000000..bebed972d73 Binary files /dev/null and b/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/ConspiratorLead.png differ diff --git a/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/meta.json b/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/meta.json index f21a67563f4..8bfc5732348 100644 --- a/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/meta.json +++ b/Resources/Textures/_Harmony/Interface/Misc/job_icons.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Conspirator made by SuperGDPWYL (GitHub).", + "copyright": "Conspirator made by SuperGDPWYL (GitHub). ConspiratorLead modified from Conspirator by stormyatt (github)", "size": { "x": 8, "y": 8 @@ -9,6 +9,9 @@ "states": [ { "name": "Conspirator" + }, + { + "name": "ConspiratorLead" } ] }