--- /dev/null
+using Content.Server.Antag.Components;
+using Content.Server.GameTicking.Rules;
+
+namespace Content.Server.Antag;
+
+public sealed class AntagRandomSpawnSystem : GameRuleSystem<AntagRandomSpawnComponent>
+{
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<AntagRandomSpawnComponent, AntagSelectLocationEvent>(OnSelectLocation);
+ }
+
+ private void OnSelectLocation(Entity<AntagRandomSpawnComponent> ent, ref AntagSelectLocationEvent args)
+ {
+ if (TryFindRandomTile(out _, out _, out _, out var coords))
+ args.Coordinates.Add(_transform.ToMapCoordinates(coords));
+ }
+}
--- /dev/null
+using Content.Server.Antag.Components;
+
+namespace Content.Server.Antag;
+
+/// <summary>
+/// Spawns an entity when creating an antag for <see cref="AntagSpawnerComponent"/>.
+/// </summary>
+public sealed class AntagSpawnerSystem : EntitySystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<AntagSpawnerComponent, AntagSelectEntityEvent>(OnSelectEntity);
+ }
+
+ private void OnSelectEntity(Entity<AntagSpawnerComponent> ent, ref AntagSelectEntityEvent args)
+ {
+ args.Entity = Spawn(ent.Comp.Prototype);
+ }
+}
--- /dev/null
+namespace Content.Server.Antag.Components;
+
+/// <summary>
+/// Spawns this rule's antags at random tiles on a station using <c>TryGetRandomTile</c>.
+/// Requires <see cref="AntagSelectionComponent"/>.
+/// </summary>
+[RegisterComponent]
+public sealed partial class AntagRandomSpawnComponent : Component;
--- /dev/null
+using Content.Server.Antag;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Antag.Components;
+
+/// <summary>
+/// Spawns a prototype for antags created with a spawner.
+/// </summary>
+[RegisterComponent, Access(typeof(AntagSpawnerSystem))]
+public sealed partial class AntagSpawnerComponent : Component
+{
+ /// <summary>
+ /// The entity to spawn.
+ /// </summary>
+ [DataField(required: true)]
+ public EntProtoId Prototype = string.Empty;
+}
-using Content.Server.GenericAntag;
using Content.Server.Objectives.Components;
using Content.Server.Objectives.Systems;
using Content.Server.Popups;
SubscribeLocalEvent<DragonComponent, DragonSpawnRiftActionEvent>(OnSpawnRift);
SubscribeLocalEvent<DragonComponent, RefreshMovementSpeedModifiersEvent>(OnDragonMove);
SubscribeLocalEvent<DragonComponent, MobStateChangedEvent>(OnMobStateChanged);
- SubscribeLocalEvent<DragonComponent, GenericAntagCreatedEvent>(OnCreated);
SubscribeLocalEvent<DragonComponent, EntityZombifiedEvent>(OnZombified);
}
DeleteRifts(uid, false, component);
}
- private void OnCreated(EntityUid uid, DragonComponent comp, ref GenericAntagCreatedEvent args)
- {
- var mindId = args.MindId;
- var mind = args.Mind;
-
- _role.MindAddRole(mindId, new DragonRoleComponent(), mind);
- _role.MindAddRole(mindId, new RoleBriefingComponent()
- {
- Briefing = Loc.GetString("dragon-role-briefing")
- }, mind);
- }
-
private void OnZombified(Entity<DragonComponent> ent, ref EntityZombifiedEvent args)
{
// prevent carp attacking zombie dragon
roles-antag-thief-name = Thief
roles-antag-thief-objective = Add some NT property to your personal collection without using violence.
+
+roles-antag-dragon-name = Space Dragon
+roles-antag-dragon-objective = Create a carp army to take over this quadrant.
+- type: entity
+ abstract: true
+ parent: MarkerBase
+ id: BaseAntagSpawner
+ name: ghost role spawn point
+ components:
+ - type: GhostRole
+ raffle:
+ settings: default
+ - type: GhostRoleAntagSpawner
+
- type: entity
id: SpawnPointGhostRatKing
name: ghost role spawn point
- type: entity
noSpawn: true
+ parent: BaseAntagSpawner
id: SpawnPointLoneNukeOperative
- name: ghost role spawn point
- suffix: loneops
- parent: MarkerBase
components:
- type: GhostRole
name: ghost-role-information-loneop-name
description: ghost-role-information-loneop-description
rules: ghost-role-information-loneop-rules
- raffle:
- settings: default
- - type: GhostRoleAntagSpawner
- type: Sprite
sprite: Markers/jobs.rsi
layers:
description: roles-antag-nuclear-operative-objective
- type: entity
- parent: MarkerBase
- id: SpawnPointGhostDragon
noSpawn: true
- name: ghost role spawn point
- suffix: dragon
+ parent: BaseAntagSpawner
+ id: SpawnPointGhostDragon
components:
- type: GhostRole
name: ghost-role-information-space-dragon-name
description: ghost-role-information-space-dragon-description
rules: ghost-role-component-default-rules
- raffle:
- settings: default
- - type: GhostRoleMobSpawner
- prototype: MobDragon
- type: Sprite
layers:
- state: green
- type: entity
parent: BaseMobDragon
id: MobDragon
+ suffix: No role or objectives
components:
- type: Dragon
spawnRiftAction: ActionSpawnRift
- - type: GenericAntag
- rule: Dragon
- type: ActionGun
action: ActionDragonsBreath
gunProto: DragonsBreathGun
components:
- type: StationEvent
weight: 6.5
- duration: 1
earliestStart: 40
reoccurrenceDelay: 20
minimumPlayers: 20
- - type: RandomSpawnRule
- prototype: SpawnPointGhostDragon
+ - type: AntagRandomSpawn
+ - type: AntagSpawner
+ prototype: MobDragon
+ - type: AntagObjectives
+ objectives:
+ - CarpRiftsObjective
+ - DragonSurviveObjective
+ - type: AntagSelection
+ agentName: dragon-round-end-agent-name
+ definitions:
+ - spawnerPrototype: SpawnPointGhostDragon
+ min: 1
+ max: 1
+ pickPlayer: false
+ mindComponents:
+ - type: DragonRole
+ prototype: Dragon
+ - type: RoleBriefing
+ briefing: dragon-role-briefing
- type: entity
parent: BaseGameRule
- type: NinjaRule
threats: NinjaThreats
-# stores configuration for dragon
-- type: entity
- noSpawn: true
- parent: BaseGameRule
- id: Dragon
- components:
- - type: GenericAntagRule
- agentName: dragon-round-end-agent-name
- objectives:
- - CarpRiftsObjective
- - DragonSurviveObjective
-
- type: entity
noSpawn: true
parent: BaseGameRule
--- /dev/null
+- type: antag
+ id: Dragon
+ name: roles-antag-dragon-name
+ antagonist: true
+ objective: roles-antag-dragon-objective