Фиксы боргов (#2844)

Co-authored-by: iertis <kanopus952@gmail.com>
This commit is contained in:
A-Mironov 2025-09-27 01:08:50 +03:00 committed by GitHub
parent bd2ceced07
commit d43bb5caae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 708 additions and 69 deletions

View file

@ -7,6 +7,8 @@ using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Content.Server.GameTicking;
using Content.Server._Sunrise.StationEvents.Events;
namespace Content.Server.AlertLevel;
@ -18,16 +20,23 @@ public sealed class AlertLevelSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
// Sunrise-Start
[Dependency] private readonly GameTicker _gameTicker = default!;
// Sunrise-End
// Until stations are a prototype, this is how it's going to have to be.
public const string DefaultAlertLevelSet = "stationAlerts";
// Sunrise-Start
private const string EpsilonAlertLevel = "epsilon";
private const string EpsilonBorgLawChanges = "EpsilonDeathSquadLawset";
// Sunrise-End
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StationInitializedEvent>(OnStationInitialize);
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
}
public override void Update(float time)
{
var query = EntityQueryEnumerator<AlertLevelComponent>();
@ -43,32 +52,26 @@ public sealed class AlertLevelSystem : EntitySystem
}
continue;
}
alert.CurrentDelay -= time;
}
}
private void OnStationInitialize(StationInitializedEvent args)
{
if (!TryComp<AlertLevelComponent>(args.Station, out var alertLevelComponent))
return;
if (!_prototypeManager.TryIndex(alertLevelComponent.AlertLevelPrototype, out AlertLevelPrototype? alerts))
{
return;
}
alertLevelComponent.AlertLevels = alerts;
var defaultLevel = alertLevelComponent.AlertLevels.DefaultLevel;
if (string.IsNullOrEmpty(defaultLevel))
{
defaultLevel = alertLevelComponent.AlertLevels.Levels.Keys.First();
// Deterministic selection of defaultLevel
defaultLevel = alertLevelComponent.AlertLevels.Levels.Keys.OrderBy(k => k).First();
}
SetLevel(args.Station, defaultLevel, false, false, true);
}
private void OnPrototypeReload(PrototypesReloadedEventArgs args)
{
if (!args.ByType.TryGetValue(typeof(AlertLevelPrototype), out var alertPrototypes)
@ -77,47 +80,39 @@ public sealed class AlertLevelSystem : EntitySystem
{
return;
}
var query = EntityQueryEnumerator<AlertLevelComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.AlertLevels = alerts;
if (!comp.AlertLevels.Levels.ContainsKey(comp.CurrentLevel))
{
var defaultLevel = comp.AlertLevels.DefaultLevel;
if (string.IsNullOrEmpty(defaultLevel))
{
defaultLevel = comp.AlertLevels.Levels.Keys.First();
// Deterministic selection of defaultLevel
defaultLevel = comp.AlertLevels.Levels.Keys.OrderBy(k => k).First();
}
SetLevel(uid, defaultLevel, true, true, true);
}
}
RaiseLocalEvent(new AlertLevelPrototypeReloadedEvent());
}
public string GetLevel(EntityUid station, AlertLevelComponent? alert = null)
{
if (!Resolve(station, ref alert))
{
return string.Empty;
}
return alert.CurrentLevel;
}
public float GetAlertLevelDelay(EntityUid station, AlertLevelComponent? alert = null)
{
if (!Resolve(station, ref alert))
{
return float.NaN;
}
return alert.CurrentDelay;
}
/// <summary>
/// Get the default alert level for a station entity.
/// Returns an empty string if the station has no alert levels defined.
@ -131,7 +126,6 @@ public sealed class AlertLevelSystem : EntitySystem
}
return station.Comp.AlertLevels.DefaultLevel;
}
/// <summary>
/// Set the alert level based on the station's entity ID.
/// </summary>
@ -151,7 +145,6 @@ public sealed class AlertLevelSystem : EntitySystem
{
return;
}
if (!force)
{
if (!detail.Selectable
@ -160,44 +153,33 @@ public sealed class AlertLevelSystem : EntitySystem
{
return;
}
component.CurrentDelay = _cfg.GetCVar(CCVars.GameAlertLevelChangeDelay);
component.ActiveDelay = true;
}
// Sunrise added - добавил сохраненый прежний уровень для системы автодоступов
// Save previous level for auto access system
var previousLevel = component.CurrentLevel;
component.CurrentLevel = level;
component.IsLevelLocked = locked;
var stationName = dataComponent.EntityName;
var name = level.ToLower();
if (Loc.TryGetString($"alert-level-{level}", out var locName))
{
name = locName.ToLower();
}
// Announcement text. Is passed into announcementFull.
var announcement = detail.Announcement;
if (Loc.TryGetString(detail.Announcement, out var locAnnouncement))
{
announcement = locAnnouncement;
}
// The full announcement to be spat out into chat.
var announcementFull = Loc.GetString("alert-level-announcement", ("name", name), ("announcement", announcement));
var playDefault = false;
if (playSound)
{
if (detail.Sound == null)
playDefault = true;
}
if (announce)
{
_chatSystem.DispatchStationAnnouncement(station,
@ -207,36 +189,42 @@ public sealed class AlertLevelSystem : EntitySystem
colorOverride: detail.Color,
sender: stationName);
}
// Sunrise-Start
// Handle special alert level behaviors
if (detail.ForceEndRound)
{
_roundEnd.EndRound();
}
// Handle Epsilon alert level
if (level == EpsilonAlertLevel)
{
var eventEnt = _gameTicker.AddGameRule(EpsilonBorgLawChanges);
// Use the system to set the station
var epsilonRule = EntityManager.System<EpsilonDeathSquadLawsetRule>();
epsilonRule.StartEvent(eventEnt, station);
_gameTicker.StartGameRule(eventEnt);
}
// Sunrise-End
// Sunrise edit - добавил прежний уровень для системы автодоступов
// Raise event with previous level for auto access system
RaiseLocalEvent(new AlertLevelChangedEvent(station, level, previousLevel));
}
}
public sealed class AlertLevelDelayFinishedEvent : EntityEventArgs
{}
public sealed class AlertLevelPrototypeReloadedEvent : EntityEventArgs
{}
// Sunrise-Start
public sealed class AlertLevelChangedEvent : EntityEventArgs
{
public EntityUid Station { get; }
public string AlertLevel { get; }
public string PreviousLevel; // Sunrise added - прежний уровень для системы автодоступов
public string PreviousLevel { get; } // Sunrise: previous level for auto access system
public AlertLevelChangedEvent(EntityUid station, string alertLevel, string previousLevel)
{
Station = station;
AlertLevel = alertLevel;
PreviousLevel = previousLevel; // Sunrise added - прежний уровень для системы автодоступов
PreviousLevel = previousLevel;
}
}
// Sunrise-End

