antag definitions + servant background

This commit is contained in:
Ed
2025-09-24 15:59:37 +03:00
parent 22254734aa
commit 00ecd0f766
17 changed files with 181 additions and 32 deletions

View File

@@ -169,7 +169,7 @@ public sealed partial class AntagSelectionSystem
return true; return true;
if (def.PrefRoles.Count == 0) if (def.PrefRoles.Count == 0)
return false; return true; //CP14 - If definition dont have PrefRoles, everyone can be this antag
var pref = (HumanoidCharacterProfile) _pref.GetPreferences(session.UserId).SelectedCharacter; var pref = (HumanoidCharacterProfile) _pref.GetPreferences(session.UserId).SelectedCharacter;
return pref.AntagPreferences.Any(p => def.PrefRoles.Contains(p)); return pref.AntagPreferences.Any(p => def.PrefRoles.Contains(p));

View File

@@ -393,7 +393,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
if (!antagEnt.HasValue) if (!antagEnt.HasValue)
{ {
var getEntEv = new AntagSelectEntityEvent(session, ent); var getEntEv = new AntagSelectEntityEvent(session, ent, def); //CP14 def added
RaiseLocalEvent(ent, ref getEntEv, true); RaiseLocalEvent(ent, ref getEntEv, true);
antagEnt = getEntEv.Entity; antagEnt = getEntEv.Entity;
} }
@@ -416,7 +416,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
// Therefore any component subscribing to this has to make sure both subscriptions return the same value // Therefore any component subscribing to this has to make sure both subscriptions return the same value
// or the ghost role raffle location preview will be wrong. // or the ghost role raffle location preview will be wrong.
var getPosEv = new AntagSelectLocationEvent(session, ent); var getPosEv = new AntagSelectLocationEvent(session, ent, def); //CP14 def added
RaiseLocalEvent(ent, ref getPosEv, true); RaiseLocalEvent(ent, ref getPosEv, true);
if (getPosEv.Handled) if (getPosEv.Handled)
{ {
@@ -603,7 +603,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
/// Only raised if the selected player's current entity is invalid. /// Only raised if the selected player's current entity is invalid.
/// </summary> /// </summary>
[ByRefEvent] [ByRefEvent]
public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity<AntagSelectionComponent> GameRule) public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity<AntagSelectionComponent> GameRule, AntagSelectionDefinition? Def = null) //CP14 Definition added
{ {
public readonly ICommonSession? Session = Session; public readonly ICommonSession? Session = Session;
@@ -616,7 +616,7 @@ public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity<Anta
/// Event raised on a game rule entity to determine the location for the antagonist. /// Event raised on a game rule entity to determine the location for the antagonist.
/// </summary> /// </summary>
[ByRefEvent] [ByRefEvent]
public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity<AntagSelectionComponent> GameRule) public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity<AntagSelectionComponent> GameRule, AntagSelectionDefinition? Def = null) //CP14 Definition added
{ {
public readonly ICommonSession? Session = Session; public readonly ICommonSession? Session = Session;

View File

@@ -73,6 +73,12 @@ public sealed partial class AntagSelectionComponent : Component
[DataDefinition] [DataDefinition]
public partial struct AntagSelectionDefinition() public partial struct AntagSelectionDefinition()
{ {
/// <summary>
/// CP14 - unique keys that allow you to separate logic in AfterAntagEntitySelectedEvent, depending on the key
/// </summary>
[DataField]
public string DefinitionKey = string.Empty;
/// <summary> /// <summary>
/// A list of antagonist roles that are used for selecting which players will be antagonists. /// A list of antagonist roles that are used for selecting which players will be antagonists.
/// </summary> /// </summary>

View File

@@ -1,23 +1,84 @@
using Content.Server._CP14.GameTicking.Rules.Components; using Content.Server._CP14.GameTicking.Rules.Components;
using Content.Server.Antag;
using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Content.Shared.Objectives.Systems;
using Content.Shared.Players;
namespace Content.Server._CP14.GameTicking.Rules; namespace Content.Server._CP14.GameTicking.Rules;
public sealed class CP14LurkerHuntRule : GameRuleSystem<CP14LurkerHuntRuleComponent> public sealed class CP14LurkerHuntRule : GameRuleSystem<CP14LurkerHuntRuleComponent>
{ {
[Dependency] private readonly SharedObjectivesSystem _objectives = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
private const string LurkerDefinitionKey = "Lurker";
private const string HunterDefinitionKey = "Hunter";
private const string VictimDefinitionKey = "Victim";
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<CP14LurkerHuntRuleComponent, AfterAntagEntitySelectedEvent>(AfterRoleSelected);
SubscribeLocalEvent<CP14LurkerHuntRuleComponent, AntagSelectLocationEvent>(OnAntagSelectLocation);
SubscribeLocalEvent<CP14LurkerHuntRuleComponent, AntagSelectEntityEvent>(OnAntagSelectEntity);
}
private void OnAntagSelectEntity(Entity<CP14LurkerHuntRuleComponent> ent, ref AntagSelectEntityEvent args)
{
if (args.Handled)
return;
if (args.Def is null)
return;
if (args.Def.Value.DefinitionKey == LurkerDefinitionKey)
{
args.Entity = Spawn(ent.Comp.LurkerProto);
}
}
private void OnAntagSelectLocation(Entity<CP14LurkerHuntRuleComponent> ent, ref AntagSelectLocationEvent args)
{
if (args.Def is null)
return;
//Spawn lurker on random position on the map
if (args.Def.Value.DefinitionKey == LurkerDefinitionKey && TryFindRandomTile(out _, out _, out _, out var coords))
{
args.Coordinates.Add(_transform.ToMapCoordinates(coords));
}
}
private void AfterRoleSelected(Entity<CP14LurkerHuntRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
{
if (args.Session is null)
return;
var mind = args.Session.GetMind();
if (mind is null)
return;
switch (args.Def.DefinitionKey)
{
case LurkerDefinitionKey:
ent.Comp.Lurker = mind;
break;
case VictimDefinitionKey:
ent.Comp.Victims.Add(mind.Value);
break;
case HunterDefinitionKey:
ent.Comp.Hunters.Add(mind.Value);
break;
}
} }
protected override void Added(EntityUid uid, CP14LurkerHuntRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) protected override void Added(EntityUid uid, CP14LurkerHuntRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
{ {
} }
protected override void Started(EntityUid uid, protected override void Started(EntityUid uid,

View File

@@ -1,4 +1,3 @@
using Content.Shared._CP14.Procedural.Prototypes;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Server._CP14.GameTicking.Rules.Components; namespace Content.Server._CP14.GameTicking.Rules.Components;
@@ -6,4 +5,15 @@ namespace Content.Server._CP14.GameTicking.Rules.Components;
[RegisterComponent, Access(typeof(CP14LurkerHuntRule))] [RegisterComponent, Access(typeof(CP14LurkerHuntRule))]
public sealed partial class CP14LurkerHuntRuleComponent : Component public sealed partial class CP14LurkerHuntRuleComponent : Component
{ {
[DataField]
public EntProtoId LurkerProto = "CP14MobLurker";
[DataField]
public EntityUid? Lurker;
[DataField]
public HashSet<EntityUid> Hunters = new();
[DataField]
public HashSet<EntityUid> Victims = new();
} }

View File

@@ -0,0 +1,8 @@
using Robust.Shared.GameStates;
namespace Content.Shared._CP14.Background;
[RegisterComponent, NetworkedComponent]
public sealed partial class CP14BackgroundMerkasServantComponent : Component
{
}

View File

@@ -1,6 +0,0 @@
cp14-bloodmoon-raising = The moon in the sky is stained with blood. The next night will be terrible.
cp14-bloodmoon-start = The blood moon shines in full force, enslaving minds.
cp14-bloodmoon-end = The blood moon sets over the horizon, losing its power.
cp14-bloodmoon-curse-removed = The curse of the blood moon is dispelled.
cp14-bloodmoon-curse-examined = [color=red]The aura of the blood moon hovers around this creature. Be careful, for his mind is unstable.[/color]

View File

@@ -0,0 +1,3 @@
cp14-lurker-briefing = In the past, you made a pact with Darkness for power and influence. Now it demands its payment. You must reap the harvest from those chosen by Lady Darkness. Use your Lurker form, to turn pitiful mortals into obedient servants of darkness.
cp14-lurker-victim-briefing = Shadows gather around you. Whispers call your name in the darkness. Dark entities are out hunting, and you are their prey. What has attracted their attention, that Darkness itself reaches out to embrace you?
cp14-lurker-hunter-briefing = Your duty as a servant of Merkas has brought you to these lands, where Darkness has set its sights on mortals. Protect the people by destroying the cursed creatures lurking in the darkness.

View File

@@ -21,4 +21,9 @@ cp14-trait-snoring-name = Loud snoring
cp14-trait-snoring-desc = It is simply impossible to sleep next to you because you snore terribly loudly at everything. cp14-trait-snoring-desc = It is simply impossible to sleep next to you because you snore terribly loudly at everything.
cp14-trait-mana-wasting-name = Magical mediocrity. cp14-trait-mana-wasting-name = Magical mediocrity.
cp14-trait-mana-wasting-desc = Fate has decreed that magic is just an empty sound for you. You are unable to store or use magical energy. cp14-trait-mana-wasting-desc = Fate has decreed that magic is just an empty sound for you. You are unable to store or use magical energy.
# Backgrounds
cp14-trait-bg-merkas-servant-name = Servant of the Light Merkas
cp14-trait-bg-merkas-servant-desc = Your past is closely tied to serving Merkas, the god of light, and his dogma is still strong in your mind. You feel compelled to help those in need, banish darkness, and bring light to the hearts of those around you.

View File

@@ -1,6 +0,0 @@
cp14-bloodmoon-raising = Луна на небосводе обагривается кровью. Следующая ночь будет ужасной.
cp14-bloodmoon-start = Кровавая луна сияет в полную силу, порабощая разумы.
cp14-bloodmoon-end = Кровавая луна заходит за горизонт, теряя свою силу.
cp14-bloodmoon-curse-removed = Проклятье кровавой луны развеивается.
cp14-bloodmoon-curse-examined = [color=red]Аура кровавой луны витает вокруг этого существа. Будьте осторожны, ибо его разум нестабилен.[/color]

View File

@@ -0,0 +1,3 @@
cp14-lurker-briefing = прошлом вы заключили контракт с Тьмой ради силы и власти. Теперь она требует свою плату. Вы должны собрать жатву с тех, кого укажет госпожа Тьма. Используйте свой теневой облик Таящегося, чтобы обратить жалких смертных в покорных слуг тьмы.
cp14-lurker-victim-briefing = Тени сгущаются рядом с вами. В темноте слышны шепоты, зовущие по имени. Темные сущности выходят на охоту, и их цель — вы. Чем вы привлекли их внимание, что сама Тьма протягивает к вам свои объятия?
cp14-lurker-hunter-briefing = Ваш долг служителя Меркаса привел вас в эти земли, где Тьма устроила свою охоту на смертных. Защитите людей, уничтожив проклятых созданий, таящихся во мраке.

View File

@@ -21,4 +21,9 @@ cp14-trait-snoring-name = Громкий храп
cp14-trait-snoring-desc = Спать рядом с вами просто невозможно, потому что во все вы жутко громко храпите. cp14-trait-snoring-desc = Спать рядом с вами просто невозможно, потому что во все вы жутко громко храпите.
cp14-trait-mana-wasting-name = Магическая бездарность cp14-trait-mana-wasting-name = Магическая бездарность
cp14-trait-mana-wasting-desc = Судьба распорядилась так, что магия для вас - лишь пустой звук. Вы не способны ни накапливать, ни использовать магическую энергию. cp14-trait-mana-wasting-desc = Судьба распорядилась так, что магия для вас - лишь пустой звук. Вы не способны ни накапливать, ни использовать магическую энергию.
# Backgrounds
cp14-trait-bg-merkas-servant-name = Служитель светлого Меркаса
cp14-trait-bg-merkas-servant-desc = Ваше прошлое тесно связано с служением Меркасу - богу света, и его догмы все еще сильны в вашем сознании. Вы считаете себя должным помогать нуждающимся, изгонять тьму и нести свет в сердца окружающих.

View File

@@ -21,3 +21,23 @@
- state: green - state: green
- sprite: _CP14/Mobs/Pets/rat.rsi - sprite: _CP14/Mobs/Pets/rat.rsi
state: rat state: rat
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: BaseAntagSpawner
id: CP14SpawnPointLurker
components:
- type: GhostRole
name: cp14-ghost-role-information-name-lurker
description: cp14-ghost-role-information-description-lurker
rules: cp14-ghost-role-information-rules-demiplane #TODO
mindRoles:
- CP14MindRoleDemiplaneAntag
raffle:
settings: default
- type: Sprite
sprite: Markers/jobs.rsi
layers:
- state: green
- sprite: _CP14/Mobs/Monster/lurker.rsi
state: live

View File

@@ -5,6 +5,38 @@
- type: CP14StationAdditionalModifierRule - type: CP14StationAdditionalModifierRule
modifiers: modifiers:
- Geodes - Geodes
- Geodes - type: CP14LurkerHuntRule
- Geodes - type: GameRule
- Geodes minPlayers: 7
- type: AntagSelection
selectionTime: PrePlayerSpawn
definitions:
- definitionKey: Lurker
spawnerPrototype: CP14SpawnPointLurker
min: 1
max: 1
blacklist:
components:
- CP14BackgroundMerkasServant
briefing:
text: cp14-lurker-briefing
- definitionKey: Victim
lateJoinAdditional: true
min: 1
max: 3
playerRatio: 3
blacklist:
components:
- CP14BackgroundMerkasServant
briefing:
text: cp14-lurker-victim-briefing
- definitionKey: Hunter
lateJoinAdditional: true
min: 1
max: 3
playerRatio: 3
whitelist:
components:
- CP14BackgroundMerkasServant
briefing:
text: cp14-lurker-hunter-briefing

View File

@@ -0,0 +1,8 @@
- type: trait
id: CP14BackgroundMerkasServant
name: cp14-trait-bg-merkas-servant-name
description: cp14-trait-bg-merkas-servant-desc
category: CP14Background
cost: 1
components:
- type: CP14BackgroundMerkasServant

View File

@@ -1,7 +1,7 @@
- type: traitCategory - type: traitCategory
id: CP14PhysicalTraits id: CP14PhysicalTraits
name: cp14-trait-category-physical name: cp14-trait-category-physical
maxTraitPoints: 1 maxTraitPoints: 2
- type: traitCategory - type: traitCategory
id: CP14Background id: CP14Background

View File

@@ -6,7 +6,7 @@
description: cp14-trait-blindness-desc description: cp14-trait-blindness-desc
#traitGear: WhiteCane #traitGear: WhiteCane
category: CP14PhysicalTraits category: CP14PhysicalTraits
cost: -2 cost: 2
whitelist: whitelist:
components: components:
- Blindable - Blindable
@@ -18,7 +18,7 @@
name: cp14-trait-mana-wasting-name name: cp14-trait-mana-wasting-name
description: cp14-trait-mana-wasting-desc description: cp14-trait-mana-wasting-desc
category: CP14PhysicalTraits category: CP14PhysicalTraits
cost: -2 cost: 2
whitelist: whitelist:
components: components:
- CP14MagicEnergyContainer - CP14MagicEnergyContainer
@@ -38,7 +38,7 @@
description: cp14-trait-poor-vision-desc description: cp14-trait-poor-vision-desc
#traitGear: ClothingEyesGlasses #traitGear: ClothingEyesGlasses
category: CP14PhysicalTraits category: CP14PhysicalTraits
cost: -1 cost: 1
whitelist: whitelist:
components: components:
- Blindable - Blindable
@@ -51,7 +51,7 @@
name: cp14-trait-narcolepsy-name name: cp14-trait-narcolepsy-name
description: cp14-trait-narcolepsy-desc description: cp14-trait-narcolepsy-desc
category: CP14PhysicalTraits category: CP14PhysicalTraits
cost: -1 cost: 1
components: components:
- type: Narcolepsy - type: Narcolepsy
timeBetweenIncidents: 300, 600 timeBetweenIncidents: 300, 600
@@ -61,7 +61,7 @@
id: CP14Muted id: CP14Muted
name: cp14-trait-muted-name name: cp14-trait-muted-name
description: cp14-trait-muted-desc description: cp14-trait-muted-desc
cost: -1 cost: 1
category: CP14PhysicalTraits category: CP14PhysicalTraits
components: components:
- type: Muted - type: Muted
@@ -70,7 +70,7 @@
id: CP14PainNumbness id: CP14PainNumbness
name: trait-painnumbness-name name: trait-painnumbness-name
description: trait-painnumbness-desc description: trait-painnumbness-desc
cost: -1 cost: 1
category: CP14PhysicalTraits category: CP14PhysicalTraits
components: components:
- type: PainNumbness - type: PainNumbness