listening post rewrite (#1369)
* rename pirate radio map to listening post, change spawner prototype * refactor pirate radio spawn rule into DebrisSpawner and LoadFarGrid * remove obsolete yml * -m make listening post rule use new stuff and antag selection * other changes * fixes * more * fixy * fix nan * final fix * what --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
parent
b00856ce39
commit
5e812e0f27
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using Content.Server.StationEvents.Events;
|
||||
|
||||
namespace Content.Server.StationEvents.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Spawns random debris in space around a loaded grid.
|
||||
/// Requires <see cref="LoadFarGridRuleComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(DebrisSpawnerRule))]
|
||||
public sealed partial class DebrisSpawnerRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// How many debris grids to spawn.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public int Count;
|
||||
|
||||
/// <summary>
|
||||
/// Modifier for debris distance.
|
||||
/// Should be between 3 and 10 generally.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public float DistanceModifier;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.StationEvents.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Loads a grid far away from a random station.
|
||||
/// Requires <see cref="RuleGridsComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(LoadFarGridRule))]
|
||||
public sealed partial class LoadFarGridRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the grid to spawn.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ResPath Path = new();
|
||||
|
||||
/// <summary>
|
||||
/// Roughly how many AABBs away
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public float DistanceModifier;
|
||||
|
||||
/// <summary>
|
||||
/// "Stations of Unusual Size Constant", derived from the AABB.Width of Shoukou.
|
||||
/// This Constant is used to check the size of a station relative to the reference point
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Sousk = 123.44f;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using Content.Server.DeltaV.StationEvents.Events;
|
||||
using Content.Server.StationEvents.Events;
|
||||
|
||||
namespace Content.Server.StationEvents.Components;
|
||||
|
||||
[RegisterComponent, Access(typeof(PirateRadioSpawnRule))]
|
||||
public sealed partial class PirateRadioSpawnRuleComponent : Component
|
||||
{
|
||||
[DataField("PirateRadioShuttlePath")]
|
||||
public string PirateRadioShuttlePath = "Maps/Shuttles/DeltaV/DV-pirateradio.yml";
|
||||
|
||||
[DataField("additionalRule")]
|
||||
public EntityUid? AdditionalRule;
|
||||
|
||||
[DataField("debrisCount")]
|
||||
public int DebrisCount { get; set; }
|
||||
|
||||
[DataField("distanceModifier")]
|
||||
public float DistanceModifier { get; set; }
|
||||
|
||||
[DataField("debrisDistanceModifier")]
|
||||
public float DebrisDistanceModifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "Stations of Unusual Size Constant", derived from the AABB.Width of Shoukou.
|
||||
/// This Constant is used to check the size of a station relative to the reference point
|
||||
/// </summary>
|
||||
[DataField("sousk")]
|
||||
public float SOUSK = 123.44f;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Salvage;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
public sealed class DebrisSpawnerRule : StationEventSystem<DebrisSpawnerRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _config = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DebrisSpawnerRuleComponent, RuleLoadedGridsEvent>(OnLoadedGrids);
|
||||
}
|
||||
|
||||
private void OnLoadedGrids(Entity<DebrisSpawnerRuleComponent> ent, ref RuleLoadedGridsEvent args)
|
||||
{
|
||||
if (_config.GetCVar<bool>(CCVars.WorldgenEnabled))
|
||||
return;
|
||||
|
||||
// get world AABBs of every grid that was loaded, probably just 1 anyway
|
||||
var boxes = new List<Box2>(args.Grids.Count);
|
||||
foreach (var gridId in args.Grids)
|
||||
{
|
||||
var grid = Comp<MapGridComponent>(gridId);
|
||||
var aabb = Transform(gridId).WorldMatrix.TransformBox(grid.LocalAABB);
|
||||
boxes.Add(aabb);
|
||||
}
|
||||
|
||||
// fetch all the salvage maps that can be picked
|
||||
var salvageMaps = _proto.EnumeratePrototypes<SalvageMapPrototype>().ToList();
|
||||
|
||||
// spawn them!
|
||||
for (var i = 0; i < ent.Comp.Count; i++)
|
||||
{
|
||||
var aabb = RobustRandom.Pick(boxes);
|
||||
var dist = MathF.Max(aabb.Height / 2f, aabb.Width / 2f) * ent.Comp.DistanceModifier;
|
||||
|
||||
var offset = RobustRandom.NextVector2(dist, dist * 2.5f);
|
||||
var randomer = RobustRandom.NextVector2(dist, dist * 5f); //Second random vector to ensure the outpost isn't perfectly centered in the debris field
|
||||
var options = new MapLoadOptions
|
||||
{
|
||||
Offset = aabb.Center + offset + randomer,
|
||||
LoadMap = false,
|
||||
};
|
||||
|
||||
var salvage = RobustRandom.PickAndTake(salvageMaps);
|
||||
_mapLoader.Load(args.Map, salvage.MapPath.ToString(), options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
public sealed class LoadFarGridRule : StationEventSystem<LoadFarGridRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
|
||||
protected override void Added(EntityUid uid, LoadFarGridRuleComponent comp, GameRuleComponent rule, GameRuleAddedEvent args)
|
||||
{
|
||||
base.Added(uid, comp, rule, args);
|
||||
|
||||
if (!TryGetRandomStation(out var station) || !TryComp<StationDataComponent>(station, out var data))
|
||||
{
|
||||
Log.Error($"{ToPrettyString(uid):rule} failed to find a station!");
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.Grids.Count < 1)
|
||||
{
|
||||
Log.Error($"{ToPrettyString(uid):rule} picked station {station} which had no grids!");
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
// get an AABB that contains all the station's grids
|
||||
var aabb = new Box2();
|
||||
var map = MapId.Nullspace;
|
||||
foreach (var gridId in data.Grids)
|
||||
{
|
||||
// use the first grid's map id
|
||||
if (map == MapId.Nullspace)
|
||||
map = Transform(gridId).MapID;
|
||||
|
||||
var grid = Comp<MapGridComponent>(gridId);
|
||||
var gridAabb = Transform(gridId).WorldMatrix.TransformBox(grid.LocalAABB);
|
||||
aabb = aabb.Union(gridAabb);
|
||||
}
|
||||
|
||||
var scale = comp.Sousk / aabb.Width;
|
||||
var modifier = comp.DistanceModifier * scale;
|
||||
var dist = MathF.Max(aabb.Height / 2f, aabb.Width / 2f) * modifier;
|
||||
var offset = RobustRandom.NextVector2(dist, dist * 2.5f);
|
||||
var options = new MapLoadOptions
|
||||
{
|
||||
Offset = aabb.Center + offset,
|
||||
LoadMap = false
|
||||
};
|
||||
|
||||
var path = comp.Path.ToString();
|
||||
Log.Debug($"Loading far grid {path} at {options.Offset}");
|
||||
if (!_mapLoader.TryLoad(map, path, out var grids, options))
|
||||
{
|
||||
Log.Error($"{ToPrettyString(uid):rule} failed to load grid {path}!");
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
// let other systems do stuff
|
||||
var ev = new RuleLoadedGridsEvent(map, grids);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Delta-V - This file is licensed under AGPLv3
|
||||
* Copyright (c) 2024 Delta-V Contributors
|
||||
* See AGPLv3.txt for details.
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Salvage;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.DeltaV.StationEvents.Events;
|
||||
|
||||
public sealed class PirateRadioSpawnRule : StationEventSystem<PirateRadioSpawnRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entities = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _map = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _confMan = default!;
|
||||
|
||||
protected override void Started(EntityUid uid, PirateRadioSpawnRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
||||
{
|
||||
//Start of Syndicate Listening Outpost spawning system
|
||||
base.Started(uid, component, gameRule, args);
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
var aabbs = EntityQuery<StationDataComponent>().SelectMany(x =>
|
||||
x.Grids.Select(x =>
|
||||
xformQuery.GetComponent(x).WorldMatrix.TransformBox(_entities.GetComponent<MapGridComponent>(x).LocalAABB)))
|
||||
.ToArray();
|
||||
if (aabbs.Length < 1) return;
|
||||
var aabb = aabbs[0];
|
||||
|
||||
for (var i = 1; i < aabbs.Length; i++)
|
||||
{
|
||||
aabb.Union(aabbs[i]);
|
||||
}
|
||||
var distanceFactorCoefficient = component.SOUSK / aabb.Width;
|
||||
var distanceModifier = Math.Clamp(component.DistanceModifier, 1, 25);
|
||||
var distanceModifierNormalized = distanceModifier * distanceFactorCoefficient;
|
||||
var a = MathF.Max(aabb.Height / 2f, aabb.Width / 2f) * distanceModifierNormalized;
|
||||
var randomoffset = _random.NextVector2(a, a * 2.5f);
|
||||
var outpostOptions = new MapLoadOptions
|
||||
{
|
||||
Offset = aabb.Center + randomoffset,
|
||||
LoadMap = false,
|
||||
};
|
||||
if (!_map.TryLoad(GameTicker.DefaultMap, component.PirateRadioShuttlePath, out var outpostids, outpostOptions)) return;
|
||||
//End of Syndicate Listening Outpost spawning system
|
||||
|
||||
//Start of Debris Field Generation
|
||||
var debrisSpawner = _confMan.GetCVar<bool>(CCVars.WorldgenEnabled);
|
||||
if (debrisSpawner == true) return;
|
||||
var debrisCount = Math.Clamp(component.DebrisCount, 0, 6);
|
||||
if (debrisCount == 0) return;
|
||||
var debrisDistanceModifier = Math.Clamp(component.DebrisDistanceModifier, 3, 10);
|
||||
foreach (var id in outpostids)
|
||||
{
|
||||
if (!TryComp<MapGridComponent>(id, out var grid)) return;
|
||||
var outpostaabb = _entities.GetComponent<TransformComponent>(id).WorldMatrix.TransformBox(grid.LocalAABB);
|
||||
var b = MathF.Max(outpostaabb.Height / 2f, aabb.Width / 2f) * debrisDistanceModifier;
|
||||
var k = 1;
|
||||
while (k < debrisCount + 1)
|
||||
{
|
||||
var debrisRandomOffset = _random.NextVector2(b, b * 2.5f);
|
||||
var randomer = _random.NextVector2(b, b * 5f); //Second random vector to ensure the outpost isn't perfectly centered in the debris field
|
||||
var debrisOptions = new MapLoadOptions
|
||||
{
|
||||
Offset = outpostaabb.Center + debrisRandomOffset + randomer,
|
||||
LoadMap = false,
|
||||
};
|
||||
|
||||
var salvageProto = _random.Pick(_prototypeManager.EnumeratePrototypes<SalvageMapPrototype>().ToList());
|
||||
_map.TryLoad(GameTicker.DefaultMap, salvageProto.MapPath.ToString(), out _, debrisOptions);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
//End of Debris Field generation
|
||||
}
|
||||
|
||||
protected override void Ended(EntityUid uid, PirateRadioSpawnRuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args)
|
||||
{
|
||||
base.Ended(uid, component, gameRule, args);
|
||||
|
||||
if (component.AdditionalRule != null)
|
||||
GameTicker.EndGameRule(component.AdditionalRule.Value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using Content.Shared.Roles;
|
||||
|
||||
namespace Content.Server.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - listening post ops have their own role
|
||||
/// </summary>
|
||||
[RegisterComponent, ExclusiveAntagonist]
|
||||
public sealed partial class ListeningPostRoleComponent : AntagonistRoleComponent;
|
||||
|
|
@ -19,6 +19,7 @@ public sealed class RoleSystem : SharedRoleSystem
|
|||
SubscribeAntagEvents<TraitorRoleComponent>();
|
||||
SubscribeAntagEvents<ZombieRoleComponent>();
|
||||
SubscribeAntagEvents<ThiefRoleComponent>();
|
||||
SubscribeAntagEvents<ListeningPostRoleComponent>(); // DeltaV - listening post role
|
||||
}
|
||||
|
||||
public string? MindGetBriefing(EntityUid? mindId)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
listening-post-round-end-agent-name = Listening Post Operative
|
||||
|
|
@ -25,7 +25,6 @@ entities:
|
|||
- type: MetaData
|
||||
name: unknown
|
||||
- type: Transform
|
||||
parent: invalid
|
||||
- type: MapGrid
|
||||
chunks:
|
||||
0,0:
|
||||
|
|
@ -5546,7 +5545,7 @@ entities:
|
|||
- type: Transform
|
||||
pos: 2.5,2.5
|
||||
parent: 1
|
||||
- proto: SpawnPointGhostSyndicateListener
|
||||
- proto: SpawnPointNukies
|
||||
entities:
|
||||
- uid: 813
|
||||
components:
|
||||
|
|
@ -20,19 +20,15 @@
|
|||
- sprite: Mobs/Species/Human/parts.rsi
|
||||
state: full
|
||||
|
||||
- type: entity # Part of PirateRadioSpawn
|
||||
- type: entity # Part of ListeningPost
|
||||
noSpawn: true
|
||||
parent: BaseAntagSpawner
|
||||
id: SpawnPointGhostSyndicateListener
|
||||
name: ghost role spawn point
|
||||
suffix: syndicate listener
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: GhostRole
|
||||
name: ghost-role-information-listeningop-name
|
||||
description: ghost-role-information-listeningop-description
|
||||
rules: ghost-role-information-listeningop-rules
|
||||
raffle:
|
||||
settings: default
|
||||
requirements: # Worth considering these numbers for the goal of making sure someone willing to MRP takes this.
|
||||
- !type:OverallPlaytimeRequirement
|
||||
time: 259200 # 72 hours
|
||||
|
|
@ -45,17 +41,9 @@
|
|||
- !type:DepartmentTimeRequirement
|
||||
department: Command
|
||||
time: 40000 # 11.1 hours
|
||||
- type: GhostRoleMobSpawner
|
||||
prototype: MobHumanSyndicateListener
|
||||
- type: Sprite
|
||||
sprite: Markers/jobs.rsi
|
||||
layers:
|
||||
- state: green
|
||||
- sprite: Structures/Wallmounts/signs.rsi
|
||||
state: radiation
|
||||
|
||||
- type: entity
|
||||
parent: MarkerBase
|
||||
parent: BaseAntagSpawner
|
||||
id: SpawnPointGhostParadoxAnomaly
|
||||
name: paradox anomaly spawn point
|
||||
components:
|
||||
|
|
@ -63,10 +51,3 @@
|
|||
name: ghost-role-information-paradox-anomaly-name
|
||||
description: ghost-role-information-paradox-anomaly-description
|
||||
rules: ghost-role-information-paradox-anomaly-rules
|
||||
raffle:
|
||||
settings: default
|
||||
- type: GhostRoleAntagSpawner
|
||||
- type: Sprite
|
||||
sprite: Markers/jobs.rsi
|
||||
layers:
|
||||
- state: green
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
- type: entity # Delta-V : Part of a mid-round PirateRadioSpawn
|
||||
noSpawn: true
|
||||
parent: MobHumanSyndicateAgent
|
||||
id: MobHumanSyndicateListener
|
||||
name: Syndicate Listener
|
||||
components:
|
||||
- type: Loadout
|
||||
prototypes: [SyndicateListenerGear]
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
- Syndicate
|
||||
- type: AutoTraitor
|
||||
giveUplink: false
|
||||
giveObjectives: false
|
||||
- type: AutoImplant
|
||||
implants:
|
||||
- DeathAcidifierImplant
|
||||
|
|
@ -1,19 +1,3 @@
|
|||
- type: entity # Delta-V part of PirateRadioSpawn
|
||||
id: RandomHumanoidSpawnerListener
|
||||
name: Syndicate Listener
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Mobs/Species/Human/parts.rsi
|
||||
state: full
|
||||
- type: RandomHumanoidSpawner
|
||||
settings: SyndicateListener
|
||||
|
||||
- type: randomHumanoidSettings
|
||||
id: SyndicateListener
|
||||
components:
|
||||
- type: Loadout
|
||||
prototypes: [SyndicateListenerGear]
|
||||
|
||||
# Mobsters
|
||||
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
- id: MobMothroach
|
||||
prob: 0.05
|
||||
|
||||
- type: entity # Delta-V : Midround Syndie Listening Station Spawn
|
||||
id: PirateRadioSpawn
|
||||
- type: entity
|
||||
id: ListeningPost
|
||||
parent: BaseGameRule
|
||||
noSpawn: true
|
||||
components:
|
||||
|
|
@ -55,16 +55,37 @@
|
|||
weight: 5
|
||||
minimumPlayers: 25
|
||||
maxOccurrences: 1
|
||||
duration: 1
|
||||
# TODO:
|
||||
# 1. use the load grid rule to load the post itself
|
||||
# 2. rename below to DebrisSpawnRule or something and have it just be debris
|
||||
# 3. use AntagSelection to spawn the listeners
|
||||
# the map will need spawnpoints like SpawnPointNukies added
|
||||
- type: PirateRadioSpawnRule
|
||||
debrisCount: 6
|
||||
duration: null
|
||||
- type: RuleGrids
|
||||
- type: LoadFarGridRule
|
||||
path: /Maps/Shuttles/DeltaV/listening_post.yml
|
||||
distanceModifier: 13
|
||||
debrisDistanceModifier: 3
|
||||
- type: DebrisSpawnerRule
|
||||
count: 6
|
||||
distanceModifier: 3
|
||||
# TODO: funny trolling or intel related objectives
|
||||
- type: AntagLoadProfileRule
|
||||
- type: AntagSelection
|
||||
agentName: listening-post-round-end-agent-name
|
||||
definitions:
|
||||
- spawnerPrototype: SpawnPointGhostSyndicateListener
|
||||
min: 2
|
||||
max: 2
|
||||
pickPlayer: false
|
||||
startingGear: SyndicateListenerGear
|
||||
components:
|
||||
- type: RandomMetadata
|
||||
nameSegments:
|
||||
- names_death_commando
|
||||
- type: AutoImplant
|
||||
implants:
|
||||
- DeathAcidifierImplant
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
- Syndicate
|
||||
mindComponents:
|
||||
- type: ListeningPostRole
|
||||
prototype: ListeningPost
|
||||
|
||||
# Mid round antag spawns
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
- type: antag
|
||||
id: ListeningPost
|
||||
name: roles-antag-listening-post-name
|
||||
antagonist: true
|
||||
objective: roles-antag-listening-post-objective
|
||||
# keep these in sync with the spawner
|
||||
requirements: # Worth considering these numbers for the goal of making sure someone willing to MRP takes this.
|
||||
- !type:OverallPlaytimeRequirement
|
||||
time: 259200 # 72 hours
|
||||
- !type:DepartmentTimeRequirement
|
||||
department: Security
|
||||
time: 40000 # 11.1 hours
|
||||
- !type:DepartmentTimeRequirement
|
||||
department: Civilian
|
||||
time: 40000 # 11.1 hours
|
||||
- !type:DepartmentTimeRequirement
|
||||
department: Command
|
||||
time: 40000 # 11.1 hours
|
||||
Loading…
Reference in New Issue