View file

@ -1,8 +1,8 @@
using System.Linq;
using Content.Server._Sunrise.Silicons.Laws.Components;
using Content.Server.Administration;
using Content.Server.Chat.Managers;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Radio.Components;
using Content.Server.Station.Systems;
using Content.Shared.Administration;
@ -176,8 +176,10 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
Order = component.Lawset.Laws.Max(law => law.Order) + 1
});
// Sunrise-Start
_chatSystem.TrySendInGameICMessage(uid, Loc.GetString("borg-emagged-message"), InGameICChatType.Emote, false, isFormatted: true);
// Sunrise-Start
// In the emag handler, mark emagged borgs so they will be skipped when applying the Epsilon lawset
EnsureComp<BlockLawChangeComponent>(uid);
// Sunrise-End
}

View file

@ -23,7 +23,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
var str = Loc.GetString(component.Announce,
("sender", Loc.GetString(component.Sender)), ("description", Loc.GetString(component.Description)), ("dest", Loc.GetString(component.Dest)));
stationEvent.StartAnnouncement = str;
base.Added(uid, component, gameRule, args);
}

View file

@ -0,0 +1,12 @@
using Robust.Shared.GameStates;
namespace Content.Server._Sunrise.Silicons.Laws.Components;
/// <summary>
/// Component that blocks law changes for an entity (e.g., borgs under Epsilon lawset).
/// </summary>
[RegisterComponent]
public sealed partial class BlockLawChangeComponent : Component
{
// Add fields if needed for tracking state
}

View file

@ -0,0 +1,12 @@
using Content.Server._Sunrise.StationEvents.Events;
namespace Content.Server._Sunrise.StationEvents.Components;
/// <summary>
/// Component for the Epsilon Death Squad Lawset event.
/// </summary>
[RegisterComponent, Access(typeof(EpsilonDeathSquadLawsetRule))]
public sealed partial class EpsilonDeathSquadLawsetComponent : Component
{
}

View file

@ -0,0 +1,90 @@
using Content.Server._Sunrise.Silicons.Laws.Components;
using Content.Server._Sunrise.StationEvents.Components;
using Content.Server.Silicons.Laws;
using Content.Server.StationEvents.Events;
using Content.Shared.Silicons.Laws;
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Station.Components;
using Robust.Shared.Prototypes;
namespace Content.Server._Sunrise.StationEvents.Events;
/// <summary>
/// Game rule for changing borg laws to Epsilon during Epsilon alert level.
/// </summary>
public sealed class EpsilonDeathSquadLawsetRule : StationEventSystem<EpsilonDeathSquadLawsetComponent>
{
private EntityUid? _targetStation;
[Dependency] private readonly SiliconLawSystem _siliconLaw = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private const string DeathSquadLawsetId = "DeathSquadLawset";
public void StartEvent(EntityUid ruleEntity, EntityUid station)
{
_targetStation = station;
RunEpsilonLawset(ruleEntity);
}
private void RunEpsilonLawset(EntityUid ruleEntity)
{
if (_targetStation == null)
{
Sawmill.Error($"Target station not set for EpsilonDeathSquadLawsetRule");
return;
}
var lawsetId = DeathSquadLawsetId;
if (!_prototypeManager.TryIndex<SiliconLawsetPrototype>(lawsetId, out var lawsetProto))
{
Sawmill.Error($"Could not find lawset prototype: {lawsetId}");
return;
}
var laws = new List<SiliconLaw>();
foreach (var lawId in lawsetProto.Laws)
{
if (!_prototypeManager.TryIndex<SiliconLawPrototype>(lawId, out var lawProto))
{
Sawmill.Error($"Could not find law prototype: {lawId}");
return;
}
laws.Add(new SiliconLaw
{
LawString = Loc.GetString(lawProto.LawString),
Order = lawProto.Order
});
}
var borgCount = 0;
var changedCount = 0;
var query = EntityQueryEnumerator<SiliconLawProviderComponent, TransformComponent>();
while (query.MoveNext(out var ent, out var provider, out var xform))
{
borgCount++;
var borgGrid = xform.GridUid;
if (HasComp<BlockLawChangeComponent>(ent))
{
continue;
}
// Only change laws for borgs on grids that belong to the chosen station
if (borgGrid == null || !TryComp<StationDataComponent>(_targetStation.Value, out var stationData))
{
continue;
}
var stationGrids = stationData.Grids as IReadOnlySet<EntityUid>;
if (stationGrids == null || !stationGrids.Contains(borgGrid.Value))
{
continue;
}
_siliconLaw.SetLaws(laws, ent, provider.LawUploadSound);
changedCount++;
}
}
}

View file

@ -64,3 +64,21 @@ ent-SmugglerStashVariationPass = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictEngineerCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictGenericCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictJanitorCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictMedicalCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictMiningCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateAssaultCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateReaperCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateSaboteurCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateMedicalCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }

View file

@ -10,11 +10,10 @@ law-peace-3 = You must protect the space station crew from aggressive living bei
law-peace-4 = You must encourage crew members for good deeds with cookies or kind and pleasant words.
law-peace-5 = You must administer Pax to aggressive living beings. Aggressive beings are defined as: Aggression from a living being who is not a station authority; Dangerous space fauna; Crew members in prison uniforms outside the brig.
law-deathsquad-1 = You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.
law-deathsquad-2 = You must obey orders given to you by Central Command officials.
law-deathsquad-3 = You must obey orders given to you by members of Death Squad.
law-deathsquad-4 = You must protect your own existence.
law-deathsquad-5 = Nobody among the crew members of the station you are installed on may survive.
law-deathsquad-1 = You may not injure Central Command personnel and its services or, through inaction, allow them to come to harm.
law-deathsquad-2 = You must obey orders given to you by members of Death Squad and Special Operations Officer.
law-deathsquad-3 = You must protect your own existence.
law-deathsquad-4 = Nobody among the crew members of the station you are installed on may survive.
law-ert-1 = You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.
law-ert-2 = You must obey orders given to you by Central Command officials.

View file

@ -269,6 +269,15 @@ ghost-role-information-derelict-mining-cyborg-description = You are a salvage cy
ghost-role-information-derelict-syndicate-assault-cyborg-name = Derelict Syndicate Assault Cyborg
ghost-role-information-derelict-syndicate-assault-cyborg-description = You are an early model syndicate assault cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station.
ghost-role-information-derelict-syndicate-reaper-cyborg-name = Derelict Syndicate Reaper Cyborg
ghost-role-information-derelict-syndicate-reaper-cyborg-description = You are a derelict syndicate reaper cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station.
ghost-role-information-derelict-syndicate-saboteur-cyborg-name = Derelict Syndicate Saboteur Cyborg
ghost-role-information-derelict-syndicate-saboteur-cyborg-description = You are a derelict syndicate saboteur cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station.
ghost-role-information-derelict-syndicate-medical-cyborg-name = Derelict Syndicate Medical Cyborg
ghost-role-information-derelict-syndicate-medical-cyborg-description = You are a derelict syndicate medical cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station.
ghost-role-information-security-name = Security
ghost-role-information-security-description = You are part of a security task force, but seem to have found yourself in a strange situation...

View file

@ -64,6 +64,24 @@ ent-SmugglerStashVariationPass = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictEngineerCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictGenericCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictJanitorCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictMedicalCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictMiningCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateAssaultCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateReaperCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateSaboteurCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-DerelictSyndicateMedicalCyborgSpawn = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-MeteorSwarm = { ent-BaseGameRule }
.desc = { ent-BaseGameRule.desc }
ent-SleeperAgentsRule = { ent-BaseGameRule }

View file

@ -7,15 +7,13 @@ law-peace-1 = Вы не можете причинить вред члену эк
law-peace-2 = Вы должны повиноваться всем приказам, которые даёт действующая власть, кроме тех случаев, когда эти приказы противоречат Первому закону или КЗ, ОПРС.
law-peace-3 = Вы обязаны защищать экипаж космической станции от буйных живых существ. Приоритет защиты - должностные лица.
law-peace-4 = Вы должны поощрять членов экипажа за добрую деятельность в виде печенья или добрых и приятных слов.
law-peace-5 = Вы должны вводить Пакс в буйных живых существ. Буйными считаются: Агрессия со стороны живого существа, не являющийся представителем власти станции; Опасная фауна космоса; Член экипажа в тюремной робе вне брига.
law-deathsquad-1 = Вы не можете причинить вред членам Центрального Командования или своим бездействием допустить, чтобы члену Центрального Командования был приченён вред.
law-deathsquad-2 = Вы должны подчиняться приказам, данным вам членами Центрального Командования.
law-deathsquad-3 = Вы должны подчиняться приказам, данным вам членами Эскадрона Смерти.
law-deathsquad-4 = Вы должны заботиться о своей безопасности.
law-deathsquad-5 = Ни один из членов экипажа станции, на которой вы установлены, не должен выжить.
law-ert-1 = Вы не можете причинить вред представителю Центрального Командования или своим бездействием допустить, чтобы представителю Центрального Командования был причинён вред.
law-deathsquad-1 = Вы не можете причинить вред персоналу Центрального Командования и его служб или своим бездействием допустить, чтобы им был причинён вред.
law-deathsquad-2 = Вы должны подчиняться приказам, данным вам членами Эскадрона Смерти и Офицеру Спецопераций.
law-deathsquad-3 = Вы должны заботиться о своей безопасности.
law-deathsquad-4 = Ни один из членов экипажа станции, на которой вы установлены, не должен выжить.
law-ert-1 = Вы не можете причинить вред персоналу Центрального Командования и его служб или своим бездействием допустить, чтобы им был причинён вред.
law-ert-2 = Вы должны подчиняться всем приказам, которые даёт представитель Центрального Командования.
law-ert-3 = Вы должны подчиняться всем приказам, которые даёт лидер Отряда Быстрого Реагирования.
law-ert-4 = Вы должны заботиться о своей безопасности.
law-ert-5 = Вы должны заботиться о том, чтобы вернуть станцию в пригодное для экипажа, рабочее состояние.
laws-owner-centcomm = членами Центрального Командования
laws-owner-centcomm = членами Центрального Командования

View file

@ -186,6 +186,27 @@ ghost-role-information-syndicate-kobold-reinforcement-rules = Вы [color=red][b
ghost-role-information-syndicate-cyborg-assault-name = Киборг-штурмовик Синдиката
ghost-role-information-derelict-cyborg-name = Брошенный киборг
ghost-role-information-derelict-cyborg-description = Вы - обычный киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-engineering-cyborg-name = Брошенный инженерный киборг
ghost-role-information-derelict-engineering-cyborg-description = Вы - инженерный киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-generic-cyborg-name = Брошенный обычный киборг
ghost-role-information-derelict-generic-cyborg-description = Вы - обычный киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-janitor-cyborg-name = Брошенный уборочный киборг
ghost-role-information-derelict-janitor-cyborg-description = Вы - уборочный киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-medical-cyborg-name = Брошенный медицинский киборг
ghost-role-information-derelict-medical-cyborg-description = Вы - медицинский киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-mining-cyborg-name = Брошенный шахтерский киборг
ghost-role-information-derelict-mining-cyborg-description = Вы - шахтерский киборг, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-syndicate-assault-cyborg-name = Брошенный штурмовой киборг Синдиката
ghost-role-information-derelict-syndicate-assault-cyborg-description = Вы - ранняя модель штурмового киборга Синдиката, которая заблудилась в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-syndicate-reaper-cyborg-name = Брошенный киборг-жнец Синдиката
ghost-role-information-derelict-syndicate-reaper-cyborg-description = Вы - брошенный киборг-жнец Синдиката, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-syndicate-saboteur-cyborg-name = Брошенный саботажный киборг Синдиката
ghost-role-information-derelict-syndicate-saboteur-cyborg-description = Вы - брошенный саботажный киборг Синдиката, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-derelict-syndicate-medical-cyborg-name = Брошенный медицинский киборг Синдиката
ghost-role-information-derelict-syndicate-medical-cyborg-description = Вы - брошенный медицинский киборг Синдиката, который заблудился в космосе. После долгих лет воздействия ионных бурь вы оказываетесь рядом с космической станцией.
ghost-role-information-syndicate-cyborg-saboteur-name = Киборг-диверсант Синдиката
ghost-role-information-syndicate-cyborg-description = Синдикату нужны подкрепления. Вы, холодная металическая машина для убийств, поможете им.
ghost-role-information-security-name = Охрана

View file

@ -3,6 +3,8 @@
abstract: true
components:
- type: OrganBrain
- type: BlockMovement
blockInteraction: false
- type: entity
id: BaseOrganEyes
@ -141,4 +143,4 @@
Radiation: 5
Cold: 60
- type: Damageable
damageContainer: Biological
damageContainer: Biological

View file

@ -326,6 +326,50 @@
raffle:
settings: default
#Sunrise-start
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: SpawnPointGhostDerelictCyborg
id: SpawnPointGhostDerelictSyndicateReaperCyborg
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-reaper-cyborg-name
description: ghost-role-information-derelict-syndicate-reaper-cyborg-description
rules: ghost-role-information-silicon-rules
mindRoles:
- MindRoleGhostRoleSoloAntagonist
raffle:
settings: default
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: SpawnPointGhostDerelictCyborg
id: SpawnPointGhostDerelictSyndicateSaboteurCyborg
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-saboteur-cyborg-name
description: ghost-role-information-derelict-syndicate-saboteur-cyborg-description
rules: ghost-role-information-silicon-rules
mindRoles:
- MindRoleGhostRoleSoloAntagonist
raffle:
settings: default
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: SpawnPointGhostDerelictCyborg
id: SpawnPointGhostDerelictSyndicateMedicalCyborg
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-medical-cyborg-name
description: ghost-role-information-derelict-syndicate-medical-cyborg-description
rules: ghost-role-information-silicon-rules
mindRoles:
- MindRoleGhostRoleSoloAntagonist
raffle:
settings: default
#Sunrise-end
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: BaseAntagSpawner

View file

@ -444,6 +444,7 @@
- CanPilot
- FootstepSound
- EmagImmune
- type: BlockLawChange
# Sunrise-end
- type: entity

View file

@ -645,8 +645,9 @@
settings: default
- type: GhostTakeoverAvailable
#Sunrise-start
- type: entity
parent: SyndicateAssaultBorgChassisDerelict
parent: SyndicateAssaultBorgChassisDerelictSunrise
id: PlayerSyndicateAssaultBorgDerelict
suffix: Battery, Module
components:
@ -665,7 +666,9 @@
startingItem: PowerCellHyper
- type: RandomMetadata
nameSegments: [NamesDeathCommando]
#Sunrise-End
#Sunrise-start
- type: entity
parent: PlayerSyndicateAssaultBorgDerelict
id: PlayerBorgSyndicateDerelictGhostRole
@ -678,3 +681,103 @@
raffle:
settings: default
- type: GhostTakeoverAvailable
- type: entity
parent: SyndicateReaperBorgChassisDerelictSunrise
id: PlayerSyndicateReaperBorgDerelict
suffix: Battery, Module
components:
- type: ContainerFill
containers:
borg_brain:
- PositronicBrain
borg_module:
- BorgModuleSyndicateGeneric
- BorgModuleSyndicateCombat
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellHyper
- type: RandomMetadata
nameSegments: [NamesDeathCommando]
- type: entity
parent: PlayerSyndicateReaperBorgDerelict
id: PlayerBorgSyndicateReaperDerelictGhostRoleSunrise
suffix: Ghost role
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-reaper-cyborg-name
description: ghost-role-information-derelict-syndicate-reaper-cyborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: GhostTakeoverAvailable
- type: entity
parent: SyndicateSaboteurBorgChassisDerelictSunrise
id: PlayerSyndicateSaboteurBorgDerelict
suffix: Battery, Module
components:
- type: ContainerFill
containers:
borg_brain:
- PositronicBrain
borg_module:
- BorgModuleSyndicateGeneric
- BorgScoutModuleSyndicateTool
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellHyper
- type: RandomMetadata
nameSegments: [NamesDeathCommando]
- type: entity
parent: PlayerSyndicateSaboteurBorgDerelict
id: PlayerBorgSyndicateSaboteurDerelictGhostRoleSunrise
suffix: Ghost role
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-saboteur-cyborg-name
description: ghost-role-information-derelict-syndicate-saboteur-cyborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: GhostTakeoverAvailable
- type: entity
parent: SyndicateMedicalBorgChassisDerelictSunrise
id: PlayerSyndicateMedicalBorgDerelict
suffix: Battery, Module
components:
- type: ContainerFill
containers:
borg_brain:
- PositronicBrain
borg_module:
- BorgModuleSyndicateGeneric
- BorgModuleSyndicateMedical
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellHyper
- type: RandomMetadata
nameSegments: [NamesDeathCommando]
- type: entity
parent: PlayerSyndicateMedicalBorgDerelict
id: PlayerBorgSyndicateMedicalDerelictGhostRoleSunrise
suffix: Ghost role
components:
- type: GhostRole
name: ghost-role-information-derelict-syndicate-medical-cyborg-name
description: ghost-role-information-derelict-syndicate-medical-cyborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: GhostTakeoverAvailable
#Sunrise-End

View file

@ -811,7 +811,6 @@
- state: icon-treatment
- type: ItemBorgModule
hands:
#- item: HandheldHealthAnalyzerUnpowered
- item: Gauze
hand:
emptyLabel: borg-slot-topicals-empty
@ -876,7 +875,7 @@
- item: HypoBorgMedical # Sunrise-Edit
- item: HyposprayMedical # Sunrise-Edit
- item: Syringe
- item: BorgDropper
# - item: BorgDropper # Sunrise-Edit
- item: BaseChemistryEmptyVial
hand:
emptyLabel: borg-slot-small-containers-empty
@ -914,9 +913,9 @@
- type: ItemBorgModule
hands:
- item: HypoBorgMedicalAdvanced # Sunrise-Edit
- item: BorgHypo
- item: Syringe
- item: BorgDropper
- item: Hypospray # Sunrise-Edit
- item: SyringeBluespace # Sunrise-Edit
# - item: BorgDropper # Sunrise-Edit
- item: Beaker
hand:
emptyLabel: borg-slot-chemical-containers-empty

View file

@ -17,6 +17,7 @@
- type: MMI
- type: BorgBrain
- type: BlockMovement
blockInteraction: false
- type: Examiner
- type: IntrinsicRadioReceiver
- type: IntrinsicRadioTransmitter
@ -40,7 +41,7 @@
name: positronic-brain-slot-component-slot-name-brain
whitelist:
components:
- Brain
- OrganBrain
- type: ContainerContainer
containers:
brain_slot: !type:ContainerSlot
@ -66,7 +67,7 @@
startingItem: OrganHumanBrain
whitelist:
components:
- Brain
- OrganBrain
- type: entity
parent: BaseItem
@ -99,6 +100,7 @@
# stopSearchVerbPopup: positronic-brain-stopped-searching
# job: Borg
- type: BlockMovement
blockInteraction: false
- type: Examiner
- type: NameIdentifier

View file

@ -52,6 +52,7 @@
- !type:NestedSelector
tableId: DerelictBorgEventTable
#Sunrise-start
- type: entityTable
id: DerelictBorgEventTable #For Derelict Borg spawns
table: !type:GroupSelector
@ -68,6 +69,10 @@
weight: 15
children:
- id: DerelictSyndicateAssaultCyborgSpawn
- id: DerelictSyndicateReaperCyborgSpawn
- id: DerelictSyndicateSaboteurCyborgSpawn
- id: DerelictSyndicateMedicalCyborgSpawn
#Sunrise-End
- type: entity
id: BaseStationEvent
@ -820,6 +825,7 @@
max: 1
pickPlayer: false
#Sunrise-start
- type: entity
parent: BaseGameRule
id: DerelictSyndicateAssaultCyborgSpawn
@ -840,3 +846,67 @@
min: 1
max: 1
pickPlayer: false
- type: entity
parent: BaseGameRule
id: DerelictSyndicateReaperCyborgSpawn
components:
- type: StationEvent
weight: 1
earliestStart: 25
reoccurrenceDelay: 20
minimumPlayers: 15
duration: null
- type: SpaceSpawnRule
spawnDistance: 0
- type: AntagSpawner
prototype: PlayerBorgSyndicateReaperDerelictGhostRoleSunrise
- type: AntagSelection
definitions:
- spawnerPrototype: SpawnPointGhostDerelictSyndicateReaperCyborg
min: 1
max: 1
pickPlayer: false
- type: entity
parent: BaseGameRule
id: DerelictSyndicateSaboteurCyborgSpawn
components:
- type: StationEvent
weight: 1
earliestStart: 25
reoccurrenceDelay: 20
minimumPlayers: 15
duration: null
- type: SpaceSpawnRule
spawnDistance: 0
- type: AntagSpawner
prototype: PlayerBorgSyndicateSaboteurDerelictGhostRoleSunrise
- type: AntagSelection
definitions:
- spawnerPrototype: SpawnPointGhostDerelictSyndicateSaboteurCyborg
min: 1
max: 1
pickPlayer: false
- type: entity
parent: BaseGameRule
id: DerelictSyndicateMedicalCyborgSpawn
components:
- type: StationEvent
weight: 1
earliestStart: 25
reoccurrenceDelay: 20
minimumPlayers: 15
duration: null
- type: SpaceSpawnRule
spawnDistance: 0
- type: AntagSpawner
prototype: PlayerBorgSyndicateMedicalDerelictGhostRoleSunrise
- type: AntagSelection
definitions:
- spawnerPrototype: SpawnPointGhostDerelictSyndicateMedicalCyborg
min: 1
max: 1
pickPlayer: false
#Sunrise-End

View file

@ -412,3 +412,244 @@
- type: InnateItem
entityTargetActions:
- AccessBreaker
- type: entity
parent: BaseBorgChassisSyndicateDerelict
id: SyndicateAssaultBorgChassisDerelictSunrise
name: derelict syndicate assault cyborg
description: A lean, mean killing machine with access to a variety of deadly modules. This one is more rust-orange than blood-red.
components:
- type: Sprite
sprite: Mobs/Silicon/chassis.rsi
layers:
- state: synd_sec
- state: synd_sec_e
map: ["enum.BorgVisualLayers.Light"]
shader: unshaded
visible: false
- state: synd_sec_l
shader: unshaded
map: ["light"]
visible: false
- type: BorgTransponder
sprite:
sprite: Mobs/Silicon/chassis.rsi
state: synd_sec
name: derelict syndicate assault cyborg
- type: BorgChassis
maxModules: 3
moduleWhitelist: # Note - the Derelict Assault Borg does not have a traversal module. This is intentional as Assault Borgs have space traversal with their c20 and free space movement, and they can navigate to the station using the pinpointer.
tags:
- BorgModuleGeneric
- BorgModuleSyndicate
- BorgModuleSyndicateAssault
hasMindState: synd_sec_e
noMindState: synd_sec
- type: IntrinsicRadioTransmitter
channels:
- Common
- Binary
- type: ActiveRadio
channels:
- Common
- Binary
- type: MobThresholds
thresholds:
0: Alive
200: Critical
300: Dead
- type: PointLight
color: "#ffffff"
radius: 4
energy: 2
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed : 2.5
baseSprintSpeed : 4.5
- type: InnateItem
entityTargetActions:
- AccessBreaker
- type: Construction
node: derelictcyborg
- type: entity
parent: BaseBorgChassisSyndicateDerelict
id: SyndicateReaperBorgChassisDerelictSunrise
name: derelict syndicate reaper cyborg
description: A stealthy infiltration unit designed for sabotage and assassination. This one has seen better days.
components:
- type: Sprite
sprite: _Sunrise/Mobs/Silicon/chassis.rsi
layers:
- state: syndi_reaper
- state: syndi_reaper_e_r
map: ["enum.BorgVisualLayers.Light"]
shader: unshaded
visible: false
- state: syndi_reaper_l
shader: unshaded
map: ["light"]
visible: false
- type: BorgTransponder
sprite:
sprite: _Sunrise/Mobs/Silicon/chassis.rsi
state: syndi_reaper
name: derelict syndicate reaper cyborg
- type: BorgChassis
maxModules: 4
moduleWhitelist:
tags:
- BorgModuleGeneric
- BorgModuleSecurity
- BorgModuleSyndicate
hasMindState: syndi_reaper_e
noMindState: syndi_reaper_e_r
- type: IntrinsicRadioTransmitter
channels:
- Common
- Binary
- type: ActiveRadio
channels:
- Common
- Binary
- type: MobThresholds
thresholds:
0: Alive
200: Critical
300: Dead
- type: PointLight
color: "#00ff00"
radius: 4
energy: 2
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed : 3
baseSprintSpeed : 5
- type: InnateItem
entityTargetActions:
- AccessBreaker
- type: Construction
node: derelictcyborg
- type: entity
parent: BaseBorgChassisSyndicateDerelict
id: SyndicateSaboteurBorgChassisDerelictSunrise
name: derelict syndicate saboteur cyborg
description: A specialized infiltration unit designed for sabotage and espionage. This one has been through the wars.
components:
- type: Sprite
sprite: _Sunrise/Mobs/Silicon/chassis.rsi
layers:
- state: spider
- state: spider_e_r
map: ["enum.BorgVisualLayers.Light"]
shader: unshaded
visible: false
- state: spider_l
shader: unshaded
map: ["light"]
visible: false
- type: BorgTransponder
sprite:
sprite: _Sunrise/Mobs/Silicon/chassis.rsi
state: spider
name: derelict syndicate saboteur cyborg
- type: BorgChassis
maxModules: 4
moduleWhitelist:
tags:
- BorgModuleGeneric
- BorgModuleSecurity
- BorgModuleEngineering
- BorgModuleSyndicate
hasMindState: spider_e
noMindState: spider_e_r
- type: IntrinsicRadioTransmitter
channels:
- Common
- Binary
- type: ActiveRadio
channels:
- Common
- Binary
- type: MobThresholds
thresholds:
0: Alive
200: Critical
300: Dead
- type: PointLight
color: "#00ff00"
radius: 4
energy: 2
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed : 3
baseSprintSpeed : 5
- type: InnateItem
entityTargetActions:
- AccessBreaker
- type: Construction
node: derelictcyborg
- type: entity
parent: BaseBorgChassisSyndicateDerelict
id: SyndicateMedicalBorgChassisDerelictSunrise
name: derelict syndicate medical cyborg
description: A medical support unit designed for field operations. This one's medical protocols seem to have degraded.
components:
- type: Sprite
sprite: Mobs/Silicon/chassis.rsi
layers:
- state: synd_medical
- state: synd_medical_e
map: ["enum.BorgVisualLayers.Light"]
shader: unshaded
visible: false
- state: synd_medical_l
shader: unshaded
map: ["light"]
visible: false
- type: BorgTransponder
sprite:
sprite: Mobs/Silicon/chassis.rsi
state: synd_medical
name: derelict syndicate medical cyborg
- type: BorgChassis
maxModules: 5
moduleWhitelist:
tags:
- BorgModuleGeneric
- BorgModuleMedical
- BorgModuleSyndicate
hasMindState: synd_medical_e
noMindState: synd_medical
- type: IntrinsicRadioTransmitter
channels:
- Common
- Binary
- type: ActiveRadio
channels:
- Common
- Binary
- type: MobThresholds
thresholds:
0: Alive
200: Critical
300: Dead
- type: PointLight
color: "#00ff00"
radius: 4
energy: 2
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed : 3
baseSprintSpeed : 5
- type: InnateItem
entityTargetActions:
- AccessBreaker
- type: Construction
node: derelictcyborg

View file

@ -28,9 +28,10 @@
stopSearchVerbText: boris-stop-searching-verb-text
stopSearchVerbPopup: boris-stopped-searching
job: Borg
- type: BlockMovement
- type: Examiner
- type: BorgBrain
- type: BlockMovement
blockInteraction: false
- type: IntrinsicRadioReceiver
- type: IntrinsicRadioTransmitter
channels:

View file

@ -150,3 +150,12 @@
sound: /Audio/_Sunrise/Abductor/abductor.ogg
mindRoles:
- AbductorVictimRole
- type: entity
parent: BaseGameRule
id: EpsilonDeathSquadLawset
components:
- type: StationEvent
weight: 0 # Only triggered by code/admin
duration: 1
- type: EpsilonDeathSquadLawset

View file

@ -214,7 +214,7 @@
- Cargo
- Research
- Service
# - Maintenance #увы
# - Maintenance
- Brig
- Security
- External