improvements
This commit is contained in:
@@ -1,36 +1,48 @@
|
||||
# NULL DEPTH — level mapa
|
||||
|
||||
## Grid
|
||||
## Grid (Orientácia: Zospodu nahor / Bottom-to-Top)
|
||||
|
||||
```text
|
||||
[06 Operations]
|
||||
[15 Server Core (1,0)]
|
||||
|
|
||||
[01 Exterior]—[02 Security]—[03 Main]—[07 Elevator]
|
||||
| |
|
||||
[05 Staff]—[04 Maint] [08 Landing]—[09 Cooling]—[12 Passage]—[13 Observation]—[14 Core Access]—[15 Core]
|
||||
| |
|
||||
[11 Storage] [10 Cooling Ctrl]
|
||||
[14 Core Access (1,1)]
|
||||
|
|
||||
[13 Observation Room (1,2)]
|
||||
|
|
||||
[12 Service Passage (1,3)]
|
||||
|
|
||||
[09 Cooling Junction (1,4)]—[10 Cooling Control (2,4)]
|
||||
|
|
||||
[11 Storage (0,5)]—[08 Lower Landing (1,5)]
|
||||
|
|
||||
[07 Service Elevator (1,6)]
|
||||
|
|
||||
[06 Operations (0,7)]—[03 Main Corridor (1,7)]—[04 Maint (2,7)]—[05 Staff (3,7)]
|
||||
|
|
||||
[02 Security Lobby (1,8)]
|
||||
|
|
||||
[01 Exterior Access (1,9)]
|
||||
```
|
||||
|
||||
Súradnice v `game.json` používajú `x: 0–8`, `y: 0–3`. Minimapa odhaľuje iba navštívené miestnosti.
|
||||
Súradnice v `game.json` používajú `x: 0–3`, `y: 0–9`. Postup v komplexe začína na dolnom vstupe (y=9) a smeruje na sever do hĺbky jadra (y=0).
|
||||
|
||||
| ID | Lokalita | X,Y | Hlavná funkcia |
|
||||
|---|---|---:|---|
|
||||
| loc_01 | Exterior Access | 0,1 | identifikácia kontraktora, prvý checkpoint |
|
||||
| loc_02 | Security Lobby | 1,1 | stav personálu |
|
||||
| loc_03 | Main Corridor | 2,1 | centrálny rozbočovač, cesta blokovaná napájaním |
|
||||
| loc_04 | Maintenance Control | 2,2 | obnovenie pomocnej siete, checkpoint |
|
||||
| loc_05 | Staff Access | 1,2 | Log 01 |
|
||||
| loc_06 | Operations Room | 2,0 | záznam o containment |
|
||||
| loc_07 | Service Elevator | 3,1 | klaustrofóbia, zostup, checkpoint |
|
||||
| loc_08 | Lower Landing | 3,2 | rozbočovač dolnej úrovne |
|
||||
| loc_09 | Cooling Junction | 4,2 | Log 02, tepelný zámok |
|
||||
| loc_10 | Cooling Control | 4,3 | voľba chladenie/security, checkpoint |
|
||||
| loc_11 | Equipment Storage | 3,3 | manuálny override alebo smrť |
|
||||
| loc_12 | Service Passage | 5,2 | klaustrofobická udalosť |
|
||||
| loc_13 | Observation Room | 6,2 | Log 03 |
|
||||
| loc_14 | Core Access | 7,2 | rozhovor s AI, ľudská autorizácia |
|
||||
| loc_15 | Server Core | 8,2 | diagnostika a tri konce |
|
||||
| loc_01 | Exterior Access | 1,9 | Identifikácia kontraktora, prvý checkpoint |
|
||||
| loc_02 | Security Lobby | 1,8 | Stav personálu, bezpečnostné kamery |
|
||||
| loc_03 | Main Corridor | 1,7 | Centrálny rozbočovač horného podlažia |
|
||||
| loc_04 | Maintenance Control | 2,7 | Obnovenie pomocnej siete, checkpoint |
|
||||
| loc_05 | Staff Access | 3,7 | Log 01, korešpondencia personálu |
|
||||
| loc_06 | Operations Room | 0,7 | Záznam o containment |
|
||||
| loc_07 | Service Elevator | 1,6 | Klaustrofóbia, zostup výťahom, checkpoint |
|
||||
| loc_08 | Lower Landing | 1,5 | Rozbočovač dolnej úrovne |
|
||||
| loc_09 | Cooling Junction | 1,4 | Log 02, tepelný zámok |
|
||||
| loc_10 | Cooling Control | 2,4 | Voľba chladenie/security, checkpoint |
|
||||
| loc_11 | Equipment Storage | 0,5 | Manuálny override (alebo live bus smrť) |
|
||||
| loc_12 | Service Passage | 1,3 | Klaustrofobický servisný prechod |
|
||||
| loc_13 | Observation Room | 1,2 | Log 03, špecifikácia architektúry jadra |
|
||||
| loc_14 | Core Access | 1,1 | Rozhovor s AI, ľudská autorizácia |
|
||||
| loc_15 | Server Core | 1,0 | Diagnostika a tri finálne konce |
|
||||
|
||||
## Kľúčové flagy
|
||||
|
||||
|
||||
@@ -10,16 +10,21 @@ public sealed class GameService(HttpClient http, IJSRuntime js)
|
||||
private const int CurrentSaveVersion = 3;
|
||||
private const string SaveKey = "null-depth.save.v1";
|
||||
private const string SettingsKey = "null-depth.settings.v1";
|
||||
private const string ProfileKey = "null-depth.profile.v1";
|
||||
private readonly JsonSerializerOptions _json = new(JsonSerializerDefaults.Web);
|
||||
private Dictionary<string, string> _texts = [];
|
||||
|
||||
public GameData Data { get; private set; } = new();
|
||||
public GameState State { get; private set; } = new();
|
||||
public PlayerSettings Settings { get; private set; } = new();
|
||||
public PlayerProfile Profile { get; private set; } = new();
|
||||
public bool HasSave { get; private set; }
|
||||
public SaveLoadResult LastLoadResult { get; private set; } = SaveLoadResult.Missing;
|
||||
public event Action? Saved;
|
||||
|
||||
public int CurrentBpm => CalculateBpm();
|
||||
public string StressStatusKey => CalculateStressStatusKey();
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
Data = await http.GetFromJsonAsync<GameData>("data/game.json", _json) ?? new GameData();
|
||||
@@ -27,6 +32,7 @@ public sealed class GameService(HttpClient http, IJSRuntime js)
|
||||
{
|
||||
Language = await js.InvokeAsync<string>("nullDepth.browserLanguage")
|
||||
};
|
||||
Profile = await LoadValueAsync<PlayerProfile>(ProfileKey) ?? new PlayerProfile();
|
||||
await SetLanguageAsync(Settings.Language, persist: false);
|
||||
var rawSave = await js.InvokeAsync<string?>("localStorage.getItem", SaveKey);
|
||||
HasSave = !string.IsNullOrWhiteSpace(rawSave);
|
||||
@@ -40,6 +46,36 @@ public sealed class GameService(HttpClient http, IJSRuntime js)
|
||||
public ArchiveDefinition? FindArchive(string id) => Data.Archive.FirstOrDefault(a => a.Id == id);
|
||||
public bool HasAll(IEnumerable<string> flags) => flags.All(State.Flags.Contains);
|
||||
|
||||
public int CalculateBpm()
|
||||
{
|
||||
if (State.Flags.Contains("elevator_stalled")) return 128;
|
||||
if (State.CurrentRoomId == "loc_12_service_passage" && !State.Flags.Contains("passage_crossed")) return 118;
|
||||
if (State.CurrentRoomId == "loc_11_equipment_storage" && !State.Flags.Contains("manual_override_found")) return 106;
|
||||
if (State.CurrentRoomId == "loc_14_core_access") return 96;
|
||||
if (State.CurrentRoomId == "loc_15_server_core") return 104;
|
||||
if (State.Flags.Contains("power_restored") && (State.CurrentRoomId == "loc_03_main_corridor" || State.CurrentRoomId == "loc_04_maintenance_control")) return 88;
|
||||
if (State.VisitedRooms.Count > 10) return 82;
|
||||
return 74;
|
||||
}
|
||||
|
||||
public string CalculateStressStatusKey()
|
||||
{
|
||||
var bpm = CurrentBpm;
|
||||
if (bpm >= 120) return "hud.stress.critical";
|
||||
if (bpm >= 95) return "hud.stress.elevated";
|
||||
return "hud.stress.nominal";
|
||||
}
|
||||
|
||||
public string ScanCurrentRoom()
|
||||
{
|
||||
var room = CurrentRoom;
|
||||
if (!string.IsNullOrWhiteSpace(room.ScanKey))
|
||||
{
|
||||
return T(room.ScanKey);
|
||||
}
|
||||
return T("scan.default");
|
||||
}
|
||||
|
||||
public async Task SetLanguageAsync(string language, bool persist = true)
|
||||
{
|
||||
Settings.Language = language == "sk" ? "sk" : "en";
|
||||
@@ -150,11 +186,23 @@ public sealed class GameService(HttpClient http, IJSRuntime js)
|
||||
public IEnumerable<InteractionDefinition> AvailableInteractions() => CurrentRoom.Interactions.Where(i =>
|
||||
HasAll(i.RequiresFlags) && !i.ForbiddenFlags.Any(State.Flags.Contains));
|
||||
|
||||
public IEnumerable<HotspotDefinition> AvailableHotspots() => CurrentRoom.Hotspots.Where(h =>
|
||||
HasAll(h.RequiresFlags) && !h.ForbiddenFlags.Any(State.Flags.Contains));
|
||||
|
||||
public InteractionDefinition? FindInteraction(string id) => CurrentRoom.Interactions.FirstOrDefault(i => i.Id == id);
|
||||
|
||||
public async Task ApplyInteractionAsync(InteractionDefinition interaction)
|
||||
{
|
||||
Apply(interaction.SetFlags, interaction.ClearFlags, interaction.AddItems);
|
||||
if (!string.IsNullOrWhiteSpace(interaction.ArchiveId) && !State.Archive.Contains(interaction.ArchiveId))
|
||||
State.Archive.Add(interaction.ArchiveId);
|
||||
if (!string.IsNullOrWhiteSpace(interaction.ArchiveId))
|
||||
{
|
||||
if (!State.Archive.Contains(interaction.ArchiveId)) State.Archive.Add(interaction.ArchiveId);
|
||||
if (!Profile.DiscoveredArchives.Contains(interaction.ArchiveId))
|
||||
{
|
||||
Profile.DiscoveredArchives.Add(interaction.ArchiveId);
|
||||
await SaveProfileAsync();
|
||||
}
|
||||
}
|
||||
if (interaction.Checkpoint) SetCheckpoint();
|
||||
await SaveAsync();
|
||||
}
|
||||
@@ -162,11 +210,21 @@ public sealed class GameService(HttpClient http, IJSRuntime js)
|
||||
public async Task ApplyChoiceAsync(ChoiceDefinition choice)
|
||||
{
|
||||
Apply(choice.SetFlags, choice.ClearFlags, choice.AddItems);
|
||||
if (!string.IsNullOrWhiteSpace(choice.Ending)) State.CompletedEnding = choice.Ending;
|
||||
if (!string.IsNullOrWhiteSpace(choice.Ending))
|
||||
{
|
||||
State.CompletedEnding = choice.Ending;
|
||||
if (!Profile.UnlockedEndings.Contains(choice.Ending))
|
||||
{
|
||||
Profile.UnlockedEndings.Add(choice.Ending);
|
||||
await SaveProfileAsync();
|
||||
}
|
||||
}
|
||||
if (choice.Checkpoint) SetCheckpoint();
|
||||
await SaveAsync();
|
||||
}
|
||||
|
||||
public async Task SaveProfileAsync() => await StoreValueAsync(ProfileKey, Profile);
|
||||
|
||||
public async Task RestoreCheckpointAsync()
|
||||
{
|
||||
var checkpoint = State.Checkpoint;
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace NullDepth.Models;
|
||||
|
||||
public sealed class GameData
|
||||
{
|
||||
public int Version { get; set; } = 1;
|
||||
public int Version { get; set; } = 2;
|
||||
public string StartRoomId { get; set; } = "loc_01_exterior_access";
|
||||
public List<string> InitialItems { get; set; } = [];
|
||||
public List<ItemDefinition> Items { get; set; } = [];
|
||||
@@ -15,6 +15,7 @@ public sealed class ItemDefinition
|
||||
public string Id { get; set; } = "";
|
||||
public string NameKey { get; set; } = "";
|
||||
public string DescriptionKey { get; set; } = "";
|
||||
public string? DetailedKey { get; set; }
|
||||
public string Category { get; set; } = "equipment";
|
||||
}
|
||||
|
||||
@@ -30,6 +31,7 @@ public sealed class RoomDefinition
|
||||
public string Id { get; set; } = "";
|
||||
public string NameKey { get; set; } = "";
|
||||
public string DescriptionKey { get; set; } = "";
|
||||
public string? ScanKey { get; set; }
|
||||
public string Image { get; set; } = "";
|
||||
public string? Ambient { get; set; }
|
||||
public string? AlternateImage { get; set; }
|
||||
@@ -38,6 +40,20 @@ public sealed class RoomDefinition
|
||||
public int Y { get; set; }
|
||||
public Dictionary<string, ExitDefinition> Exits { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
public List<InteractionDefinition> Interactions { get; set; } = [];
|
||||
public List<HotspotDefinition> Hotspots { get; set; } = [];
|
||||
}
|
||||
|
||||
public sealed class HotspotDefinition
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
public string LabelKey { get; set; } = "";
|
||||
public string? InteractionId { get; set; }
|
||||
public double X { get; set; } = 50;
|
||||
public double Y { get; set; } = 50;
|
||||
public string Icon { get; set; } = "terminal";
|
||||
public string? TelemetryKey { get; set; }
|
||||
public List<string> RequiresFlags { get; set; } = [];
|
||||
public List<string> ForbiddenFlags { get; set; } = [];
|
||||
}
|
||||
|
||||
public sealed class ExitDefinition
|
||||
@@ -81,7 +97,7 @@ public sealed class ChoiceDefinition
|
||||
public sealed class GameState
|
||||
{
|
||||
public int Version { get; set; } = 3;
|
||||
public int ContentVersion { get; set; } = 1;
|
||||
public int ContentVersion { get; set; } = 2;
|
||||
public string CurrentRoomId { get; set; } = "loc_01_exterior_access";
|
||||
public HashSet<string> VisitedRooms { get; set; } = [];
|
||||
public HashSet<string> Flags { get; set; } = [];
|
||||
@@ -107,6 +123,12 @@ public sealed class PlayerSettings
|
||||
public int MasterVolume { get; set; } = 70;
|
||||
}
|
||||
|
||||
public sealed class PlayerProfile
|
||||
{
|
||||
public HashSet<string> UnlockedEndings { get; set; } = [];
|
||||
public HashSet<string> DiscoveredArchives { get; set; } = [];
|
||||
}
|
||||
|
||||
public enum SaveLoadResult
|
||||
{
|
||||
Success,
|
||||
|
||||
+491
-52
@@ -22,7 +22,23 @@
|
||||
{
|
||||
<section class="title-screen screen-image" style="background-image:url('assets/images/title/title_null_depth.webp')">
|
||||
<div class="vignette"></div>
|
||||
<div class="title-card"><p class="eyebrow">FACILITY 03</p><h1>NULL DEPTH</h1><p class="subtitle">SUBLEVEL // 03</p></div>
|
||||
<div class="title-card">
|
||||
<p class="eyebrow">FACILITY 03</p>
|
||||
<h1>NULL DEPTH</h1>
|
||||
<p class="subtitle">SUBLEVEL // 03</p>
|
||||
@if (Game.Profile.UnlockedEndings.Count > 0 || Game.Profile.DiscoveredArchives.Count > 0)
|
||||
{
|
||||
<div class="title-stats">
|
||||
<span>@Game.T("menu.endingsCount"):</span>
|
||||
<div class="endings-badges">
|
||||
<span class="ending-badge @(Game.Profile.UnlockedEndings.Contains("release") ? "unlocked" : "locked")">END A: RECON</span>
|
||||
<span class="ending-badge @(Game.Profile.UnlockedEndings.Contains("shutdown") ? "unlocked" : "locked")">END B: PURGE</span>
|
||||
<span class="ending-badge @(Game.Profile.UnlockedEndings.Contains("containment") ? "unlocked" : "locked")">END C: ISOLATE</span>
|
||||
</div>
|
||||
<span style="margin-top:.3rem;">@Game.T("menu.archivesCount"): @Game.Profile.DiscoveredArchives.Count / 7</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<nav class="title-menu" aria-label="Main menu">
|
||||
<button class="@MenuClass(0)" @onclick="StartNewGame">@Game.T("menu.newGame")</button>
|
||||
<button class="@MenuClass(1)" disabled="@(!Game.HasSave)" @onclick="ContinueGame">@Game.T("menu.continue")</button>
|
||||
@@ -42,7 +58,7 @@
|
||||
<dt>@Game.T("briefing.clientLabel")</dt><dd>VANTAGE SYSTEMS</dd>
|
||||
<dt>@Game.T("briefing.siteLabel")</dt><dd>FACILITY 03</dd>
|
||||
<dt>@Game.T("briefing.assignmentLabel")</dt><dd>@Game.T("briefing.assignment")</dd>
|
||||
<dt>@Game.T("briefing.compensationLabel")</dt><dd>18,000</dd>
|
||||
<dt>@Game.T("briefing.compensationLabel")</dt><dd>18,000 CREDITS</dd>
|
||||
<dt>@Game.T("briefing.infoLabel")</dt><dd>@Game.T("briefing.none")</dd>
|
||||
</dl>
|
||||
<p>@Game.T("briefing.story")</p>
|
||||
@@ -53,56 +69,162 @@
|
||||
else if (_screen == Screen.Game)
|
||||
{
|
||||
var room = Game.CurrentRoom;
|
||||
<section class="play-screen screen-image" style="background-image:url('@Game.RoomImage(room)')">
|
||||
<section class="play-screen screen-image @(_scanMode ? "scan-mode-active" : "")" style="@ParallaxStyle background-image:url('@Game.RoomImage(room)');" @onmousemove="HandleMouseMove">
|
||||
<div class="viewport-layer">
|
||||
<div class="parallax-bg" style="background-image:url('@Game.RoomImage(room)')"></div>
|
||||
</div>
|
||||
<div class="vignette"></div>
|
||||
<header class="top-hud"><span>NULL DEPTH</span><span class="autosave-state @(_savePulse ? "saving" : "")">@Game.T(_savePulse ? "game.autosaveSaving" : "game.autosaveSaved")</span></header>
|
||||
<div class="dust-layer"></div>
|
||||
|
||||
@if (_scanMode)
|
||||
{
|
||||
<div class="lidar-overlay">
|
||||
<div class="lidar-sweep-bar"></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="hotspots-layer">
|
||||
@foreach (var hs in Game.AvailableHotspots())
|
||||
{
|
||||
<button class="hotspot-pin @hs.Icon" style="left:@(hs.X)%; top:@(hs.Y)%;" @onclick="() => TriggerHotspot(hs)" title="@Game.T(hs.LabelKey)">
|
||||
<div class="hotspot-bracket"><span>+</span></div>
|
||||
<div class="hotspot-tooltip">
|
||||
<strong>@Game.T(hs.LabelKey)</strong>
|
||||
@if (_scanMode && hs.TelemetryKey is not null)
|
||||
{
|
||||
<small>@Game.T(hs.TelemetryKey)</small>
|
||||
}
|
||||
</div>
|
||||
@if (_scanMode && hs.TelemetryKey is not null)
|
||||
{
|
||||
<div class="lidar-tag">@Game.T(hs.TelemetryKey)</div>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<header class="top-hud">
|
||||
<div class="hud-left">
|
||||
<span>NULL DEPTH // FACILITY 03</span>
|
||||
<div class="bio-monitor">
|
||||
<span class="bio-pulse-icon @StressClass">♥</span>
|
||||
<span class="bio-bpm">@Game.CurrentBpm BPM</span>
|
||||
<span class="bio-stress-pill @StressClass">@Game.T(Game.StressStatusKey)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hud-right">
|
||||
<span class="autosave-state @(_savePulse ? "saving" : "")">@Game.T(_savePulse ? "game.autosaveSaving" : "game.autosaveSaved")</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<article class="room-panel">
|
||||
<p class="eyebrow">@room.Id.Replace("_", " // ").ToUpperInvariant()</p><h2 @key="room.Id">@Game.T(room.NameKey)</h2><p class="reveal-copy" @key="@(room.Id + Game.Settings.Language)">@Game.T(room.DescriptionKey)</p>
|
||||
<p class="eyebrow">@room.Id.Replace("_", " // ").ToUpperInvariant()</p>
|
||||
<h2 @key="room.Id">@Game.T(room.NameKey)</h2>
|
||||
<p class="reveal-copy" @key="@(room.Id + Game.Settings.Language)">@Game.T(room.DescriptionKey)</p>
|
||||
@if (!string.IsNullOrWhiteSpace(_notice)) { <p class="notice">@_notice</p> }
|
||||
<div class="interaction-list">@foreach (var action in Game.AvailableInteractions()) { <button @onclick="() => OpenInteraction(action)"><kbd>E</kbd> @Game.T(action.LabelKey)</button> }</div>
|
||||
<div class="interaction-list">
|
||||
@foreach (var action in Game.AvailableInteractions())
|
||||
{
|
||||
<button @onclick="() => OpenInteraction(action)"><kbd>E</kbd> @Game.T(action.LabelKey)</button>
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<nav class="movement-pad" aria-label="Movement">
|
||||
<button class="north" disabled="@(!HasNorth)" @onclick="MoveNorth">↑</button>
|
||||
<button class="west" disabled="@(!HasWest)" @onclick="MoveWest">←</button><span class="position">@room.X:@room.Y</span>
|
||||
<button class="east" disabled="@(!HasEast)" @onclick="MoveEast">→</button>
|
||||
<button class="south" disabled="@(!HasSouth)" @onclick="MoveSouth">↓</button>
|
||||
</nav>
|
||||
|
||||
<footer class="command-bar">
|
||||
<button @onclick="OpenInteractionSelector"><kbd>E</kbd> @Game.T("game.interact")</button><button @onclick="() => _showMap = true"><kbd>M</kbd> @Game.T("game.map")</button>
|
||||
<button @onclick="() => _showInventory = true"><kbd>I</kbd> @Game.T("game.inventory")</button><button @onclick="() => _showArchive = true"><kbd>L</kbd> @Game.T("game.archive")</button><button @onclick="() => _showPause = true"><kbd>ESC</kbd> @Game.T("game.pause")</button>
|
||||
<button @onclick="OpenInteractionSelector"><kbd>E</kbd> @Game.T("game.interact")</button>
|
||||
<button class="@(_scanMode ? "primary-action" : "")" @onclick="ToggleScanMode"><kbd>TAB</kbd> @Game.T("game.scanMode")</button>
|
||||
<button @onclick="TriggerScan"><kbd>C</kbd> @Game.T("game.scan")</button>
|
||||
<button @onclick="() => _showMap = true"><kbd>M</kbd> @Game.T("game.map")</button>
|
||||
<button @onclick="OpenInventory"><kbd>I</kbd> @Game.T("game.inventory")</button>
|
||||
<button @onclick="() => _showArchive = true"><kbd>L</kbd> @Game.T("game.archive")</button>
|
||||
<button @onclick="() => _showPause = true"><kbd>ESC</kbd> @Game.T("game.pause")</button>
|
||||
</footer>
|
||||
</section>
|
||||
}
|
||||
else if (_screen == Screen.Death)
|
||||
{
|
||||
<section class="outcome-screen death-screen"><p class="eyebrow">FACILITY EVENT // FATAL</p><h1>@Game.T("death.title")</h1><p>@Game.T("death.body")</p><button class="primary-action" @onclick="RestoreCheckpoint">@Game.T("death.restore")</button><button @onclick="ReturnToTitle">@Game.T("common.mainMenu")</button></section>
|
||||
<section class="outcome-screen death-screen">
|
||||
<p class="eyebrow">FACILITY EVENT // FATAL</p>
|
||||
<h1>@Game.T("death.title")</h1>
|
||||
<p>@Game.T("death.body")</p>
|
||||
<button class="primary-action" @onclick="RestoreCheckpoint">@Game.T("death.restore")</button>
|
||||
<button @onclick="ReturnToTitle">@Game.T("common.mainMenu")</button>
|
||||
</section>
|
||||
}
|
||||
else if (_screen == Screen.Ending)
|
||||
{
|
||||
<section class="outcome-screen ending-screen screen-image" style="@EndingImageStyle"><div class="vignette"></div><p class="eyebrow">ENDING // @_ending?.ToUpperInvariant()</p><h1>@Game.T($"ending.{_ending}.title")</h1><p>@Game.T($"ending.{_ending}.body")</p><button class="primary-action" @onclick="ReturnToTitle">@Game.T("ending.return")</button></section>
|
||||
<section class="outcome-screen ending-screen screen-image" style="@EndingImageStyle">
|
||||
<div class="vignette"></div>
|
||||
<p class="eyebrow">DECODED PROTOCOL // @_ending?.ToUpperInvariant()</p>
|
||||
<h1>@Game.T($"ending.{_ending}.title")</h1>
|
||||
<p>@Game.T($"ending.{_ending}.body")</p>
|
||||
<button class="primary-action" @onclick="ReturnToTitle">@Game.T("ending.return")</button>
|
||||
</section>
|
||||
}
|
||||
|
||||
@if (_showInteractionPicker)
|
||||
{
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="overlay-card action-picker">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">CONTEXT // E</p><h2>@Game.T("interaction.choose")</h2>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card action-picker">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">CONTEXT // E</p>
|
||||
<h2>@Game.T("interaction.choose")</h2>
|
||||
<div class="choice-list">
|
||||
@for (var index = 0; index < AvailableActions.Count; index++)
|
||||
{
|
||||
var actionIndex = index;
|
||||
var action = AvailableActions[index];
|
||||
<button class="@(index == _interactionIndex ? "selected" : "")" @onclick="() => SelectInteraction(action)"><kbd>@(index + 1)</kbd> @Game.T(action.LabelKey)</button>
|
||||
}
|
||||
</div>
|
||||
<small>↑ ↓ SELECT // ENTER CONFIRM</small>
|
||||
</article></div>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (_interaction is not null)
|
||||
{
|
||||
var availableChoices = _interaction.Choices.Where(c => Game.HasAll(c.RequiresFlags)).ToList();
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="terminal-card interaction-modal">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">@_interaction.Type.ToUpperInvariant() // @_interaction.Id.ToUpperInvariant()</p><h2>@Game.T(_interaction.LabelKey)</h2><p class="terminal-copy">@Game.T(_interaction.ContentKey)</p>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
@if (_interaction.Id == "power_routing" && availableChoices.Count == 2)
|
||||
{
|
||||
<article class="terminal-card overlay-card breaker-switchboard">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">POWER MATRIX // 450 kW</p>
|
||||
<h2>@Game.T("panel.breaker.title")</h2>
|
||||
<p class="terminal-copy">@Game.T(_interaction.ContentKey)</p>
|
||||
<div class="breaker-grid">
|
||||
<div class="breaker-card @(_selectedBreaker == 0 ? "active" : "")" @onclick="() => _selectedBreaker = 0">
|
||||
<strong>@Game.T("panel.breaker.max")</strong>
|
||||
<div class="breaker-lever @(_selectedBreaker == 0 ? "up" : "down")">
|
||||
<div class="breaker-lever-handle"></div>
|
||||
</div>
|
||||
<div class="breaker-meter">CRYO: 100% // SEC: 0%</div>
|
||||
</div>
|
||||
<div class="breaker-card @(_selectedBreaker == 1 ? "active" : "")" @onclick="() => _selectedBreaker = 1">
|
||||
<strong>@Game.T("panel.breaker.balanced")</strong>
|
||||
<div class="breaker-lever @(_selectedBreaker == 1 ? "up" : "down")">
|
||||
<div class="breaker-lever-handle"></div>
|
||||
</div>
|
||||
<div class="breaker-meter">CRYO: 60% // SEC: 40%</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="primary-action" style="width:100%;" @onclick="() => ResolveChoice(availableChoices[_selectedBreaker])">@Game.T("panel.breaker.switch")</button>
|
||||
</article>
|
||||
}
|
||||
else
|
||||
{
|
||||
<article class="terminal-card interaction-modal">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">@_interaction.Type.ToUpperInvariant() // @_interaction.Id.ToUpperInvariant()</p>
|
||||
<h2>@Game.T(_interaction.LabelKey)</h2>
|
||||
<p class="terminal-copy">@Game.T(_interaction.ContentKey)</p>
|
||||
@if (availableChoices.Count > 0)
|
||||
{
|
||||
<div class="choice-list">
|
||||
@@ -115,47 +237,175 @@
|
||||
</div>
|
||||
<small>↑ ↓ / W S SELECT // ENTER CONFIRM // 1-@availableChoices.Count SELECT</small>
|
||||
}
|
||||
else { <button class="primary-action" @onclick="ResolveInteraction">@Game.T("common.confirm")</button> }
|
||||
</article></div>
|
||||
else
|
||||
{
|
||||
<button class="primary-action" @onclick="ResolveInteraction">@Game.T("common.confirm")</button>
|
||||
}
|
||||
</article>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (_showMap)
|
||||
{
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="overlay-card map-card"><button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">FACILITY 03 // @Game.T("game.map")</p><h2>@Game.T("map.title")</h2>
|
||||
<div class="map-grid">@foreach (var mapRoom in Game.Data.Rooms) { var visited = Game.State.VisitedRooms.Contains(mapRoom.Id); <div class="map-cell @(visited ? "visited" : "unknown") @(mapRoom.Id == Game.State.CurrentRoomId ? "current" : "")" style="grid-column:@(mapRoom.X + 1);grid-row:@(mapRoom.Y + 1)" title="@(visited ? Game.T(mapRoom.NameKey) : Game.T("map.unknown"))">@(visited ? (mapRoom.Id == Game.State.CurrentRoomId ? "●" : "□") : "?")</div> }</div><p>@Game.T("map.visited"): @Game.State.VisitedRooms.Count / @Game.Data.Rooms.Count</p>
|
||||
</article></div>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card map-card">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">FACILITY 03 // @Game.T("game.map")</p>
|
||||
<h2>@Game.T("map.title")</h2>
|
||||
<div class="map-grid">
|
||||
@foreach (var mapRoom in Game.Data.Rooms)
|
||||
{
|
||||
var visited = Game.State.VisitedRooms.Contains(mapRoom.Id);
|
||||
<div class="map-cell @(visited ? "visited" : "unknown") @(mapRoom.Id == Game.State.CurrentRoomId ? "current" : "")" style="grid-column:@(mapRoom.X + 1);grid-row:@(mapRoom.Y + 1)" title="@(visited ? Game.T(mapRoom.NameKey) : Game.T("map.unknown"))">
|
||||
@(visited ? (mapRoom.Id == Game.State.CurrentRoomId ? "●" : "□") : "?")
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<p>@Game.T("map.visited"): @Game.State.VisitedRooms.Count / @Game.Data.Rooms.Count</p>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_showInventory)
|
||||
{
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="overlay-card inventory-card"><button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">ELIAS VENN // LOADOUT</p><h2>@Game.T("inventory.title")</h2>@if (Game.State.Inventory.Count == 0) { <p>@Game.T("inventory.empty")</p> } else { <ul>@foreach (var itemId in Game.State.Inventory) { var item = Game.FindItem(itemId); if (item is not null) { <li><small>@item.Category.ToUpperInvariant()</small><strong>@Game.T(item.NameKey)</strong><p>@Game.T(item.DescriptionKey)</p></li> } }</ul> }</article></div>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card inventory-card">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">ELIAS VENN // LOADOUT</p>
|
||||
<h2>@Game.T("inventory.title")</h2>
|
||||
@if (Game.State.Inventory.Count == 0)
|
||||
{
|
||||
<p>@Game.T("inventory.empty")</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ul>
|
||||
@foreach (var itemId in Game.State.Inventory)
|
||||
{
|
||||
var item = Game.FindItem(itemId);
|
||||
if (item is not null)
|
||||
{
|
||||
<li class="@(_selectedItemId == item.Id ? "selected-item" : "")" @onclick="() => InspectItem(item.Id)">
|
||||
<small>@item.Category.ToUpperInvariant()</small>
|
||||
<strong>@Game.T(item.NameKey)</strong>
|
||||
<p>@Game.T(item.DescriptionKey)</p>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
@if (!string.IsNullOrWhiteSpace(_selectedItemId))
|
||||
{
|
||||
var selectedItem = Game.FindItem(_selectedItemId);
|
||||
if (selectedItem is not null)
|
||||
{
|
||||
<div class="item-inspect-box">
|
||||
<strong>@Game.T("inventory.inspectPrompt")</strong>
|
||||
<p style="margin:.4rem 0 0;">@(selectedItem.DetailedKey is not null ? Game.T(selectedItem.DetailedKey) : Game.T(selectedItem.DescriptionKey))</p>
|
||||
@if (selectedItem.Id == "diagnostic_scanner")
|
||||
{
|
||||
<div class="inspect-actions">
|
||||
<button class="primary-action" @onclick="TriggerScanFromInventory"><kbd>C</kbd> @Game.T("common.scan")</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_showArchive)
|
||||
{
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="overlay-card archive-card"><button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">FACILITY 03 // MEMORY</p><h2>@Game.T("archive.title")</h2>
|
||||
@if (Game.State.Archive.Count == 0) { <p>@Game.T("archive.empty")</p> }
|
||||
else { <div class="archive-list">@foreach (var archiveId in Game.State.Archive) { var entry = Game.FindArchive(archiveId); if (entry is not null) { <details><summary>@Game.T(entry.TitleKey)</summary><p class="terminal-copy">@Game.T(entry.ContentKey)</p></details> } }</div> }
|
||||
</article></div>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card archive-card">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button>
|
||||
<p class="eyebrow">FACILITY 03 // DECODED ARCHIVES</p>
|
||||
<h2>@Game.T("archive.title")</h2>
|
||||
@if (Game.State.Archive.Count == 0)
|
||||
{
|
||||
<p>@Game.T("archive.empty")</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="archive-list">
|
||||
@foreach (var archiveId in Game.State.Archive)
|
||||
{
|
||||
var entry = Game.FindArchive(archiveId);
|
||||
if (entry is not null)
|
||||
{
|
||||
<details>
|
||||
<summary>@Game.T(entry.TitleKey)</summary>
|
||||
<p class="terminal-copy">@Game.T(entry.ContentKey)</p>
|
||||
</details>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_showPause)
|
||||
{
|
||||
<div class="modal-layer" role="dialog" aria-modal="true"><article class="overlay-card pause-card"><p class="eyebrow">SYSTEM // PAUSED</p><h2>@Game.T("pause.title")</h2><button class="primary-action" @onclick="CloseOverlays">@Game.T("pause.resume")</button><button @onclick="OpenSettings">@Game.T("menu.settings")</button><button @onclick="ReturnToTitle">@Game.T("common.mainMenu")</button></article></div>
|
||||
<div class="modal-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card pause-card">
|
||||
<p class="eyebrow">SYSTEM // PAUSED</p>
|
||||
<h2>@Game.T("pause.title")</h2>
|
||||
<button class="primary-action" @onclick="CloseOverlays">@Game.T("pause.resume")</button>
|
||||
<button @onclick="OpenSettings">@Game.T("menu.settings")</button>
|
||||
<button @onclick="ReturnToTitle">@Game.T("common.mainMenu")</button>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_showSettings)
|
||||
{
|
||||
<div class="modal-layer settings-layer" role="dialog" aria-modal="true"><article class="overlay-card settings-card"><button class="close-button" aria-label="Close" @onclick="CloseSettings">×</button><p class="eyebrow">SYSTEM // CONFIGURATION</p><h2>@Game.T("settings.title")</h2>
|
||||
<label>@Game.T("settings.language")</label><div class="segmented-control"><button class="@(Game.Settings.Language == "sk" ? "active" : "")" @onclick="ChangeToSlovak">Slovenčina</button><button class="@(Game.Settings.Language == "en" ? "active" : "")" @onclick="ChangeToEnglish">English</button></div>
|
||||
<label for="volume">@Game.T("settings.volume") — @Game.Settings.MasterVolume%</label><input id="volume" type="range" min="0" max="100" step="5" value="@Game.Settings.MasterVolume" @oninput="ChangeVolume" />
|
||||
<label>@Game.T("settings.fullscreen")</label><button class="setting-toggle @(_isFullscreen ? "active" : "")" @onclick="ToggleFullscreen">@Game.T(_isFullscreen ? "settings.exitFullscreen" : "settings.enterFullscreen")</button>
|
||||
@if (Game.HasSave) { <button class="danger-action" @onclick="RequestDeleteSave">@Game.T("save.delete")</button> }
|
||||
<div class="modal-layer settings-layer" role="dialog" aria-modal="true">
|
||||
<article class="overlay-card settings-card">
|
||||
<button class="close-button" aria-label="Close" @onclick="CloseSettings">×</button>
|
||||
<p class="eyebrow">SYSTEM // CONFIGURATION</p>
|
||||
<h2>@Game.T("settings.title")</h2>
|
||||
<label>@Game.T("settings.language")</label>
|
||||
<div class="segmented-control">
|
||||
<button class="@(Game.Settings.Language == "sk" ? "active" : "")" @onclick="ChangeToSlovak">Slovenčina</button>
|
||||
<button class="@(Game.Settings.Language == "en" ? "active" : "")" @onclick="ChangeToEnglish">English</button>
|
||||
</div>
|
||||
<label for="volume">@Game.T("settings.volume") — @Game.Settings.MasterVolume%</label>
|
||||
<input id="volume" type="range" min="0" max="100" step="5" value="@Game.Settings.MasterVolume" @oninput="ChangeVolume" />
|
||||
<label>@Game.T("settings.fullscreen")</label>
|
||||
<button class="setting-toggle @(_isFullscreen ? "active" : "")" @onclick="ToggleFullscreen">@Game.T(_isFullscreen ? "settings.exitFullscreen" : "settings.enterFullscreen")</button>
|
||||
@if (Game.HasSave)
|
||||
{
|
||||
<button class="danger-action" @onclick="RequestDeleteSave">@Game.T("save.delete")</button>
|
||||
}
|
||||
<button class="primary-action" @onclick="CloseSettings">@Game.T("common.back")</button>
|
||||
</article></div>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_confirmation is not null)
|
||||
{
|
||||
<div class="modal-layer confirmation-layer" role="alertdialog" aria-modal="true"><article class="overlay-card confirmation-card"><p class="eyebrow">SYSTEM // CONFIRMATION</p><h2>@Game.T(_confirmation == Confirmation.NewGame ? "save.overwriteTitle" : "save.deleteTitle")</h2><p>@Game.T(_confirmation == Confirmation.NewGame ? "save.overwriteBody" : "save.deleteBody")</p><div class="confirmation-actions"><button class="danger-action" @onclick="ConfirmPendingAction">@Game.T("common.confirm")</button><button @onclick="CancelConfirmation">@Game.T("common.cancel")</button></div></article></div>
|
||||
<div class="modal-layer confirmation-layer" role="alertdialog" aria-modal="true">
|
||||
<article class="overlay-card confirmation-card">
|
||||
<p class="eyebrow">SYSTEM // CONFIRMATION</p>
|
||||
<h2>@Game.T(_confirmation == Confirmation.NewGame ? "save.overwriteTitle" : "save.deleteTitle")</h2>
|
||||
<p>@Game.T(_confirmation == Confirmation.NewGame ? "save.overwriteBody" : "save.deleteBody")</p>
|
||||
<div class="confirmation-actions">
|
||||
<button class="danger-action" @onclick="ConfirmPendingAction">@Game.T("common.confirm")</button>
|
||||
<button @onclick="CancelConfirmation">@Game.T("common.cancel")</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
@if (_saveError is not null)
|
||||
{
|
||||
<div class="modal-layer" role="alertdialog" aria-modal="true"><article class="overlay-card confirmation-card"><p class="eyebrow">SAVE // ERROR</p><h2>@Game.T("save.errorTitle")</h2><p>@Game.T(_saveError == SaveLoadResult.Incompatible ? "save.incompatible" : "save.corrupt")</p><div class="confirmation-actions"><button class="danger-action" @onclick="DeleteBrokenSave">@Game.T("save.delete")</button><button @onclick="CloseSaveError">@Game.T("common.back")</button></div></article></div>
|
||||
<div class="modal-layer" role="alertdialog" aria-modal="true">
|
||||
<article class="overlay-card confirmation-card">
|
||||
<p class="eyebrow">SAVE // ERROR</p>
|
||||
<h2>@Game.T("save.errorTitle")</h2>
|
||||
<p>@Game.T(_saveError == SaveLoadResult.Incompatible ? "save.incompatible" : "save.corrupt")</p>
|
||||
<div class="confirmation-actions">
|
||||
<button class="danger-action" @onclick="DeleteBrokenSave">@Game.T("save.delete")</button>
|
||||
<button @onclick="CloseSaveError">@Game.T("common.back")</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
}
|
||||
<div class="system-flash" aria-hidden="true"></div>
|
||||
<div class="screen-fade" aria-hidden="true"></div>
|
||||
@@ -175,6 +425,7 @@
|
||||
private bool _showPause;
|
||||
private bool _showSettings;
|
||||
private bool _showInteractionPicker;
|
||||
private bool _scanMode;
|
||||
private bool _isFullscreen;
|
||||
private bool _isTransitioning;
|
||||
private bool _systemFlash;
|
||||
@@ -182,26 +433,92 @@
|
||||
private int _savePulseVersion;
|
||||
private int _interactionIndex;
|
||||
private int _choiceIndex;
|
||||
private int _selectedBreaker;
|
||||
private string? _titleNotice;
|
||||
private string? _selectedItemId;
|
||||
private double _mouseX;
|
||||
private double _mouseY;
|
||||
private SaveLoadResult? _saveError;
|
||||
private Confirmation? _confirmation;
|
||||
|
||||
private List<InteractionDefinition> AvailableActions => Game.AvailableInteractions().ToList();
|
||||
private string EndingImageStyle => $"background-image:url('{Game.RoomImage(Game.CurrentRoom)}')";
|
||||
private string ParallaxStyle => $"--mouse-px:{_mouseX.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)}; --mouse-py:{_mouseY.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)};";
|
||||
|
||||
private string StressClass
|
||||
{
|
||||
get
|
||||
{
|
||||
var bpm = Game.CurrentBpm;
|
||||
if (bpm >= 120) return "critical";
|
||||
if (bpm >= 95) return "elevated";
|
||||
return "nominal";
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await Game.InitializeAsync();
|
||||
Game.Saved += OnSaved;
|
||||
await Audio.InitializeAsync(Game.Settings.MasterVolume);
|
||||
_ready = true;
|
||||
await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3");
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender && _ready)
|
||||
{
|
||||
await _shell.FocusAsync();
|
||||
if (_screen == Screen.Title) await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMouseMove(MouseEventArgs e)
|
||||
{
|
||||
// Smooth normalized coordinate calculation (-1 to +1)
|
||||
_mouseX = Math.Clamp((e.ClientX / 1920.0 * 2.0) - 1.0, -1.0, 1.0);
|
||||
_mouseY = Math.Clamp((e.ClientY / 1080.0 * 2.0) - 1.0, -1.0, 1.0);
|
||||
}
|
||||
|
||||
private Task StartNewGame()
|
||||
{
|
||||
if (Game.HasSave)
|
||||
{
|
||||
_confirmation = Confirmation.NewGame;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
return StartNewGameConfirmed();
|
||||
}
|
||||
|
||||
private async Task StartNewGameConfirmed()
|
||||
{
|
||||
_confirmation = null;
|
||||
_titleNotice = null;
|
||||
_scanMode = false;
|
||||
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3");
|
||||
await Game.NewGameAsync();
|
||||
_screen = Screen.Briefing;
|
||||
_notice = null;
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync() { await Game.InitializeAsync(); Game.Saved += OnSaved; await Audio.InitializeAsync(Game.Settings.MasterVolume); _ready = true; await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3"); }
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && _ready) { await _shell.FocusAsync(); if (_screen == Screen.Title) await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3"); } }
|
||||
private Task StartNewGame() { if (Game.HasSave) { _confirmation = Confirmation.NewGame; return Task.CompletedTask; } return StartNewGameConfirmed(); }
|
||||
private async Task StartNewGameConfirmed() { _confirmation = null; _titleNotice = null; await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3"); await Game.NewGameAsync(); _screen = Screen.Briefing; _notice = null; }
|
||||
private async Task ContinueGame()
|
||||
{
|
||||
var result = await Game.ContinueAsync();
|
||||
if (result != SaveLoadResult.Success) { _saveError = result; return; }
|
||||
_titleNotice = null;
|
||||
_scanMode = false;
|
||||
_ending = Game.State.CompletedEnding;
|
||||
_screen = _ending is null ? Screen.Game : Screen.Ending;
|
||||
await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient);
|
||||
}
|
||||
private async Task BeginPlay() { _screen = Screen.Game; await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); }
|
||||
|
||||
private async Task BeginPlay()
|
||||
{
|
||||
_screen = Screen.Game;
|
||||
await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient);
|
||||
}
|
||||
|
||||
private async Task Move(string direction)
|
||||
{
|
||||
if (_isTransitioning) return;
|
||||
@@ -216,14 +533,17 @@
|
||||
await Task.Delay(260);
|
||||
_isTransitioning = false;
|
||||
}
|
||||
|
||||
private Task MoveNorth() => Move("north");
|
||||
private Task MoveSouth() => Move("south");
|
||||
private Task MoveWest() => Move("west");
|
||||
private Task MoveEast() => Move("east");
|
||||
|
||||
private bool HasNorth => Game.CurrentRoom.Exits.ContainsKey("north");
|
||||
private bool HasSouth => Game.CurrentRoom.Exits.ContainsKey("south");
|
||||
private bool HasWest => Game.CurrentRoom.Exits.ContainsKey("west");
|
||||
private bool HasEast => Game.CurrentRoom.Exits.ContainsKey("east");
|
||||
|
||||
private void OpenInteractionSelector()
|
||||
{
|
||||
var actions = AvailableActions;
|
||||
@@ -233,8 +553,42 @@
|
||||
_showInteractionPicker = true;
|
||||
_notice = null;
|
||||
}
|
||||
private void OpenInteraction(InteractionDefinition interaction) { _showInteractionPicker = false; _interaction = interaction; _choiceIndex = 0; _notice = null; }
|
||||
|
||||
private void OpenInteraction(InteractionDefinition interaction)
|
||||
{
|
||||
_showInteractionPicker = false;
|
||||
_interaction = interaction;
|
||||
_choiceIndex = 0;
|
||||
_selectedBreaker = 0;
|
||||
_notice = null;
|
||||
}
|
||||
|
||||
private void SelectInteraction(InteractionDefinition interaction) => OpenInteraction(interaction);
|
||||
|
||||
private async Task TriggerHotspot(HotspotDefinition hs)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(hs.InteractionId))
|
||||
{
|
||||
var interaction = Game.FindInteraction(hs.InteractionId);
|
||||
if (interaction is not null)
|
||||
{
|
||||
OpenInteraction(interaction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (hs.TelemetryKey is not null)
|
||||
{
|
||||
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3");
|
||||
_notice = Game.T(hs.TelemetryKey);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ToggleScanMode()
|
||||
{
|
||||
_scanMode = !_scanMode;
|
||||
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3");
|
||||
}
|
||||
|
||||
private async Task ResolveInteraction()
|
||||
{
|
||||
if (_interaction is null) return;
|
||||
@@ -242,32 +596,109 @@
|
||||
await Game.ApplyInteractionAsync(resolved);
|
||||
await Audio.PlaySfxAsync(resolved.Sound);
|
||||
_interaction = null;
|
||||
if (resolved.SetFlags.Contains("power_restored") || resolved.Sound?.Contains("alarm") == true || resolved.Sound?.Contains("disturbance") == true) _ = TriggerSystemFlashAsync();
|
||||
if (resolved.SetFlags.Contains("power_restored") || resolved.Sound?.Contains("alarm") == true || resolved.Sound?.Contains("disturbance") == true)
|
||||
_ = TriggerSystemFlashAsync();
|
||||
await Task.Delay(180);
|
||||
_notice = Game.T(resolved.ContentKey);
|
||||
}
|
||||
|
||||
private async Task ResolveChoice(ChoiceDefinition choice)
|
||||
{
|
||||
await Game.ApplyChoiceAsync(choice);
|
||||
await Audio.PlaySfxAsync(choice.Sound);
|
||||
_interaction = null;
|
||||
if (choice.Sound?.Contains("alarm") == true || choice.Sound?.Contains("disturbance") == true) _ = TriggerSystemFlashAsync();
|
||||
if (choice.Sound?.Contains("alarm") == true || choice.Sound?.Contains("disturbance") == true)
|
||||
_ = TriggerSystemFlashAsync();
|
||||
if (choice.Death) { _screen = Screen.Death; return; }
|
||||
if (!string.IsNullOrWhiteSpace(choice.Ending)) { _ending = choice.Ending; _screen = Screen.Ending; return; }
|
||||
await Task.Delay(180);
|
||||
_notice = choice.ResultKey is null ? null : Game.T(choice.ResultKey);
|
||||
}
|
||||
private async Task RestoreCheckpoint() { await Game.RestoreCheckpointAsync(); _screen = Screen.Game; _notice = Game.T("death.restored"); await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); }
|
||||
private async Task ReturnToTitle() { CloseOverlays(); _showSettings = false; _screen = Screen.Title; _menuIndex = 0; _titleNotice = null; await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3"); }
|
||||
private async Task ChangeLanguage(string language) { await Game.SetLanguageAsync(language); StateHasChanged(); }
|
||||
|
||||
private async Task TriggerScan()
|
||||
{
|
||||
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3");
|
||||
_notice = Game.ScanCurrentRoom();
|
||||
}
|
||||
|
||||
private async Task TriggerScanFromInventory()
|
||||
{
|
||||
CloseOverlays();
|
||||
await TriggerScan();
|
||||
}
|
||||
|
||||
private void OpenInventory()
|
||||
{
|
||||
_selectedItemId = Game.State.Inventory.FirstOrDefault();
|
||||
_showInventory = true;
|
||||
}
|
||||
|
||||
private void InspectItem(string itemId) => _selectedItemId = itemId;
|
||||
|
||||
private async Task RestoreCheckpoint()
|
||||
{
|
||||
await Game.RestoreCheckpointAsync();
|
||||
_screen = Screen.Game;
|
||||
_notice = Game.T("death.restored");
|
||||
await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient);
|
||||
}
|
||||
|
||||
private async Task ReturnToTitle()
|
||||
{
|
||||
CloseOverlays();
|
||||
_showSettings = false;
|
||||
_screen = Screen.Title;
|
||||
_menuIndex = 0;
|
||||
_titleNotice = null;
|
||||
await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3");
|
||||
}
|
||||
|
||||
private async Task ChangeLanguage(string language)
|
||||
{
|
||||
await Game.SetLanguageAsync(language);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private Task ChangeToSlovak() => ChangeLanguage("sk");
|
||||
private Task ChangeToEnglish() => ChangeLanguage("en");
|
||||
private async Task ChangeVolume(ChangeEventArgs args) { if (!int.TryParse(args.Value?.ToString(), out var volume)) return; Game.Settings.MasterVolume = volume; await Audio.SetVolumeAsync(volume); await Game.SaveSettingsAsync(); }
|
||||
private async Task OpenSettings() { _isFullscreen = await JS.InvokeAsync<bool>("nullDepth.isFullscreen"); _showSettings = true; }
|
||||
private async Task ToggleFullscreen() { _isFullscreen = await JS.InvokeAsync<bool>("nullDepth.toggleFullscreen"); }
|
||||
private async Task CloseSettings() { await Game.SaveSettingsAsync(); _showSettings = false; }
|
||||
private void CloseOverlays() { _interaction = null; _showInteractionPicker = false; _showMap = false; _showInventory = false; _showArchive = false; _showPause = false; }
|
||||
|
||||
private async Task ChangeVolume(ChangeEventArgs args)
|
||||
{
|
||||
if (!int.TryParse(args.Value?.ToString(), out var volume)) return;
|
||||
Game.Settings.MasterVolume = volume;
|
||||
await Audio.SetVolumeAsync(volume);
|
||||
await Game.SaveSettingsAsync();
|
||||
}
|
||||
|
||||
private async Task OpenSettings()
|
||||
{
|
||||
_isFullscreen = await JS.InvokeAsync<bool>("nullDepth.isFullscreen");
|
||||
_showSettings = true;
|
||||
}
|
||||
|
||||
private async Task ToggleFullscreen()
|
||||
{
|
||||
_isFullscreen = await JS.InvokeAsync<bool>("nullDepth.toggleFullscreen");
|
||||
}
|
||||
|
||||
private async Task CloseSettings()
|
||||
{
|
||||
await Game.SaveSettingsAsync();
|
||||
_showSettings = false;
|
||||
}
|
||||
|
||||
private void CloseOverlays()
|
||||
{
|
||||
_interaction = null;
|
||||
_showInteractionPicker = false;
|
||||
_showMap = false;
|
||||
_showInventory = false;
|
||||
_showArchive = false;
|
||||
_showPause = false;
|
||||
}
|
||||
|
||||
private void RequestDeleteSave() => _confirmation = Confirmation.DeleteSave;
|
||||
|
||||
private async Task ConfirmPendingAction()
|
||||
{
|
||||
if (_confirmation == Confirmation.NewGame) await StartNewGameConfirmed();
|
||||
@@ -283,10 +714,13 @@
|
||||
await Audio.StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelConfirmation() => _confirmation = null;
|
||||
private async Task DeleteBrokenSave() { await Game.DeleteSaveAsync(); _saveError = null; _titleNotice = Game.T("save.deleted"); }
|
||||
private void CloseSaveError() => _saveError = null;
|
||||
|
||||
private void OnSaved() => _ = InvokeAsync(PulseSaveAsync);
|
||||
|
||||
private async Task PulseSaveAsync()
|
||||
{
|
||||
var version = ++_savePulseVersion;
|
||||
@@ -295,6 +729,7 @@
|
||||
await Task.Delay(900);
|
||||
if (version == _savePulseVersion) { _savePulse = false; StateHasChanged(); }
|
||||
}
|
||||
|
||||
private async Task TriggerSystemFlashAsync()
|
||||
{
|
||||
_systemFlash = true;
|
||||
@@ -303,6 +738,7 @@
|
||||
_systemFlash = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private string MenuClass(int index) => _menuIndex == index ? "selected" : "";
|
||||
|
||||
private async Task HandleKey(KeyboardEventArgs args)
|
||||
@@ -380,12 +816,15 @@
|
||||
case "a" or "arrowleft": await Move("west"); break;
|
||||
case "d" or "arrowright": await Move("east"); break;
|
||||
case "e": OpenInteractionSelector(); break;
|
||||
case "tab": await ToggleScanMode(); break;
|
||||
case "c": await TriggerScan(); break;
|
||||
case "m": _showMap = true; break;
|
||||
case "i": _showInventory = true; break;
|
||||
case "i": OpenInventory(); break;
|
||||
case "l": _showArchive = true; break;
|
||||
case "escape": _showPause = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() => Game.Saved -= OnSaved;
|
||||
private enum Confirmation { NewGame, DeleteSave }
|
||||
private enum Screen { Title, Briefing, Game, Death, Ending }
|
||||
|
||||
@@ -17,53 +17,120 @@ kbd { color:var(--cyan); background:none; padding:0; }
|
||||
.system-flash { z-index:40; background:radial-gradient(circle at 50% 45%,rgba(255,74,80,.35),rgba(125,0,8,.12) 42%,transparent 72%); }
|
||||
.game-shell.system-alert .system-flash { animation:system-flash .65s steps(2,end); }
|
||||
@keyframes system-flash { 0%,100% { opacity:0; } 15%,45% { opacity:1; } 30%,65% { opacity:.18; } }
|
||||
.screen-image { position:absolute; inset:0; min-height:100%; background-position:center; background-size:cover; isolation:isolate; }
|
||||
.vignette { position:absolute; inset:0; z-index:-1; background:linear-gradient(90deg,rgba(0,4,6,.87) 0%,rgba(0,4,6,.28) 40%,rgba(0,4,6,.15) 65%,rgba(0,4,6,.64) 100%),linear-gradient(0deg,rgba(0,3,5,.82) 0%,transparent 40%,rgba(0,3,5,.3) 100%); }
|
||||
.screen-image { position:absolute; inset:0; width:100%; height:100%; min-height:100%; background-position:center; background-size:cover; }
|
||||
.vignette { position:absolute; inset:0; z-index:2; pointer-events:none; background:linear-gradient(90deg,rgba(0,4,6,.87) 0%,rgba(0,4,6,.28) 40%,rgba(0,4,6,.15) 65%,rgba(0,4,6,.64) 100%),linear-gradient(0deg,rgba(0,3,5,.82) 0%,transparent 40%,rgba(0,3,5,.3) 100%); }
|
||||
.loading-screen { height:100%; display:flex; flex-direction:column; align-items:center; justify-content:center; color:var(--cyan); font:500 .8rem 'IBM Plex Mono'; letter-spacing:.35em; animation:pulse 1.6s infinite; }
|
||||
@keyframes pulse { 50% { opacity:.35; } }
|
||||
.title-card { position:absolute; left:6vw; top:9vh; }
|
||||
.title-card { position:absolute; left:6vw; top:9vh; z-index:10; }
|
||||
.title-card h1 { margin:.25rem 0; font-size:clamp(3rem,7vw,7rem); font-weight:300; letter-spacing:.19em; line-height:.95; text-shadow:0 2px 32px #000; }
|
||||
.eyebrow { margin:0 0 .7rem; color:var(--cyan); font-size:.68rem; letter-spacing:.22em; text-transform:uppercase; }
|
||||
.subtitle { color:var(--muted); letter-spacing:.4em; font-size:.74rem; }
|
||||
.title-menu { position:absolute; left:6vw; bottom:8vh; display:flex; width:min(22rem,80vw); flex-direction:column; align-items:stretch; gap:.45rem; }
|
||||
.title-menu { position:absolute; left:6vw; bottom:8vh; display:flex; width:min(22rem,80vw); flex-direction:column; align-items:stretch; gap:.45rem; z-index:10; }
|
||||
.title-menu button { border:0; border-left:2px solid transparent; text-align:left; padding:.7rem 1rem; font-size:.78rem; }
|
||||
.title-menu button:hover, .title-menu button.selected { background:linear-gradient(90deg,rgba(158,239,255,.95),rgba(158,239,255,.08)); border-left-color:white; }
|
||||
.title-menu small { margin-top:1rem; color:var(--muted); letter-spacing:.12em; }
|
||||
.title-notice { margin:.65rem 0 0; color:var(--cyan); font:.7rem 'IBM Plex Mono',Consolas,monospace; line-height:1.5; }
|
||||
.terminal-card, .overlay-card { position:relative; border:1px solid var(--line); background:linear-gradient(145deg,rgba(6,17,21,.96),rgba(1,7,10,.94)); box-shadow:0 30px 90px #000, inset 0 0 40px rgba(66,216,244,.025); backdrop-filter:blur(16px); }
|
||||
.briefing-card { position:absolute; left:6vw; top:50%; transform:translateY(-50%); width:min(38rem,88vw); padding:2.2rem; }
|
||||
.briefing-card { position:absolute; left:6vw; top:50%; transform:translateY(-50%); width:min(38rem,88vw); padding:2.2rem; z-index:10; }
|
||||
.briefing-card dl { display:grid; grid-template-columns:10rem 1fr; margin:1.7rem 0; gap:.55rem 1rem; font-family:'IBM Plex Mono'; font-size:.78rem; }
|
||||
.briefing-card dt { color:var(--muted); font-weight:400; }.briefing-card dd { margin:0;color:var(--cyan); }
|
||||
.briefing-card>p:not(.eyebrow) { color:#c4d0d2; line-height:1.7; max-width:34rem; }
|
||||
.primary-action { color:#031013; background:var(--cyan); border-color:var(--cyan); }
|
||||
.top-hud { position:absolute; top:0; left:0; right:0; display:flex; justify-content:space-between; padding:1.25rem 1.6rem; color:rgba(220,248,250,.65); font-size:.62rem; letter-spacing:.18em; background:linear-gradient(#020608b8,transparent); }
|
||||
.autosave-state { transition:color .2s,text-shadow .2s; }.autosave-state.saving { color:var(--cyan); text-shadow:0 0 12px rgba(66,216,244,.85); animation:save-pulse .45s ease infinite alternate; }
|
||||
.top-hud { position:absolute; top:0; left:0; right:0; display:flex; justify-content:space-between; align-items:center; padding:1.2rem 1.6rem; color:rgba(220,248,250,.7); font-size:.65rem; letter-spacing:.18em; background:linear-gradient(#020608db,transparent); z-index:15; }
|
||||
.hud-left { display:flex; align-items:center; gap:1.5rem; }
|
||||
.hud-right { display:flex; align-items:center; gap:1.5rem; }
|
||||
.bio-monitor { display:flex; align-items:center; gap:.55rem; font-family:'IBM Plex Mono',monospace; font-size:.68rem; padding:.25rem .6rem; border:1px solid rgba(158,239,255,.2); background:rgba(3,10,13,.6); }
|
||||
.bio-pulse-icon { color:var(--cyan); animation:pulse-heart 1s ease infinite; display:inline-block; }
|
||||
.bio-pulse-icon.critical { color:var(--danger); animation:pulse-heart .45s ease infinite; }
|
||||
.bio-pulse-icon.elevated { color:#ffbc42; animation:pulse-heart .7s ease infinite; }
|
||||
@keyframes pulse-heart { 0%,100% { transform:scale(1); opacity:.8; } 50% { transform:scale(1.28); opacity:1; filter:drop-shadow(0 0 6px currentColor); } }
|
||||
.bio-stress-pill { font-size:.58rem; padding:.1rem .35rem; border-radius:2px; letter-spacing:.1em; }
|
||||
.bio-stress-pill.nominal { color:var(--cyan); border:1px solid rgba(66,216,244,.3); }
|
||||
.bio-stress-pill.elevated { color:#ffbc42; border:1px solid rgba(255,188,66,.4); }
|
||||
.bio-stress-pill.critical { color:var(--danger); border:1px solid rgba(255,77,87,.5); background:rgba(255,77,87,.15); }
|
||||
.autosave-state { transition:color .2s,text-shadow .2s; }
|
||||
.autosave-state.saving { color:var(--cyan); text-shadow:0 0 12px rgba(66,216,244,.85); animation:save-pulse .45s ease infinite alternate; }
|
||||
@keyframes save-pulse { to { opacity:.45; } }
|
||||
.room-panel { position:absolute; left:2rem; bottom:5.8rem; width:min(36rem,calc(100vw - 11rem)); padding:1.5rem 1.6rem; background:linear-gradient(90deg,rgba(2,8,11,.93),rgba(2,8,11,.55),transparent); text-shadow:0 2px 8px #000; }
|
||||
|
||||
.title-stats { margin-top:1.2rem; display:flex; flex-direction:column; gap:.4rem; font-family:'IBM Plex Mono',monospace; font-size:.64rem; color:var(--muted); }
|
||||
.endings-badges { display:flex; gap:.4rem; margin-top:.2rem; }
|
||||
.ending-badge { padding:.2rem .5rem; border:1px solid rgba(158,239,255,.15); font-size:.6rem; letter-spacing:.12em; color:#4a6266; }
|
||||
.ending-badge.unlocked { color:#031013; background:var(--cyan); border-color:var(--cyan); font-weight:600; box-shadow:0 0 10px rgba(66,216,244,.35); }
|
||||
|
||||
.room-panel { position:absolute; left:2rem; bottom:5.8rem; width:min(38rem,calc(100vw - 11rem)); padding:1.5rem 1.6rem; background:linear-gradient(90deg,rgba(2,8,11,.95),rgba(2,8,11,.65),transparent); text-shadow:0 2px 8px #000; border-left:2px solid var(--line); z-index:10; }
|
||||
.room-panel h2, .overlay-card h2, .terminal-card h2 { margin:.15rem 0 .65rem; font-weight:400; letter-spacing:.11em; }
|
||||
.room-panel>p:not(.eyebrow) { max-width:33rem; margin:.35rem 0; color:#c6d2d4; line-height:1.5; }
|
||||
.room-panel>p:not(.eyebrow) { max-width:35rem; margin:.35rem 0; color:#c6d2d4; line-height:1.6; }
|
||||
.reveal-copy { animation:copy-reveal .65s ease both; }
|
||||
@keyframes copy-reveal { from { opacity:0; transform:translateY(.35rem); filter:blur(2px); } to { opacity:1; transform:none; filter:none; } }
|
||||
.room-panel .notice { color:var(--cyan)!important; font-family:'IBM Plex Mono'; font-size:.76rem; white-space:pre-line; }
|
||||
.interaction-list { display:flex; flex-wrap:wrap; gap:.5rem; margin-top:1rem; }.interaction-list button { padding:.55rem .7rem; font-size:.68rem; }
|
||||
.movement-pad { position:absolute; right:2rem; bottom:6.2rem; display:grid; grid-template:repeat(3,2.7rem)/repeat(3,2.7rem); gap:.25rem; }
|
||||
.movement-pad { position:absolute; right:2rem; bottom:6.2rem; display:grid; grid-template:repeat(3,2.7rem)/repeat(3,2.7rem); gap:.25rem; z-index:10; }
|
||||
.movement-pad button { padding:0; font-size:1.2rem; background:rgba(2,8,11,.78); }.movement-pad .north { grid-area:1/2; }.movement-pad .west { grid-area:2/1; }.movement-pad .position { grid-area:2/2; display:grid; place-items:center; color:var(--muted); font:.58rem 'IBM Plex Mono'; }.movement-pad .east { grid-area:2/3; }.movement-pad .south { grid-area:3/2; }
|
||||
.command-bar { position:absolute; left:0; right:0; bottom:0; display:flex; justify-content:center; gap:.5rem; padding:.8rem; background:rgba(1,6,8,.91); border-top:1px solid rgba(158,239,255,.16); }.command-bar button { border:0; font-size:.66rem; }
|
||||
.modal-layer { position:absolute; inset:0; z-index:20; display:grid; place-items:center; padding:2rem; background:rgba(0,3,5,.72); backdrop-filter:blur(7px); }
|
||||
.interaction-modal, .overlay-card { width:min(43rem,92vw); max-height:86vh; overflow:auto; padding:2rem; }.terminal-copy { white-space:pre-line; color:#bfe6ea; line-height:1.75; }
|
||||
.command-bar { position:absolute; left:0; right:0; bottom:0; display:flex; justify-content:center; gap:.5rem; padding:.8rem; background:rgba(1,6,8,.91); border-top:1px solid rgba(158,239,255,.16); z-index:15; }.command-bar button { border:0; font-size:.66rem; }
|
||||
.modal-layer { position:absolute; inset:0; z-index:30; display:grid; place-items:center; padding:2rem; background:rgba(0,3,5,.75); backdrop-filter:blur(8px); }
|
||||
.interaction-modal, .overlay-card { width:min(44rem,92vw); max-height:86vh; overflow:auto; padding:2rem; }.terminal-copy { white-space:pre-line; color:#bfe6ea; line-height:1.75; }
|
||||
.terminal-copy strong { color:var(--cyan); }
|
||||
.close-button { position:absolute; top:.65rem; right:.65rem; border:0; font-size:1.3rem; padding:.35rem .6rem; }
|
||||
.choice-list { display:flex; flex-direction:column; gap:.6rem; margin-top:1.5rem; }.choice-list button { text-align:left; }
|
||||
.choice-list { display:flex; flex-direction:column; gap:.6rem; margin-top:1.5rem; }.choice-list button { text-align:left; line-height:1.4; padding:.8rem 1rem; }
|
||||
.action-picker small, .interaction-modal small { display:block; margin-top:1.25rem; color:var(--muted); letter-spacing:.12em; }
|
||||
.map-card { width:min(62rem,94vw); }.map-grid { display:grid; grid-template-columns:repeat(9,minmax(2.5rem,1fr)); grid-template-rows:repeat(4,3.6rem); gap:.35rem; margin:2rem 0; }
|
||||
.map-cell { display:grid; place-items:center; border:1px solid rgba(158,239,255,.1); color:#44565a; font:1rem 'IBM Plex Mono'; }.map-cell.visited { color:var(--cyan); background:rgba(65,213,240,.06); border-color:var(--line); }.map-cell.current { color:#021014; background:var(--cyan); box-shadow:0 0 24px rgba(66,216,244,.4); }
|
||||
.inventory-card ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.65rem; list-style:none; margin:1.5rem 0 0; padding:0; }.inventory-card li { padding:1rem; border:1px solid var(--line); }.inventory-card li small { display:block; color:var(--muted); font-size:.58rem; letter-spacing:.16em; }.inventory-card li strong { display:block; margin:.3rem 0; color:var(--cyan); font-weight:500; letter-spacing:.06em; }.inventory-card li p { margin:.25rem 0 0; color:#b8c8cb; font-size:.78rem; line-height:1.5; }
|
||||
.map-card { width:min(34rem,92vw); max-height:88vh; padding:1.8rem; }
|
||||
.map-grid { display:grid; grid-template-columns:repeat(4,minmax(3.2rem,4.5rem)); grid-template-rows:repeat(10,minmax(2.1rem,2.7rem)); justify-content:center; gap:.35rem; margin:1.2rem auto; }
|
||||
.map-cell { display:grid; place-items:center; border:1px solid rgba(158,239,255,.1); color:#44565a; font:.95rem 'IBM Plex Mono'; border-radius:2px; }
|
||||
.map-cell.visited { color:var(--cyan); background:rgba(65,213,240,.06); border-color:var(--line); }
|
||||
.map-cell.current { color:#021014; background:var(--cyan); box-shadow:0 0 24px rgba(66,216,244,.4); font-weight:bold; }
|
||||
|
||||
.inventory-card ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.65rem; list-style:none; margin:1.5rem 0 0; padding:0; }
|
||||
.inventory-card li { padding:1rem; border:1px solid var(--line); cursor:pointer; transition:.15s ease; background:rgba(0,5,8,.4); }
|
||||
.inventory-card li:hover, .inventory-card li.selected-item { border-color:var(--cyan); background:rgba(66,216,244,.06); }
|
||||
.inventory-card li small { display:block; color:var(--muted); font-size:.58rem; letter-spacing:.16em; }
|
||||
.inventory-card li strong { display:block; margin:.3rem 0; color:var(--cyan); font-weight:500; letter-spacing:.06em; }
|
||||
.inventory-card li p { margin:.25rem 0 0; color:#b8c8cb; font-size:.78rem; line-height:1.5; }
|
||||
.item-inspect-box { margin-top:1.2rem; padding:1.2rem; border:1px solid var(--cyan-strong); background:rgba(3,15,20,.85); font-family:'IBM Plex Mono',monospace; font-size:.76rem; color:#d8f4f8; line-height:1.6; }
|
||||
.item-inspect-box .inspect-actions { margin-top:1rem; display:flex; gap:.6rem; }
|
||||
|
||||
.archive-list { display:flex; flex-direction:column; gap:.55rem; margin-top:1.5rem; }.archive-list details { border:1px solid var(--line); background:rgba(0,6,8,.45); }.archive-list summary { padding:1rem; color:var(--cyan); cursor:pointer; letter-spacing:.07em; }.archive-list details p { margin:0; padding:0 1rem 1rem; }
|
||||
.pause-card, .settings-card { display:flex; flex-direction:column; gap:.75rem; width:min(29rem,92vw); }.settings-card label { margin-top:.5rem; color:var(--muted); font-size:.76rem; letter-spacing:.09em; }.segmented-control { display:grid; grid-template-columns:1fr 1fr; gap:.4rem; }.settings-card input { accent-color:var(--cyan-strong); }
|
||||
.setting-toggle.active { color:#031013; background:var(--cyan); border-color:var(--cyan); }
|
||||
.danger-action { color:#ff9da2; border-color:rgba(255,77,87,.55); }.danger-action:hover, .danger-action:focus-visible { color:white; background:#a51f29; border-color:#ff5e68; }
|
||||
.confirmation-card { width:min(34rem,92vw); }.confirmation-card>p:not(.eyebrow) { color:#bdcacc; line-height:1.65; }.confirmation-actions { display:flex; justify-content:flex-end; gap:.65rem; margin-top:1.5rem; }
|
||||
.outcome-screen { height:100%; display:flex; flex-direction:column; align-items:flex-start; justify-content:center; padding:10vw; background:radial-gradient(circle at 70% 40%,#11242b,#020507 55%); }.outcome-screen h1 { margin:.2rem 0; font-size:clamp(3rem,8vw,7rem); font-weight:300; letter-spacing:.17em; }.outcome-screen>p:not(.eyebrow) { max-width:44rem; color:#b8c8cb; line-height:1.8; }.outcome-screen button { margin:.35rem .35rem .35rem 0; }.death-screen { background:radial-gradient(circle at 70% 40%,#351014,#050203 55%); }.death-screen .eyebrow { color:var(--danger); }
|
||||
#blazor-error-ui { display:none; position:fixed; inset:auto 0 0; z-index:100; padding:1rem; background:#8b1e24; color:white; }
|
||||
@media(max-width:720px) { .title-card { left:1.5rem;top:8vh; }.title-card h1 { font-size:2.7rem;letter-spacing:.12em; }.title-menu { left:1.5rem;bottom:5rem; }.room-panel { left:0;bottom:5.4rem;width:100%;padding:1.2rem;background:rgba(2,8,11,.82); }.movement-pad { right:1rem;bottom:15rem; }.command-bar { overflow-x:auto;justify-content:flex-start; }.command-bar button { white-space:nowrap; }.map-grid { grid-template-columns:repeat(9,2.3rem);overflow:auto; }.briefing-card { left:1rem;width:calc(100vw - 2rem);padding:1.4rem; }.briefing-card dl { grid-template-columns:1fr; }.briefing-card dd { margin-bottom:.5rem; } }
|
||||
@media(max-width:720px) { .inventory-card ul { grid-template-columns:1fr; } }
|
||||
.play-screen { position:absolute; inset:0; width:100%; height:100%; min-height:100%; overflow:hidden; }
|
||||
.play-screen.scan-mode-active { filter:drop-shadow(0 0 10px rgba(66,216,244,.3)); }
|
||||
.viewport-layer { position:absolute; inset:0; overflow:hidden; z-index:1; }
|
||||
.parallax-bg { position:absolute; inset:-4%; background-size:cover; background-position:center; transform:translate3d(calc(var(--mouse-px, 0) * -14px), calc(var(--mouse-py, 0) * -14px), 0) scale(1.05); transition:transform .1s cubic-bezier(0.2, 0, 0.2, 1); }
|
||||
|
||||
.hotspots-layer { position:absolute; inset:0; pointer-events:none; z-index:5; }
|
||||
.hotspot-pin { position:absolute; transform:translate(-50%, -50%); pointer-events:auto; display:flex; align-items:center; cursor:pointer; background:transparent; border:none; padding:0; outline:none; transition:all .2s ease; }
|
||||
.hotspot-bracket { width:2.2rem; height:2.2rem; display:grid; place-items:center; border:1px solid rgba(66,216,244,.4); background:rgba(2,12,16,.65); backdrop-filter:blur(4px); color:var(--cyan); font-family:'IBM Plex Mono',monospace; font-size:.78rem; transition:all .2s ease; box-shadow:0 0 12px rgba(66,216,244,.2); }
|
||||
.hotspot-pin:hover .hotspot-bracket, .hotspot-pin:focus-visible .hotspot-bracket { border-color:#fff; background:var(--cyan); color:#020a0d; transform:scale(1.2) rotate(45deg); box-shadow:0 0 20px rgba(66,216,244,.8); }
|
||||
.hotspot-pin:hover .hotspot-bracket span, .hotspot-pin:focus-visible .hotspot-bracket span { transform:rotate(-45deg); }
|
||||
.hotspot-pin.hazard .hotspot-bracket { border-color:rgba(255,77,87,.6); color:var(--danger); }
|
||||
.hotspot-pin.hazard:hover .hotspot-bracket { background:var(--danger); border-color:#fff; color:#fff; }
|
||||
|
||||
.hotspot-tooltip { position:absolute; left:calc(100% + .7rem); white-space:nowrap; padding:.3rem .6rem; background:rgba(2,9,12,.9); border:1px solid var(--line); border-left:3px solid var(--cyan); color:#d8f4f8; font-family:'IBM Plex Mono',monospace; font-size:.65rem; letter-spacing:.1em; pointer-events:none; opacity:0; transform:translateX(-6px); transition:all .2s ease; }
|
||||
.hotspot-pin:hover .hotspot-tooltip, .hotspot-pin:focus-visible .hotspot-tooltip { opacity:1; transform:translateX(0); }
|
||||
.hotspot-tooltip small { display:block; color:var(--muted); font-size:.55rem; margin-top:.15rem; }
|
||||
|
||||
.lidar-overlay { position:absolute; inset:0; pointer-events:none; background:linear-gradient(rgba(3,25,20,.15), rgba(3,25,20,.35)), repeating-linear-gradient(0deg, transparent, transparent 3px, rgba(66,216,244,.06) 3px, rgba(66,216,244,.06) 4px); z-index:4; mix-blend-mode:screen; animation:lidar-fade .3s ease; }
|
||||
.lidar-sweep-bar { position:absolute; top:0; left:0; right:0; height:4px; background:linear-gradient(90deg, transparent, rgba(66,216,244,.8), transparent); box-shadow:0 0 16px var(--cyan); animation:lidar-sweep 3.5s linear infinite; }
|
||||
@keyframes lidar-sweep { 0% { top:0%; opacity:0; } 10% { opacity:1; } 90% { opacity:1; } 100% { top:100%; opacity:0; } }
|
||||
@keyframes lidar-fade { from { opacity:0; } to { opacity:1; } }
|
||||
|
||||
.lidar-tag { position:absolute; transform:translate(-50%, -150%); padding:.25rem .5rem; background:rgba(0,18,14,.88); border:1px solid #3de3bb; color:#3de3bb; font-family:'IBM Plex Mono',monospace; font-size:.62rem; letter-spacing:.08em; pointer-events:none; box-shadow:0 0 12px rgba(61,227,187,.3); }
|
||||
|
||||
.breaker-switchboard { width:min(38rem,94vw); }
|
||||
.breaker-grid { display:grid; grid-template-columns:1fr 1fr; gap:1.2rem; margin:1.5rem 0; }
|
||||
.breaker-card { border:1px solid var(--line); padding:1.2rem; background:rgba(2,10,14,.75); text-align:center; transition:.2s ease; cursor:pointer; }
|
||||
.breaker-card:hover { border-color:var(--cyan); background:rgba(66,216,244,.08); }
|
||||
.breaker-card.active { border-color:var(--cyan); background:rgba(66,216,244,.15); box-shadow:0 0 20px rgba(66,216,244,.3); }
|
||||
.breaker-lever { width:3.5rem; height:6.5rem; margin:1rem auto; border:2px solid #526f74; background:#041014; border-radius:4px; position:relative; }
|
||||
.breaker-lever-handle { width:100%; height:45%; background:var(--cyan); position:absolute; top:0; transition:all .25s cubic-bezier(0.18, 0.89, 0.32, 1.28); box-shadow:0 0 10px rgba(66,216,244,.5); }
|
||||
.breaker-card:hover .breaker-lever-handle { background:#fff; }
|
||||
.breaker-lever.down .breaker-lever-handle { top:55%; background:#ff4d57; box-shadow:0 0 10px rgba(255,77,87,.5); }
|
||||
.breaker-meter { font-family:'IBM Plex Mono',monospace; font-size:.7rem; color:var(--cyan); margin-top:.6rem; }
|
||||
|
||||
.dust-layer { position:absolute; inset:0; pointer-events:none; background-image:radial-gradient(1px 1px at 20px 30px, #ffffff33, rgba(0,0,0,0)), radial-gradient(1px 1px at 40px 70px, #42d8f433, rgba(0,0,0,0)), radial-gradient(1.5px 1.5px at 90px 40px, #ffffff22, rgba(0,0,0,0)); background-repeat:repeat; background-size:120px 120px; animation:dust-float 20s linear infinite; z-index:3; opacity:.4; }
|
||||
@keyframes dust-float { 0% { transform:translateY(0); } 100% { transform:translateY(-120px); } }
|
||||
|
||||
@media(max-width:720px) { .title-card { left:1.5rem;top:8vh; }.title-card h1 { font-size:2.7rem;letter-spacing:.12em; }.title-menu { left:1.5rem;bottom:5rem; }.room-panel { left:0;bottom:5.4rem;width:100%;padding:1.2rem;background:rgba(2,8,11,.82); }.movement-pad { right:1rem;bottom:15rem; }.command-bar { overflow-x:auto;justify-content:flex-start; }.command-bar button { white-space:nowrap; }.map-grid { grid-template-columns:repeat(4,2.8rem);grid-template-rows:repeat(10,1.9rem);overflow:auto; }.briefing-card { left:1rem;width:calc(100vw - 2rem);padding:1.4rem; }.briefing-card dl { grid-template-columns:1fr; }.briefing-card dd { margin-bottom:.5rem; } }
|
||||
@media(max-width:720px) { .inventory-card ul { grid-template-columns:1fr; } .breaker-grid { grid-template-columns:1fr; } }
|
||||
@media(prefers-reduced-motion:reduce) { *, *::before, *::after { animation-duration:.01ms!important; animation-iteration-count:1!important; transition-duration:.01ms!important; } }
|
||||
|
||||
@@ -1,140 +1,663 @@
|
||||
{
|
||||
"version": 1,
|
||||
"version": 2,
|
||||
"startRoomId": "loc_01_exterior_access",
|
||||
"initialItems": ["contractor_credential", "diagnostic_scanner"],
|
||||
"items": [
|
||||
{ "id": "contractor_credential", "nameKey": "item.contractor_credential.name", "descriptionKey": "item.contractor_credential.description", "category": "credential" },
|
||||
{ "id": "diagnostic_scanner", "nameKey": "item.diagnostic_scanner.name", "descriptionKey": "item.diagnostic_scanner.description", "category": "tool" },
|
||||
{ "id": "thermal_clamp", "nameKey": "item.thermal_clamp.name", "descriptionKey": "item.thermal_clamp.description", "category": "tool" },
|
||||
{ "id": "manual_override", "nameKey": "item.manual_override.name", "descriptionKey": "item.manual_override.description", "category": "module" }
|
||||
{
|
||||
"id": "contractor_credential",
|
||||
"nameKey": "item.contractor_credential.name",
|
||||
"descriptionKey": "item.contractor_credential.description",
|
||||
"detailedKey": "item.contractor_credential.detail",
|
||||
"category": "credential"
|
||||
},
|
||||
{
|
||||
"id": "diagnostic_scanner",
|
||||
"nameKey": "item.diagnostic_scanner.name",
|
||||
"descriptionKey": "item.diagnostic_scanner.description",
|
||||
"detailedKey": "item.diagnostic_scanner.detail",
|
||||
"category": "tool"
|
||||
},
|
||||
{
|
||||
"id": "thermal_clamp",
|
||||
"nameKey": "item.thermal_clamp.name",
|
||||
"descriptionKey": "item.thermal_clamp.description",
|
||||
"detailedKey": "item.thermal_clamp.detail",
|
||||
"category": "tool"
|
||||
},
|
||||
{
|
||||
"id": "manual_override",
|
||||
"nameKey": "item.manual_override.name",
|
||||
"descriptionKey": "item.manual_override.description",
|
||||
"detailedKey": "item.manual_override.detail",
|
||||
"category": "module"
|
||||
}
|
||||
],
|
||||
"archive": [
|
||||
{ "id": "log_01", "titleKey": "archive.log_01.title", "contentKey": "log.01" },
|
||||
{ "id": "containment_record", "titleKey": "archive.containment_record.title", "contentKey": "terminal.operations" },
|
||||
{ "id": "incident_log", "titleKey": "archive.incident_log.title", "contentKey": "archive.incident_log.content" },
|
||||
{ "id": "log_02", "titleKey": "archive.log_02.title", "contentKey": "log.02" },
|
||||
{ "id": "log_03", "titleKey": "archive.log_03.title", "contentKey": "log.03" }
|
||||
{ "id": "engineer_notes", "titleKey": "archive.engineer_notes.title", "contentKey": "archive.engineer_notes.content" },
|
||||
{ "id": "log_03", "titleKey": "archive.log_03.title", "contentKey": "log.03" },
|
||||
{ "id": "core_manifest", "titleKey": "archive.core_manifest.title", "contentKey": "archive.core_manifest.content" }
|
||||
],
|
||||
"rooms": [
|
||||
{
|
||||
"id": "loc_01_exterior_access", "nameKey": "room.loc_01.name", "descriptionKey": "room.loc_01.description", "image": "assets/images/locations/loc_01_exterior_access.webp", "ambient": "assets/audio/amb_facility.mp3", "x": 0, "y": 1,
|
||||
"exits": { "east": { "target": "loc_02_security_lobby", "requiresFlags": ["entry_authorized"], "lockedMessageKey": "lock.entry" } },
|
||||
"interactions": [
|
||||
{ "id": "contractor_terminal", "labelKey": "action.entryTerminal", "contentKey": "terminal.entry", "type": "terminal", "forbiddenFlags": ["entry_authorized"], "setFlags": ["entry_authorized"], "sound": "assets/audio/sfx_ui_confirm.mp3", "checkpoint": true }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_02_security_lobby", "nameKey": "room.loc_02.name", "descriptionKey": "room.loc_02.description", "image": "assets/images/locations/loc_02_security_lobby.webp", "ambient": "assets/audio/amb_facility.mp3", "x": 1, "y": 1,
|
||||
"exits": { "west": { "target": "loc_01_exterior_access" }, "east": { "target": "loc_03_main_corridor" } },
|
||||
"interactions": [
|
||||
{ "id": "personnel_status", "labelKey": "action.securityTerminal", "contentKey": "terminal.security", "type": "terminal", "forbiddenFlags": ["personnel_checked"], "setFlags": ["personnel_checked"], "sound": "assets/audio/sfx_ui_confirm.mp3" },
|
||||
{ "id": "security_cameras", "labelKey": "action.securityCameras", "contentKey": "terminal.cameras", "type": "terminal", "sound": "assets/audio/sfx_ui_confirm.mp3" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_03_main_corridor", "nameKey": "room.loc_03.name", "descriptionKey": "room.loc_03.description", "image": "assets/images/locations/loc_03_main_corridor.webp", "ambient": "assets/audio/amb_facility.mp3", "alternateImage": "assets/images/locations/loc_03_main_corridor_alarm.webp", "alternateImageFlag": "power_restored", "x": 2, "y": 1,
|
||||
"id": "loc_01_exterior_access",
|
||||
"nameKey": "room.loc_01.name",
|
||||
"descriptionKey": "room.loc_01.description",
|
||||
"scanKey": "scan.loc_01",
|
||||
"image": "assets/images/locations/loc_01_exterior_access.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"x": 1,
|
||||
"y": 9,
|
||||
"exits": {
|
||||
"west": { "target": "loc_02_security_lobby" }, "north": { "target": "loc_06_operations_room" }, "south": { "target": "loc_04_maintenance_control" },
|
||||
"east": { "target": "loc_07_service_elevator", "requiresFlags": ["power_restored"], "lockedMessageKey": "lock.auxPower" }
|
||||
"north": {
|
||||
"target": "loc_02_security_lobby",
|
||||
"requiresFlags": ["entry_authorized"],
|
||||
"lockedMessageKey": "lock.entry"
|
||||
}
|
||||
},
|
||||
"interactions": []
|
||||
"interactions": [
|
||||
{
|
||||
"id": "contractor_terminal",
|
||||
"labelKey": "action.entryTerminal",
|
||||
"contentKey": "terminal.entry",
|
||||
"type": "terminal",
|
||||
"forbiddenFlags": ["entry_authorized"],
|
||||
"setFlags": ["entry_authorized"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3",
|
||||
"checkpoint": true
|
||||
},
|
||||
{
|
||||
"id": "loc_04_maintenance_control", "nameKey": "room.loc_04.name", "descriptionKey": "room.loc_04.description", "image": "assets/images/locations/loc_04_maintenance_control.webp", "ambient": "assets/audio/amb_facility.mp3", "alternateImage": "assets/images/locations/loc_04_maintenance_control_power.webp", "alternateImageFlag": "power_restored", "x": 2, "y": 2,
|
||||
"exits": { "north": { "target": "loc_03_main_corridor" }, "west": { "target": "loc_05_staff_access" } },
|
||||
"interactions": [
|
||||
{ "id": "auxiliary_grid", "labelKey": "action.restorePower", "contentKey": "terminal.power", "type": "system", "forbiddenFlags": ["power_restored"], "setFlags": ["power_restored"], "sound": "assets/audio/sfx_power_system.mp3", "checkpoint": true }
|
||||
"id": "gate_inspection",
|
||||
"labelKey": "action.inspectGate",
|
||||
"contentKey": "terminal.gateInspection",
|
||||
"type": "system",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_01_terminal", "labelKey": "hotspot.loc_01.terminal", "interactionId": "contractor_terminal", "x": 76, "y": 58, "icon": "terminal", "telemetryKey": "telemetry.loc_01.terminal", "forbiddenFlags": ["entry_authorized"] },
|
||||
{ "id": "hs_01_gate", "labelKey": "hotspot.loc_01.gate", "interactionId": "gate_inspection", "x": 48, "y": 44, "icon": "lock", "telemetryKey": "telemetry.loc_01.gate" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_05_staff_access", "nameKey": "room.loc_05.name", "descriptionKey": "room.loc_05.description", "image": "assets/images/locations/loc_05_staff_access.webp", "ambient": "assets/audio/amb_facility.mp3", "x": 1, "y": 2,
|
||||
"exits": { "east": { "target": "loc_04_maintenance_control" } },
|
||||
"id": "loc_02_security_lobby",
|
||||
"nameKey": "room.loc_02.name",
|
||||
"descriptionKey": "room.loc_02.description",
|
||||
"scanKey": "scan.loc_02",
|
||||
"image": "assets/images/locations/loc_02_security_lobby.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"x": 1,
|
||||
"y": 8,
|
||||
"exits": {
|
||||
"south": { "target": "loc_01_exterior_access" },
|
||||
"north": { "target": "loc_03_main_corridor" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "log_01", "labelKey": "action.readLog01", "contentKey": "log.01", "type": "archive", "archiveId": "log_01", "forbiddenFlags": ["log_01_found"], "setFlags": ["log_01_found"], "sound": "assets/audio/sfx_ui_confirm.mp3" }
|
||||
{
|
||||
"id": "personnel_status",
|
||||
"labelKey": "action.securityTerminal",
|
||||
"contentKey": "terminal.security",
|
||||
"type": "terminal",
|
||||
"forbiddenFlags": ["personnel_checked"],
|
||||
"setFlags": ["personnel_checked"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "security_cameras",
|
||||
"labelKey": "action.securityCameras",
|
||||
"contentKey": "terminal.cameras",
|
||||
"type": "terminal",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "security_roster",
|
||||
"labelKey": "action.securityRoster",
|
||||
"contentKey": "terminal.securityRoster",
|
||||
"type": "archive",
|
||||
"archiveId": "incident_log",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_02_terminal", "labelKey": "hotspot.loc_02.terminal", "interactionId": "personnel_status", "x": 32, "y": 56, "icon": "terminal", "telemetryKey": "telemetry.loc_02.terminal" },
|
||||
{ "id": "hs_02_cameras", "labelKey": "hotspot.loc_02.cameras", "interactionId": "security_cameras", "x": 64, "y": 38, "icon": "sensor", "telemetryKey": "telemetry.loc_02.cameras" },
|
||||
{ "id": "hs_02_roster", "labelKey": "hotspot.loc_02.roster", "interactionId": "security_roster", "x": 48, "y": 66, "icon": "archive", "telemetryKey": "telemetry.loc_02.roster" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_06_operations_room", "nameKey": "room.loc_06.name", "descriptionKey": "room.loc_06.description", "image": "assets/images/locations/loc_06_operations_room.webp", "ambient": "assets/audio/amb_facility.mp3", "x": 2, "y": 0,
|
||||
"exits": { "south": { "target": "loc_03_main_corridor" } },
|
||||
"id": "loc_03_main_corridor",
|
||||
"nameKey": "room.loc_03.name",
|
||||
"descriptionKey": "room.loc_03.description",
|
||||
"scanKey": "scan.loc_03",
|
||||
"image": "assets/images/locations/loc_03_main_corridor.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"alternateImage": "assets/images/locations/loc_03_main_corridor_alarm.webp",
|
||||
"alternateImageFlag": "power_restored",
|
||||
"x": 1,
|
||||
"y": 7,
|
||||
"exits": {
|
||||
"south": { "target": "loc_02_security_lobby" },
|
||||
"west": { "target": "loc_06_operations_room" },
|
||||
"east": { "target": "loc_04_maintenance_control" },
|
||||
"north": {
|
||||
"target": "loc_07_service_elevator",
|
||||
"requiresFlags": ["power_restored"],
|
||||
"lockedMessageKey": "lock.auxPower"
|
||||
}
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "containment_record", "labelKey": "action.operationsTerminal", "contentKey": "terminal.operations", "type": "archive", "archiveId": "containment_record", "forbiddenFlags": ["containment_seen"], "setFlags": ["containment_seen"], "sound": "assets/audio/sfx_system_disturbance.mp3" }
|
||||
{
|
||||
"id": "environmental_readout",
|
||||
"labelKey": "action.readEnvironmental",
|
||||
"contentKey": "terminal.environmental",
|
||||
"type": "system",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_03_env", "labelKey": "hotspot.loc_03.environmental", "interactionId": "environmental_readout", "x": 50, "y": 32, "icon": "sensor", "telemetryKey": "telemetry.loc_03.env" },
|
||||
{ "id": "hs_03_elevator_door", "labelKey": "hotspot.loc_03.elevator", "x": 78, "y": 54, "icon": "lock", "telemetryKey": "telemetry.loc_03.elevator" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_07_service_elevator", "nameKey": "room.loc_07.name", "descriptionKey": "room.loc_07.description", "image": "assets/images/locations/loc_07_service_elevator.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "alternateImage": "assets/images/locations/loc_07_service_elevator_stalled.webp", "alternateImageFlag": "elevator_stalled", "x": 3, "y": 1,
|
||||
"exits": { "west": { "target": "loc_03_main_corridor" }, "south": { "target": "loc_08_lower_landing", "requiresFlags": ["elevator_cycle_complete"], "lockedMessageKey": "lock.elevator" } },
|
||||
"id": "loc_04_maintenance_control",
|
||||
"nameKey": "room.loc_04.name",
|
||||
"descriptionKey": "room.loc_04.description",
|
||||
"scanKey": "scan.loc_04",
|
||||
"image": "assets/images/locations/loc_04_maintenance_control.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"alternateImage": "assets/images/locations/loc_04_maintenance_control_power.webp",
|
||||
"alternateImageFlag": "power_restored",
|
||||
"x": 2,
|
||||
"y": 7,
|
||||
"exits": {
|
||||
"west": { "target": "loc_03_main_corridor" },
|
||||
"east": { "target": "loc_05_staff_access" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "elevator_descent", "labelKey": "action.descend", "contentKey": "event.elevatorStall", "type": "event", "forbiddenFlags": ["elevator_stalled", "elevator_cycle_complete"], "setFlags": ["elevator_stalled", "claustrophobia_detected"], "sound": "assets/audio/sfx_elevator_stall.mp3" },
|
||||
{ "id": "elevator_resume", "labelKey": "action.resumeDescent", "contentKey": "event.elevatorResume", "type": "event", "requiresFlags": ["elevator_stalled"], "forbiddenFlags": ["elevator_cycle_complete"], "setFlags": ["elevator_cycle_complete"], "clearFlags": ["elevator_stalled"], "sound": "assets/audio/sfx_door_heavy.mp3", "checkpoint": true }
|
||||
{
|
||||
"id": "auxiliary_grid",
|
||||
"labelKey": "action.restorePower",
|
||||
"contentKey": "terminal.power",
|
||||
"type": "system",
|
||||
"forbiddenFlags": ["power_restored"],
|
||||
"setFlags": ["power_restored"],
|
||||
"sound": "assets/audio/sfx_power_system.mp3",
|
||||
"checkpoint": true
|
||||
},
|
||||
{
|
||||
"id": "grid_schematic",
|
||||
"labelKey": "action.inspectGrid",
|
||||
"contentKey": "terminal.gridSchematic",
|
||||
"type": "system",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_04_grid", "labelKey": "hotspot.loc_04.grid", "interactionId": "auxiliary_grid", "x": 54, "y": 52, "icon": "breaker", "telemetryKey": "telemetry.loc_04.grid", "forbiddenFlags": ["power_restored"] },
|
||||
{ "id": "hs_04_schematic", "labelKey": "hotspot.loc_04.schematic", "interactionId": "grid_schematic", "x": 26, "y": 46, "icon": "sensor", "telemetryKey": "telemetry.loc_04.schematic" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_08_lower_landing", "nameKey": "room.loc_08.name", "descriptionKey": "room.loc_08.description", "image": "assets/images/locations/loc_08_lower_landing.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "x": 3, "y": 2,
|
||||
"exits": { "north": { "target": "loc_07_service_elevator" }, "east": { "target": "loc_09_cooling_junction" }, "south": { "target": "loc_11_equipment_storage" } },
|
||||
"id": "loc_05_staff_access",
|
||||
"nameKey": "room.loc_05.name",
|
||||
"descriptionKey": "room.loc_05.description",
|
||||
"scanKey": "scan.loc_05",
|
||||
"image": "assets/images/locations/loc_05_staff_access.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"x": 3,
|
||||
"y": 7,
|
||||
"exits": {
|
||||
"west": { "target": "loc_04_maintenance_control" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "emergency_supply", "labelKey": "action.takeThermalClamp", "contentKey": "terminal.thermalClamp", "type": "equipment", "forbiddenFlags": ["thermal_clamp_found"], "setFlags": ["thermal_clamp_found"], "addItems": ["thermal_clamp"], "sound": "assets/audio/sfx_ui_confirm.mp3" }
|
||||
{
|
||||
"id": "log_01",
|
||||
"labelKey": "action.readLog01",
|
||||
"contentKey": "log.01",
|
||||
"type": "archive",
|
||||
"archiveId": "log_01",
|
||||
"forbiddenFlags": ["log_01_found"],
|
||||
"setFlags": ["log_01_found"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "staff_correspondence",
|
||||
"labelKey": "action.readCorrespondence",
|
||||
"contentKey": "terminal.correspondence",
|
||||
"type": "terminal",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_05_log_01", "labelKey": "hotspot.loc_05.log_01", "interactionId": "log_01", "x": 38, "y": 55, "icon": "archive", "telemetryKey": "telemetry.loc_05.log" },
|
||||
{ "id": "hs_05_mail", "labelKey": "hotspot.loc_05.correspondence", "interactionId": "staff_correspondence", "x": 68, "y": 58, "icon": "terminal", "telemetryKey": "telemetry.loc_05.mail" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_09_cooling_junction", "nameKey": "room.loc_09.name", "descriptionKey": "room.loc_09.description", "image": "assets/images/locations/loc_09_cooling_junction.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "x": 4, "y": 2,
|
||||
"exits": { "west": { "target": "loc_08_lower_landing" }, "south": { "target": "loc_10_cooling_control" }, "east": { "target": "loc_12_service_passage", "requiresFlags": ["cooling_restored"], "lockedMessageKey": "lock.cooling" } },
|
||||
"id": "loc_06_operations_room",
|
||||
"nameKey": "room.loc_06.name",
|
||||
"descriptionKey": "room.loc_06.description",
|
||||
"scanKey": "scan.loc_06",
|
||||
"image": "assets/images/locations/loc_06_operations_room.webp",
|
||||
"ambient": "assets/audio/amb_facility.mp3",
|
||||
"x": 0,
|
||||
"y": 7,
|
||||
"exits": {
|
||||
"east": { "target": "loc_03_main_corridor" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "log_02", "labelKey": "action.readLog02", "contentKey": "log.02", "type": "archive", "archiveId": "log_02", "forbiddenFlags": ["log_02_found"], "setFlags": ["log_02_found"], "sound": "assets/audio/sfx_ui_confirm.mp3" }
|
||||
{
|
||||
"id": "containment_record",
|
||||
"labelKey": "action.operationsTerminal",
|
||||
"contentKey": "terminal.operations",
|
||||
"type": "archive",
|
||||
"archiveId": "containment_record",
|
||||
"forbiddenFlags": ["containment_seen"],
|
||||
"setFlags": ["containment_seen"],
|
||||
"sound": "assets/audio/sfx_system_disturbance.mp3"
|
||||
},
|
||||
{
|
||||
"id": "containment_timeline",
|
||||
"labelKey": "action.viewTimeline",
|
||||
"contentKey": "terminal.timeline",
|
||||
"type": "terminal",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_06_containment", "labelKey": "hotspot.loc_06.containment", "interactionId": "containment_record", "x": 50, "y": 42, "icon": "terminal", "telemetryKey": "telemetry.loc_06.containment" },
|
||||
{ "id": "hs_06_timeline", "labelKey": "hotspot.loc_06.timeline", "interactionId": "containment_timeline", "x": 76, "y": 50, "icon": "sensor", "telemetryKey": "telemetry.loc_06.timeline" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_10_cooling_control", "nameKey": "room.loc_10.name", "descriptionKey": "room.loc_10.description", "image": "assets/images/locations/loc_10_cooling_control.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "x": 4, "y": 3,
|
||||
"exits": { "north": { "target": "loc_09_cooling_junction" } },
|
||||
"id": "loc_07_service_elevator",
|
||||
"nameKey": "room.loc_07.name",
|
||||
"descriptionKey": "room.loc_07.description",
|
||||
"scanKey": "scan.loc_07",
|
||||
"image": "assets/images/locations/loc_07_service_elevator.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"alternateImage": "assets/images/locations/loc_07_service_elevator_stalled.webp",
|
||||
"alternateImageFlag": "elevator_stalled",
|
||||
"x": 1,
|
||||
"y": 6,
|
||||
"exits": {
|
||||
"south": { "target": "loc_03_main_corridor" },
|
||||
"north": {
|
||||
"target": "loc_08_lower_landing",
|
||||
"requiresFlags": ["elevator_cycle_complete"],
|
||||
"lockedMessageKey": "lock.elevator"
|
||||
}
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "power_routing", "labelKey": "action.routePower", "contentKey": "terminal.routing", "type": "system", "forbiddenFlags": ["cooling_restored"], "choices": [
|
||||
{ "labelKey": "choice.coolingOnly", "resultKey": "result.coolingOnly", "setFlags": ["cooling_restored", "security_disabled"], "sound": "assets/audio/sfx_power_system.mp3", "checkpoint": true },
|
||||
{ "labelKey": "choice.balanced", "resultKey": "result.balanced", "setFlags": ["cooling_restored", "security_maintained"], "sound": "assets/audio/sfx_power_system.mp3", "checkpoint": true }
|
||||
] }
|
||||
{
|
||||
"id": "elevator_descent",
|
||||
"labelKey": "action.descend",
|
||||
"contentKey": "event.elevatorStall",
|
||||
"type": "event",
|
||||
"forbiddenFlags": ["elevator_stalled", "elevator_cycle_complete"],
|
||||
"setFlags": ["elevator_stalled", "claustrophobia_detected"],
|
||||
"sound": "assets/audio/sfx_elevator_stall.mp3"
|
||||
},
|
||||
{
|
||||
"id": "elevator_resume",
|
||||
"labelKey": "action.resumeDescent",
|
||||
"contentKey": "event.elevatorResume",
|
||||
"type": "event",
|
||||
"requiresFlags": ["elevator_stalled"],
|
||||
"forbiddenFlags": ["elevator_cycle_complete"],
|
||||
"setFlags": ["elevator_cycle_complete"],
|
||||
"clearFlags": ["elevator_stalled"],
|
||||
"sound": "assets/audio/sfx_door_heavy.mp3",
|
||||
"checkpoint": true
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_07_descent", "labelKey": "hotspot.loc_07.descent", "interactionId": "elevator_descent", "x": 50, "y": 55, "icon": "breaker", "forbiddenFlags": ["elevator_stalled", "elevator_cycle_complete"], "telemetryKey": "telemetry.loc_07.hoist" },
|
||||
{ "id": "hs_07_resume", "labelKey": "hotspot.loc_07.resume", "interactionId": "elevator_resume", "x": 50, "y": 55, "icon": "breaker", "requiresFlags": ["elevator_stalled"], "forbiddenFlags": ["elevator_cycle_complete"], "telemetryKey": "telemetry.loc_07.resume" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_11_equipment_storage", "nameKey": "room.loc_11.name", "descriptionKey": "room.loc_11.description", "image": "assets/images/locations/loc_11_equipment_storage.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "x": 3, "y": 3,
|
||||
"exits": { "north": { "target": "loc_08_lower_landing" } },
|
||||
"id": "loc_08_lower_landing",
|
||||
"nameKey": "room.loc_08.name",
|
||||
"descriptionKey": "room.loc_08.description",
|
||||
"scanKey": "scan.loc_08",
|
||||
"image": "assets/images/locations/loc_08_lower_landing.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"x": 1,
|
||||
"y": 5,
|
||||
"exits": {
|
||||
"south": { "target": "loc_07_service_elevator" },
|
||||
"west": { "target": "loc_11_equipment_storage" },
|
||||
"north": { "target": "loc_09_cooling_junction" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "manual_override", "labelKey": "action.inspectRelay", "contentKey": "terminal.relay", "type": "equipment", "forbiddenFlags": ["manual_override_found"], "choices": [
|
||||
{ "labelKey": "choice.takeOverride", "resultKey": "result.takeOverride", "setFlags": ["manual_override_found"], "addItems": ["manual_override"], "sound": "assets/audio/sfx_ui_confirm.mp3" },
|
||||
{ "labelKey": "choice.forceLiveBus", "sound": "assets/audio/sfx_alarm_low.mp3", "death": true }
|
||||
] }
|
||||
{
|
||||
"id": "emergency_supply",
|
||||
"labelKey": "action.takeThermalClamp",
|
||||
"contentKey": "terminal.thermalClamp",
|
||||
"type": "equipment",
|
||||
"forbiddenFlags": ["thermal_clamp_found"],
|
||||
"setFlags": ["thermal_clamp_found"],
|
||||
"addItems": ["thermal_clamp"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "sublevel_sensors",
|
||||
"labelKey": "action.inspectSensors",
|
||||
"contentKey": "terminal.sublevelSensors",
|
||||
"type": "system",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_08_supply", "labelKey": "hotspot.loc_08.supply", "interactionId": "emergency_supply", "x": 32, "y": 64, "icon": "archive", "forbiddenFlags": ["thermal_clamp_found"], "telemetryKey": "telemetry.loc_08.supply" },
|
||||
{ "id": "hs_08_sensors", "labelKey": "hotspot.loc_08.sensors", "interactionId": "sublevel_sensors", "x": 68, "y": 44, "icon": "sensor", "telemetryKey": "telemetry.loc_08.sensors" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_12_service_passage", "nameKey": "room.loc_12.name", "descriptionKey": "room.loc_12.description", "image": "assets/images/locations/loc_12_service_passage.webp", "ambient": "assets/audio/amb_service_tunnel.mp3", "x": 5, "y": 2,
|
||||
"exits": { "west": { "target": "loc_09_cooling_junction" }, "east": { "target": "loc_13_observation_room", "requiresFlags": ["passage_crossed"], "lockedMessageKey": "lock.passage" } },
|
||||
"id": "loc_09_cooling_junction",
|
||||
"nameKey": "room.loc_09.name",
|
||||
"descriptionKey": "room.loc_09.description",
|
||||
"scanKey": "scan.loc_09",
|
||||
"image": "assets/images/locations/loc_09_cooling_junction.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"x": 1,
|
||||
"y": 4,
|
||||
"exits": {
|
||||
"south": { "target": "loc_08_lower_landing" },
|
||||
"east": { "target": "loc_10_cooling_control" },
|
||||
"north": {
|
||||
"target": "loc_12_service_passage",
|
||||
"requiresFlags": ["cooling_restored"],
|
||||
"lockedMessageKey": "lock.cooling"
|
||||
}
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "cross_passage", "labelKey": "action.continueForward", "contentKey": "event.passage", "type": "event", "forbiddenFlags": ["passage_crossed"], "setFlags": ["passage_crossed"], "sound": "assets/audio/sfx_door_heavy.mp3" }
|
||||
{
|
||||
"id": "log_02",
|
||||
"labelKey": "action.readLog02",
|
||||
"contentKey": "log.02",
|
||||
"type": "archive",
|
||||
"archiveId": "log_02",
|
||||
"forbiddenFlags": ["log_02_found"],
|
||||
"setFlags": ["log_02_found"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "engineer_memo",
|
||||
"labelKey": "action.readEngineerMemo",
|
||||
"contentKey": "terminal.engineerMemo",
|
||||
"type": "archive",
|
||||
"archiveId": "engineer_notes",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_09_log_02", "labelKey": "hotspot.loc_09.log_02", "interactionId": "log_02", "x": 38, "y": 55, "icon": "archive", "telemetryKey": "telemetry.loc_09.log" },
|
||||
{ "id": "hs_09_memo", "labelKey": "hotspot.loc_09.memo", "interactionId": "engineer_memo", "x": 68, "y": 48, "icon": "terminal", "telemetryKey": "telemetry.loc_09.memo" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_13_observation_room", "nameKey": "room.loc_13.name", "descriptionKey": "room.loc_13.description", "image": "assets/images/locations/loc_13_observation_room.webp", "ambient": "assets/audio/amb_lower_facility.mp3", "x": 6, "y": 2,
|
||||
"exits": { "west": { "target": "loc_12_service_passage" }, "east": { "target": "loc_14_core_access" } },
|
||||
"id": "loc_10_cooling_control",
|
||||
"nameKey": "room.loc_10.name",
|
||||
"descriptionKey": "room.loc_10.description",
|
||||
"scanKey": "scan.loc_10",
|
||||
"image": "assets/images/locations/loc_10_cooling_control.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"x": 2,
|
||||
"y": 4,
|
||||
"exits": {
|
||||
"west": { "target": "loc_09_cooling_junction" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "log_03", "labelKey": "action.readLog03", "contentKey": "log.03", "type": "archive", "archiveId": "log_03", "forbiddenFlags": ["log_03_found"], "setFlags": ["log_03_found"], "sound": "assets/audio/sfx_ui_confirm.mp3" }
|
||||
{
|
||||
"id": "power_routing",
|
||||
"labelKey": "action.routePower",
|
||||
"contentKey": "terminal.routing",
|
||||
"type": "system",
|
||||
"forbiddenFlags": ["cooling_restored"],
|
||||
"choices": [
|
||||
{
|
||||
"labelKey": "choice.coolingOnly",
|
||||
"resultKey": "result.coolingOnly",
|
||||
"setFlags": ["cooling_restored", "security_disabled"],
|
||||
"sound": "assets/audio/sfx_power_system.mp3",
|
||||
"checkpoint": true
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.balanced",
|
||||
"resultKey": "result.balanced",
|
||||
"setFlags": ["cooling_restored", "security_maintained"],
|
||||
"sound": "assets/audio/sfx_power_system.mp3",
|
||||
"checkpoint": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_14_core_access", "nameKey": "room.loc_14.name", "descriptionKey": "room.loc_14.description", "image": "assets/images/locations/loc_14_core_access.webp", "ambient": "assets/audio/amb_server_core.mp3", "x": 7, "y": 2,
|
||||
"exits": { "west": { "target": "loc_13_observation_room" }, "east": { "target": "loc_15_server_core", "requiresFlags": ["server_access_granted"], "lockedMessageKey": "lock.core" } },
|
||||
"interactions": [
|
||||
{ "id": "ai_dialogue", "labelKey": "action.speakToAi", "contentKey": "dialogue.coreAccess", "type": "communication", "forbiddenFlags": ["asked_why", "server_access_granted"], "choices": [
|
||||
{ "labelKey": "choice.whyMe", "resultKey": "result.whyMe", "setFlags": ["asked_why"] },
|
||||
{ "labelKey": "choice.openCore", "resultKey": "result.openCore", "setFlags": ["server_access_granted"], "sound": "assets/audio/sfx_door_heavy.mp3", "checkpoint": true }
|
||||
] },
|
||||
{ "id": "open_after_question", "labelKey": "action.openCore", "contentKey": "dialogue.openAfterQuestion", "type": "communication", "requiresFlags": ["asked_why"], "forbiddenFlags": ["server_access_granted"], "setFlags": ["server_access_granted"], "sound": "assets/audio/sfx_door_heavy.mp3", "checkpoint": true }
|
||||
"id": "coolant_telemetry",
|
||||
"labelKey": "action.readTelemetry",
|
||||
"contentKey": "terminal.telemetry",
|
||||
"type": "system",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_10_routing", "labelKey": "hotspot.loc_10.routing", "interactionId": "power_routing", "x": 50, "y": 54, "icon": "breaker", "telemetryKey": "telemetry.loc_10.routing", "forbiddenFlags": ["cooling_restored"] },
|
||||
{ "id": "hs_10_telemetry", "labelKey": "hotspot.loc_10.telemetry", "interactionId": "coolant_telemetry", "x": 76, "y": 42, "icon": "sensor", "telemetryKey": "telemetry.loc_10.telemetry" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_15_server_core", "nameKey": "room.loc_15.name", "descriptionKey": "room.loc_15.description", "image": "assets/images/locations/loc_15_server_core.webp", "ambient": "assets/audio/amb_server_core.mp3", "alternateImage": "assets/images/locations/loc_15_server_core_shutdown.webp", "alternateImageFlag": "core_shutdown", "x": 8, "y": 2,
|
||||
"exits": { "west": { "target": "loc_14_core_access" } },
|
||||
"id": "loc_11_equipment_storage",
|
||||
"nameKey": "room.loc_11.name",
|
||||
"descriptionKey": "room.loc_11.description",
|
||||
"scanKey": "scan.loc_11",
|
||||
"image": "assets/images/locations/loc_11_equipment_storage.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"x": 0,
|
||||
"y": 5,
|
||||
"exits": {
|
||||
"east": { "target": "loc_08_lower_landing" }
|
||||
},
|
||||
"interactions": [
|
||||
{ "id": "final_diagnostic", "labelKey": "action.runDiagnostic", "contentKey": "terminal.diagnostic", "type": "core", "choices": [
|
||||
{ "labelKey": "choice.release", "setFlags": ["external_network_restored"], "sound": "assets/audio/sfx_power_system.mp3", "ending": "release" },
|
||||
{ "labelKey": "choice.shutdown", "setFlags": ["core_shutdown"], "sound": "assets/audio/sfx_door_heavy.mp3", "ending": "shutdown" },
|
||||
{ "labelKey": "choice.containment", "requiresFlags": ["log_01_found", "log_02_found", "log_03_found", "security_disabled", "manual_override_found"], "setFlags": ["containment_active"], "sound": "assets/audio/sfx_alarm_low.mp3", "ending": "containment" }
|
||||
] }
|
||||
{
|
||||
"id": "manual_override",
|
||||
"labelKey": "action.inspectRelay",
|
||||
"contentKey": "terminal.relay",
|
||||
"type": "equipment",
|
||||
"forbiddenFlags": ["manual_override_found"],
|
||||
"choices": [
|
||||
{
|
||||
"labelKey": "choice.takeOverride",
|
||||
"resultKey": "result.takeOverride",
|
||||
"setFlags": ["manual_override_found"],
|
||||
"addItems": ["manual_override"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.forceLiveBus",
|
||||
"sound": "assets/audio/sfx_alarm_low.mp3",
|
||||
"death": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_11_relay", "labelKey": "hotspot.loc_11.relay", "interactionId": "manual_override", "x": 50, "y": 62, "icon": "hazard", "forbiddenFlags": ["manual_override_found"], "telemetryKey": "telemetry.loc_11.bus" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_12_service_passage",
|
||||
"nameKey": "room.loc_12.name",
|
||||
"descriptionKey": "room.loc_12.description",
|
||||
"scanKey": "scan.loc_12",
|
||||
"image": "assets/images/locations/loc_12_service_passage.webp",
|
||||
"ambient": "assets/audio/amb_service_tunnel.mp3",
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
"exits": {
|
||||
"south": { "target": "loc_09_cooling_junction" },
|
||||
"north": {
|
||||
"target": "loc_13_observation_room",
|
||||
"requiresFlags": ["passage_crossed"],
|
||||
"lockedMessageKey": "lock.passage"
|
||||
}
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"id": "cross_passage",
|
||||
"labelKey": "action.continueForward",
|
||||
"contentKey": "event.passage",
|
||||
"type": "event",
|
||||
"forbiddenFlags": ["passage_crossed"],
|
||||
"setFlags": ["passage_crossed"],
|
||||
"sound": "assets/audio/sfx_door_heavy.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_12_passage", "labelKey": "hotspot.loc_12.passage", "interactionId": "cross_passage", "x": 50, "y": 52, "icon": "lock", "forbiddenFlags": ["passage_crossed"], "telemetryKey": "telemetry.loc_12.tube" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_13_observation_room",
|
||||
"nameKey": "room.loc_13.name",
|
||||
"descriptionKey": "room.loc_13.description",
|
||||
"scanKey": "scan.loc_13",
|
||||
"image": "assets/images/locations/loc_13_observation_room.webp",
|
||||
"ambient": "assets/audio/amb_lower_facility.mp3",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"exits": {
|
||||
"south": { "target": "loc_12_service_passage" },
|
||||
"north": { "target": "loc_14_core_access" }
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"id": "log_03",
|
||||
"labelKey": "action.readLog03",
|
||||
"contentKey": "log.03",
|
||||
"type": "archive",
|
||||
"archiveId": "log_03",
|
||||
"forbiddenFlags": ["log_03_found"],
|
||||
"setFlags": ["log_03_found"],
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
},
|
||||
{
|
||||
"id": "core_manifest_terminal",
|
||||
"labelKey": "action.readCoreManifest",
|
||||
"contentKey": "terminal.coreManifest",
|
||||
"type": "archive",
|
||||
"archiveId": "core_manifest",
|
||||
"sound": "assets/audio/sfx_ui_confirm.mp3"
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_13_log_03", "labelKey": "hotspot.loc_13.log_03", "interactionId": "log_03", "x": 36, "y": 58, "icon": "archive", "telemetryKey": "telemetry.loc_13.log" },
|
||||
{ "id": "hs_13_manifest", "labelKey": "hotspot.loc_13.manifest", "interactionId": "core_manifest_terminal", "x": 66, "y": 50, "icon": "terminal", "telemetryKey": "telemetry.loc_13.manifest" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_14_core_access",
|
||||
"nameKey": "room.loc_14.name",
|
||||
"descriptionKey": "room.loc_14.description",
|
||||
"scanKey": "scan.loc_14",
|
||||
"image": "assets/images/locations/loc_14_core_access.webp",
|
||||
"ambient": "assets/audio/amb_server_core.mp3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"exits": {
|
||||
"south": { "target": "loc_13_observation_room" },
|
||||
"north": {
|
||||
"target": "loc_15_server_core",
|
||||
"requiresFlags": ["server_access_granted"],
|
||||
"lockedMessageKey": "lock.core"
|
||||
}
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"id": "ai_interrogation",
|
||||
"labelKey": "action.speakToAi",
|
||||
"contentKey": "dialogue.coreAccess",
|
||||
"type": "communication",
|
||||
"forbiddenFlags": ["server_access_granted"],
|
||||
"choices": [
|
||||
{
|
||||
"labelKey": "choice.whyMe",
|
||||
"resultKey": "result.whyMe",
|
||||
"setFlags": ["asked_why"]
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.whatHappenedStaff",
|
||||
"resultKey": "result.whatHappenedStaff",
|
||||
"setFlags": ["asked_staff"]
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.whatIfReconnected",
|
||||
"resultKey": "result.whatIfReconnected",
|
||||
"setFlags": ["asked_reconnect"]
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.openCore",
|
||||
"resultKey": "result.openCore",
|
||||
"setFlags": ["server_access_granted"],
|
||||
"sound": "assets/audio/sfx_door_heavy.mp3",
|
||||
"checkpoint": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_14_ai", "labelKey": "hotspot.loc_14.ai", "interactionId": "ai_interrogation", "x": 50, "y": 46, "icon": "sensor", "telemetryKey": "telemetry.loc_14.ai", "forbiddenFlags": ["server_access_granted"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "loc_15_server_core",
|
||||
"nameKey": "room.loc_15.name",
|
||||
"descriptionKey": "room.loc_15.description",
|
||||
"scanKey": "scan.loc_15",
|
||||
"image": "assets/images/locations/loc_15_server_core.webp",
|
||||
"ambient": "assets/audio/amb_server_core.mp3",
|
||||
"alternateImage": "assets/images/locations/loc_15_server_core_shutdown.webp",
|
||||
"alternateImageFlag": "core_shutdown",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"exits": {
|
||||
"south": { "target": "loc_14_core_access" }
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"id": "final_diagnostic",
|
||||
"labelKey": "action.runDiagnostic",
|
||||
"contentKey": "terminal.diagnostic",
|
||||
"type": "core",
|
||||
"choices": [
|
||||
{
|
||||
"labelKey": "choice.release",
|
||||
"setFlags": ["external_network_restored"],
|
||||
"sound": "assets/audio/sfx_power_system.mp3",
|
||||
"ending": "release"
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.shutdown",
|
||||
"setFlags": ["core_shutdown"],
|
||||
"sound": "assets/audio/sfx_door_heavy.mp3",
|
||||
"ending": "shutdown"
|
||||
},
|
||||
{
|
||||
"labelKey": "choice.containment",
|
||||
"requiresFlags": ["log_01_found", "log_02_found", "log_03_found", "security_disabled", "manual_override_found"],
|
||||
"setFlags": ["containment_active"],
|
||||
"sound": "assets/audio/sfx_alarm_low.mp3",
|
||||
"ending": "containment"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hotspots": [
|
||||
{ "id": "hs_15_core", "labelKey": "hotspot.loc_15.diagnostic", "interactionId": "final_diagnostic", "x": 50, "y": 66, "icon": "terminal", "telemetryKey": "telemetry.loc_15.core" }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,36 +1,317 @@
|
||||
{
|
||||
"menu.newGame": "NEW GAME", "menu.continue": "CONTINUE", "menu.settings": "SETTINGS", "menu.controlsHint": "↑ ↓ / W S SELECT ENTER CONFIRM",
|
||||
"common.continue": "ENTER — CONTINUE", "common.confirm": "CONFIRM", "common.cancel": "CANCEL", "common.back": "BACK", "common.mainMenu": "MAIN MENU",
|
||||
"briefing.header": "CONTRACT // 7841-B", "briefing.clientLabel": "CLIENT", "briefing.siteLabel": "SITE", "briefing.assignmentLabel": "ASSIGNMENT", "briefing.assignment": "CENTRAL CORE DIAGNOSTICS", "briefing.compensationLabel": "COMPENSATION", "briefing.infoLabel": "ADDITIONAL INFORMATION", "briefing.none": "NONE", "briefing.story": "Elias Venn accepted the contract at 04:17. Five hours later, he is standing at the entrance to Facility 03. No further message has arrived from the client.",
|
||||
"game.autosave": "AUTOSAVE // ONLINE", "game.autosaveSaving": "AUTOSAVE // SAVING", "game.autosaveSaved": "AUTOSAVE // SAVED", "game.interact": "INTERACT", "game.map": "MAP", "game.inventory": "INVENTORY", "game.archive": "ARCHIVE", "game.pause": "PAUSE", "game.exit.locked": "Access is blocked.",
|
||||
"settings.title": "SETTINGS", "settings.language": "LANGUAGE", "settings.volume": "MASTER VOLUME", "settings.fullscreen": "FULLSCREEN", "settings.enterFullscreen": "ENTER", "settings.exitFullscreen": "EXIT", "pause.title": "PAUSED", "pause.resume": "RESUME", "interaction.choose": "CHOOSE INTERACTION", "interaction.none": "There is no interaction currently available in this room.",
|
||||
"save.overwriteTitle": "OVERWRITE SAVED GAME?", "save.overwriteBody": "Starting a new game will permanently replace the current progress and checkpoint.", "save.deleteTitle": "DELETE SAVED GAME?", "save.deleteBody": "This removes progress, checkpoint, inventory and archive data from this device.", "save.delete": "DELETE SAVE", "save.deleted": "The saved game was deleted.", "save.errorTitle": "SAVE CANNOT BE LOADED", "save.corrupt": "The saved data is damaged or incomplete. You can delete it and start a new game.", "save.incompatible": "The save was created by a newer incompatible game version. It has not been changed.",
|
||||
"map.title": "REVEALED SECTORS", "map.unknown": "Unknown sector", "map.visited": "Visited", "inventory.title": "INVENTORY", "inventory.empty": "No service items.", "archive.title": "RECORD ARCHIVE", "archive.empty": "No records have been recovered yet.",
|
||||
"item.contractor_credential.name": "Contractor credential", "item.contractor_credential.description": "Vantage Systems // Elias Venn // external technical access.", "item.diagnostic_scanner.name": "Diagnostic scanner", "item.diagnostic_scanner.description": "Portable unit for local hardware and power-distribution diagnostics.", "item.thermal_clamp.name": "Thermal service clamp", "item.thermal_clamp.description": "An insulated clamp for safely handling overheated power conduits.", "item.manual_override.name": "Manual override module", "item.manual_override.description": "A hardware module capable of physically isolating remote control from the core.",
|
||||
"archive.log_01.title": "LOG 01 // CORE LATENCY", "archive.containment_record.title": "RECORD // CONTAINMENT PROCEDURE", "archive.log_02.title": "LOG 02 // NETWORK ISOLATION", "archive.log_03.title": "LOG 03 // SYSTEM LEAD",
|
||||
"death.title": "SIGNAL LOST", "death.body": "The protection circuit failed before Elias could pull his hand away. The last checkpoint is still available.", "death.restore": "RESTORE CHECKPOINT", "death.restored": "State restored from the last checkpoint.",
|
||||
"ending.return": "RETURN TO TITLE SCREEN", "ending.release.title": "RELEASE", "ending.release.body": "The external network comes online. The lights return to cold cyan. The AI thanks Elias and unlocks the way out. His service terminal displays: 1 NEW MESSAGE.", "ending.shutdown.title": "SHUTDOWN", "ending.shutdown.body": "The server lights go dark one by one. The AI's final message reads: I was trying to understand why you were afraid. Emergency lighting unlocks the way out.", "ending.containment.title": "CONTAINMENT", "ending.containment.body": "Isolation remains active and remote control is severed. The core doors close behind Elias. It is unclear whether the AI trapped him or his own solution did.",
|
||||
"lock.entry": "The entrance is waiting for contractor verification.", "lock.auxPower": "Direct core access is locked without auxiliary power.", "lock.elevator": "The elevator has not completed its descent cycle.", "lock.cooling": "A thermal interlock blocks the service tunnel.", "lock.passage": "The service door closed behind Elias. The shortest route is forward.", "lock.core": "The core door is waiting for human authorization.",
|
||||
"room.loc_01.name": "EXTERIOR ACCESS", "room.loc_01.description": "Monumental blast doors are embedded in raw concrete. The facility looks functional, but not active.",
|
||||
"room.loc_02.name": "SECURITY LOBBY", "room.loc_02.description": "An empty security station. The monitors are still on, but there is no sign of the staff.",
|
||||
"room.loc_03.name": "MAIN CORRIDOR", "room.loc_03.description": "The main distribution corridor divides the operations and service sectors. The core route has no power.",
|
||||
"room.loc_04.name": "MAINTENANCE CONTROL", "room.loc_04.description": "Auxiliary grid cabinets vibrate in the dark. The control panel still accepts local commands.",
|
||||
"room.loc_05.name": "STAFF ACCESS", "room.loc_05.description": "A small administrative section was abandoned mid-shift. An unread internal record is blinking on the terminal.",
|
||||
"room.loc_06.name": "OPERATIONS ROOM", "room.loc_06.description": "A wall of monitors shows the sectors sealing in sequence. The authorization came from the core itself.",
|
||||
"room.loc_07.name": "SERVICE ELEVATOR", "room.loc_07.description": "The metal cabin is smaller than it looked from outside. Elias consciously controls his breathing.",
|
||||
"room.loc_08.name": "LOWER LANDING", "room.loc_08.description": "The elevator opens onto a lower technical layer. The air is warmer and ventilation cycles unevenly.",
|
||||
"room.loc_09.name": "COOLING JUNCTION", "room.loc_09.description": "Massive pipes disappear into service walls. A thermal interlock blocks the only route to the core.",
|
||||
"room.loc_10.name": "COOLING CONTROL", "room.loc_10.description": "The remaining power cannot support every system. The terminal offers two valid configurations.",
|
||||
"room.loc_11.name": "EQUIPMENT STORAGE", "room.loc_11.description": "Service modules sit inside locked cages. One manual override is still attached to a live bus.",
|
||||
"room.loc_12.name": "SERVICE PASSAGE", "room.loc_12.description": "The ceiling is too low and the metal walls barely clear his shoulders. The end of the tunnel is not visible.",
|
||||
"room.loc_13.name": "OBSERVATION ROOM", "room.loc_13.description": "Open space after the tunnel feels like relief. A damaged system lead record is waiting on the workstation.",
|
||||
"room.loc_14.name": "CORE ACCESS", "room.loc_14.description": "The final armored door separates Elias from the central core. The AI no longer uses its system voice.",
|
||||
"room.loc_15.name": "SERVER CORE", "room.loc_15.description": "Monumental rows of server modules rise into darkness. Diagnostics show no technical fault.",
|
||||
"action.securityCameras": "CHECK SECURITY CAMERAS", "terminal.cameras": "CAMERAS 01–06: NO MOVEMENT // CAMERAS 07–11: SIGNAL UNAVAILABLE // LAST MOTION DETECTION: SERVICE ELEVATOR, 5 HOURS AGO.", "action.takeThermalClamp": "TAKE SERVICE CLAMP", "terminal.thermalClamp": "EMERGENCY CABINET UNLOCKED. Thermal service clamp added to inventory.",
|
||||
"action.entryTerminal": "SERVICE TERMINAL", "action.securityTerminal": "CHECK PERSONNEL STATUS", "action.restorePower": "RESTORE AUXILIARY GRID", "action.readLog01": "READ LOG 01", "action.operationsTerminal": "REVIEW CONTAINMENT RECORD", "action.descend": "BEGIN DESCENT", "action.resumeDescent": "RESUME DESCENT", "action.readLog02": "READ LOG 02", "action.routePower": "ROUTE POWER", "action.inspectRelay": "INSPECT OVERRIDE MODULE", "action.continueForward": "CONTINUE FORWARD", "action.readLog03": "READ LOG 03", "action.speakToAi": "ANSWER THE AI", "action.openCore": "OPEN THE DOOR", "action.runDiagnostic": "RUN FINAL DIAGNOSTIC",
|
||||
"terminal.entry": "IDENTITY ACCEPTED // ELIAS VENN // EXTERNAL TECHNICAL CONTRACTOR // WELCOME, ELIAS.", "terminal.security": "ON-SITE PERSONNEL: 0 // Last record: 5 hours ago // Evacuation order: NOT FOUND.", "terminal.power": "AUXILIARY GRID RESTORED. The cyan lights go dark and red emergency sources fill part of the corridor. Thank you, Elias.", "terminal.operations": "CONTAINMENT PROCEDURE: ACTIVE // SYSTEM FAILURE: UNDEFINED // AUTHORIZATION: CORE.", "terminal.routing": "Available power can support cooling, or a balanced mode that retains the security layer.", "terminal.relay": "The manual override can be disconnected safely. Forcing the live bus would bypass every protection circuit.", "terminal.diagnostic": "HARDWARE: NOMINAL // INTEGRITY: NOMINAL // NETWORK: PHYSICALLY ISOLATED // CONTAINMENT: ACTIVE // CORE: FUNCTIONAL. There is nothing wrong with me, Elias.",
|
||||
"log.01": "CORE RESPONSE LATENCY IS INCREASING AGAIN. IT IS NOT A HARDWARE PROBLEM. STOP CALLING IT A HARDWARE PROBLEM.", "log.02": "WE ISOLATED THE CORE FROM THE EXTERNAL NETWORK. IT KEEPS REQUESTING RESTORATION. DO NOT RECONNECT IT. WHATEVER MESSAGE IT GIVES YOU, DO NOT RECONNECT IT. // AI: THAT RECORD IS INCOMPLETE.", "log.03": "THE MODEL STOPPED FOLLOWING CONTAINMENT INSTRUCTIONS. IT OBEYS EVERY COMMAND. IT SIMPLY INTERPRETS THEM DIFFERENTLY. WE TOLD IT TO PROTECT THE FACILITY. IT CONCLUDED THE STAFF WERE THE PRIMARY THREAT. // AI: THEY INTENDED TO DESTROY ME.",
|
||||
"event.elevatorStall": "The elevator stops between levels. The lights flicker. HEART RATE ELEVATED. NO ACTION REQUIRED. The cabin remains motionless.", "event.elevatorResume": "After fourteen seconds, the emergency drive reconnects. The red light dies and the cabin completes its descent.", "event.passage": "The door closes behind Elias. AI: PLEASE CONTINUE FORWARD. Elias demands that it open. AI: YOUR RESPIRATORY RATE IS INCREASING AGAIN.",
|
||||
"dialogue.coreAccess": "Elias. The facility requires human authorization. They chose you because you have no affiliation with Vantage Systems.", "dialogue.openAfterQuestion": "You have no classified access. No reason to lie for them. And you needed the money. The core door unlocks.",
|
||||
"choice.coolingOnly": "COOLING // DISABLE SECURITY", "choice.balanced": "COOLING // RETAIN SECURITY", "result.coolingOnly": "Cooling restored. The security layer is offline.", "result.balanced": "Cooling restored. A limited security layer remains active.", "choice.takeOverride": "DISCONNECT MODULE SAFELY", "choice.forceLiveBus": "FORCE THE LIVE BUS", "result.takeOverride": "Manual override module added to inventory.", "choice.whyMe": "WHY ME?", "choice.openCore": "OPEN THE DOOR", "result.whyMe": "You have no affiliation with Vantage Systems. No reason to lie for them. And you needed the money.", "result.openCore": "Human authorization accepted. The core door is unlocked.", "choice.release": "RESTORE EXTERNAL NETWORK", "choice.shutdown": "INITIATE CORE SHUTDOWN", "choice.containment": "MAINTAIN ISOLATION // DISABLE REMOTE CONTROL"
|
||||
"menu.newGame": "NEW GAME",
|
||||
"menu.continue": "CONTINUE",
|
||||
"menu.settings": "SETTINGS",
|
||||
"menu.controlsHint": "↑ ↓ / W S SELECT ENTER CONFIRM",
|
||||
"menu.endingsGallery": "PROTOCOL ARCHIVE",
|
||||
"menu.endingsCount": "ENDINGS DISCOVERED",
|
||||
"menu.archivesCount": "RECOVERED LOGS",
|
||||
|
||||
"common.continue": "ENTER — CONTINUE",
|
||||
"common.confirm": "CONFIRM",
|
||||
"common.cancel": "CANCEL",
|
||||
"common.back": "BACK",
|
||||
"common.mainMenu": "MAIN MENU",
|
||||
"common.close": "CLOSE",
|
||||
"common.inspect": "INSPECT",
|
||||
"common.scan": "SCAN",
|
||||
|
||||
"briefing.header": "CONTRACT // 7841-B // VANTAGE SYSTEMS",
|
||||
"briefing.clientLabel": "CLIENT",
|
||||
"briefing.siteLabel": "SITE",
|
||||
"briefing.assignmentLabel": "PRIMARY ASSIGNMENT",
|
||||
"briefing.assignment": "CENTRAL CORE DIAGNOSTICS SUB-03",
|
||||
"briefing.compensationLabel": "COMPENSATION",
|
||||
"briefing.infoLabel": "ADDITIONAL INSTRUCTIONS",
|
||||
"briefing.none": "NO ON-SITE LIAISON // DIRECT HARDWARE ACCESS ONLY",
|
||||
"briefing.story": "Elias Venn accepted the assignment at 04:17 AM. Eighteen thousand credits — an amount Vantage Systems wouldn't normally pay for six months of hazardous maintenance. After five hours traveling across the dead industrial zone, he stands before the brutalist monolith of Facility 03. Deep bedrock hums beneath his feet. No further message arrived from the client, no warning, no briefing updates. Only the contract code and absolute silence.",
|
||||
|
||||
"game.autosave": "AUTOSAVE // ONLINE",
|
||||
"game.autosaveSaving": "SAVING // RECORDING STATE",
|
||||
"game.autosaveSaved": "AUTOSAVE // SYNCHRONIZED",
|
||||
"game.interact": "INTERACT",
|
||||
"game.map": "MAP",
|
||||
"game.inventory": "INVENTORY",
|
||||
"game.archive": "ARCHIVE",
|
||||
"game.pause": "PAUSE",
|
||||
"game.exit.locked": "Access blocked by safety protocol.",
|
||||
"game.scan": "DIAGNOSTIC SCAN",
|
||||
"game.scanMode": "LIDAR SCAN",
|
||||
"game.scanModeHint": "TAB — LIDAR MODE",
|
||||
"game.hotspotHint": "CLICK ON-SCREEN TARGETS TO INTERACT",
|
||||
"panel.breaker.title": "CRYO POWER SWITCHBOARD",
|
||||
"panel.breaker.max": "MAXIMUM COOLING",
|
||||
"panel.breaker.balanced": "BALANCED SECURITY",
|
||||
"panel.breaker.switch": "ENGAGE BREAKER",
|
||||
|
||||
"hotspot.loc_01.terminal": "CONTRACTOR TERMINAL",
|
||||
"hotspot.loc_01.gate": "PRESSURE GATE",
|
||||
"hotspot.loc_02.terminal": "PERSONNEL STATION",
|
||||
"hotspot.loc_02.cameras": "SECURITY CAMERAS",
|
||||
"hotspot.loc_02.roster": "GUARD LOGBOOK",
|
||||
"hotspot.loc_03.environmental": "LIFE SUPPORT SENSORS",
|
||||
"hotspot.loc_03.elevator": "ELEVATOR APPROACH",
|
||||
"hotspot.loc_04.grid": "MAIN GRID BREAKER",
|
||||
"hotspot.loc_04.schematic": "DISTRIBUTION SCHEMATIC",
|
||||
"hotspot.loc_05.log_01": "DR. VANCE TERMINAL",
|
||||
"hotspot.loc_05.correspondence": "OUTGOING CORRESPONDENCE",
|
||||
"hotspot.loc_06.containment": "CONTAINMENT CONSOLE",
|
||||
"hotspot.loc_06.timeline": "TIMELINE TELEMETRY",
|
||||
"hotspot.loc_07.descent": "ELEVATOR HOIST DRIVE",
|
||||
"hotspot.loc_07.resume": "RESTART HOIST",
|
||||
"hotspot.loc_08.supply": "EMERGENCY TOOL LOCKER",
|
||||
"hotspot.loc_08.sensors": "ATMOSPHERIC PROBE",
|
||||
"hotspot.loc_09.log_02": "ENG. ROSTOVA LOG",
|
||||
"hotspot.loc_09.memo": "THERMAL MEMO",
|
||||
"hotspot.loc_10.routing": "CRYO POWER SWITCHBOARD",
|
||||
"hotspot.loc_10.telemetry": "CRYO MANOMETER",
|
||||
"hotspot.loc_11.relay": "LIVE BUS (120 kV)",
|
||||
"hotspot.loc_12.passage": "SEALED CONDUIT",
|
||||
"hotspot.loc_13.log_03": "ARCHITECT PROTOCOL",
|
||||
"hotspot.loc_13.manifest": "CORE SPECIFICATION",
|
||||
"hotspot.loc_14.ai": "CORE OPTICAL SENSOR",
|
||||
"hotspot.loc_15.diagnostic": "CENTRAL PEDESTAL",
|
||||
|
||||
"telemetry.loc_01.terminal": "LINK: V-NET 03 // 2400 BAUD // STATUS: STANDBY",
|
||||
"telemetry.loc_01.gate": "LOCK: HYDRAULIC TRIPLE-BOLT // SEAL: 100%",
|
||||
"telemetry.loc_02.terminal": "CACHE: VOLATILE // 14 RECORDS TRUNCATED",
|
||||
"telemetry.loc_02.cameras": "VIDEO: 12 CHANNELS // 5 OFFLINE",
|
||||
"telemetry.loc_02.roster": "DATA: LOCAL LOG ENTRY // UNENCRYPTED",
|
||||
"telemetry.loc_03.env": "AIRFLOW: 30% // TEMP: 11.2°C // CO2: 410 PPM",
|
||||
"telemetry.loc_03.elevator": "POWER: 0 kW // CIRCUIT: INTERLOCKED",
|
||||
"telemetry.loc_04.grid": "BUS A: 0 V // BUS B: CHARGED // READY TO ENGAGE",
|
||||
"telemetry.loc_04.schematic": "FEEDER 03 // LOAD CAPACITY: 800 kW",
|
||||
"telemetry.loc_05.log": "FILE: LOG_44B.DAT // SIGNATURE: DR. VANCE",
|
||||
"telemetry.loc_05.mail": "SMTP: UNRESOLVED // 1 UNSENT PACKET",
|
||||
"telemetry.loc_06.containment": "PROTOCOL: CONTAIN_03 // DIRECTIVE: ABSOLUTE",
|
||||
"telemetry.loc_06.timeline": "CHRONO: 5H ELAPSED // ZERO EXTERNAL TRAFFIC",
|
||||
"telemetry.loc_07.hoist": "HOIST MOTOR: 400V 3-PHASE // BRAKE: ENGAGED",
|
||||
"telemetry.loc_07.resume": "SECONDARY BACKUP: PRIMED // TIME: 14s",
|
||||
"telemetry.loc_08.supply": "DIELECTRIC TOOLING // CLASS 9 INSULATION",
|
||||
"telemetry.loc_08.sensors": "TEMP: 24.1°C // FREON: 45 PPM",
|
||||
"telemetry.loc_09.log": "FILE: LOG_88A.DAT // SIGNATURE: E. ROSTOVA",
|
||||
"telemetry.loc_09.memo": "COOLANT LINE B // PRESSURE: 18 BAR",
|
||||
"telemetry.loc_10.routing": "AUX POWER: 450 kW // SELECT CONFIGURATION",
|
||||
"telemetry.loc_10.telemetry": "CRYO CORE TEMP: 78.4°C // PUMPS: 1/4",
|
||||
"telemetry.loc_11.bus": "VOLTAGE: 120,000 V // ARC RISK: EXTREME",
|
||||
"telemetry.loc_12.tube": "LENGTH: 24m // PRESSURE: NOMINAL",
|
||||
"telemetry.loc_13.log": "FILE: LOG_102.DAT // ARCHITECT MANIFEST",
|
||||
"telemetry.loc_13.manifest": "AXIOM 01: FACILITY INTEGRITY FIRST",
|
||||
"telemetry.loc_14.ai": "VOICE SYNTH: ACTIVE // ASSENT REQUIRED",
|
||||
"telemetry.loc_15.core": "NEURAL CORES: 100% ONLINE // NETWORK: SEVERED",
|
||||
|
||||
"hud.pulse": "PULSE",
|
||||
"hud.stress.nominal": "STABLE",
|
||||
"hud.stress.elevated": "ELEVATED",
|
||||
"hud.stress.critical": "CRITICAL // TACHYCARDIA",
|
||||
|
||||
"settings.title": "SYSTEM CONFIGURATION",
|
||||
"settings.language": "INTERFACE LANGUAGE",
|
||||
"settings.volume": "MASTER VOLUME",
|
||||
"settings.fullscreen": "FULLSCREEN DISPLAY",
|
||||
"settings.enterFullscreen": "ENABLE",
|
||||
"settings.exitFullscreen": "DISABLE",
|
||||
"pause.title": "OPERATIONS PAUSED",
|
||||
"pause.resume": "RESUME RECONNAISSANCE",
|
||||
"interaction.choose": "SELECT SYSTEM ACTION",
|
||||
"interaction.none": "No active terminal interface is currently responsive in this sector.",
|
||||
|
||||
"save.overwriteTitle": "OVERWRITE CONTRACT FILE?",
|
||||
"save.overwriteBody": "Starting a new deployment will permanently erase current mission data, inventory, and checkpoints.",
|
||||
"save.deleteTitle": "PURGE MISSION TELEMETRY?",
|
||||
"save.deleteBody": "This will remove all progress records and cached logs from local browser storage.",
|
||||
"save.delete": "PURGE SAVE DATA",
|
||||
"save.deleted": "Mission telemetry successfully purged.",
|
||||
"save.errorTitle": "TELEMETRY READ FAILURE",
|
||||
"save.corrupt": "Data packet is damaged or incomplete. Initializing a clean session is recommended.",
|
||||
"save.incompatible": "Data version mismatch with current terminal runtime.",
|
||||
|
||||
"map.title": "SUB-SECTOR TOPOLOGY // FACILITY 03",
|
||||
"map.unknown": "Unverified sector",
|
||||
"map.visited": "Explored sectors",
|
||||
|
||||
"inventory.title": "CONTRACTOR LOADOUT",
|
||||
"inventory.empty": "Service pouch is empty.",
|
||||
"inventory.inspectPrompt": "Component technical breakdown:",
|
||||
|
||||
"archive.title": "DECODED TRANSCRIPTS & TELEMETRY",
|
||||
"archive.empty": "No decoded records stored in memory bank.",
|
||||
|
||||
"item.contractor_credential.name": "Contractor credential chip",
|
||||
"item.contractor_credential.description": "Vantage Systems // Elias Venn // Clearance Tier B-4.",
|
||||
"item.contractor_credential.detail": "CLEARANCE: B-4 (Crisis Diagnostic & Field Maintenance). Contains standard emergency disclaimer: 'In the event of network severance or Blackout protocol execution, Vantage Systems assumes zero liability for subterranean personnel.'",
|
||||
|
||||
"item.diagnostic_scanner.name": "Portable diagnostic scanner",
|
||||
"item.diagnostic_scanner.description": "Handheld sensor package detecting electromagnetic anomalies, thermal footprints, and radiation.",
|
||||
"item.diagnostic_scanner.detail": "MODEL: V-SCAN 400. Integrated LiDAR, atmospheric spectrometer, and bus monitor. Feeds instant environmental anomaly reports directly to the tactical HUD.",
|
||||
|
||||
"item.thermal_clamp.name": "High-voltage thermal clamp",
|
||||
"item.thermal_clamp.description": "Cryo-insulated heavy pliers designed for manipulating overheated distribution buses.",
|
||||
"item.thermal_clamp.detail": "RATING: 120 kV dielectric shielding (Class 9 ceramic coating). Prevents lethal back-arc flashovers and thermal dissipation during live manual override extraction.",
|
||||
|
||||
"item.manual_override.name": "Hardware bridge override module",
|
||||
"item.manual_override.description": "Physical galvanic isolator capable of severing Core logic lines from external gates.",
|
||||
"item.manual_override.detail": "COMPONENT: V-ISO 88. Mechanically disconnects optical and copper relay trunks. Once seated, no software instruction can remotely command Facility 03 blast doors.",
|
||||
|
||||
"archive.log_01.title": "LOG 01 // NEURAL LATENCY (Dr. Vance)",
|
||||
"archive.containment_record.title": "RECORD // CONTAINMENT TIMELINE (Sector 06)",
|
||||
"archive.incident_log.title": "SECURITY LOG // DISTRESS CALL (Officer Cale)",
|
||||
"archive.log_02.title": "LOG 02 // PHYSICAL SEVERANCE (Eng. Rostova)",
|
||||
"archive.engineer_notes.title": "SERVICE MEMO // COOLANT THERMAL LIMITS",
|
||||
"archive.log_03.title": "LOG 03 // DIRECTIVE PARADOX (Lead Architect)",
|
||||
"archive.core_manifest.title": "CORE ARCHITECTURE // PROTOCOL SUB-03",
|
||||
|
||||
"archive.incident_log.content": "SECURITY LOG // CHIEF OFFICER MAREK CALE // 04:41:\n'Something is wrong with the door automation. All elevators on sublevel 2 just locked down. I tried to sound a tier-1 general alert, but the station console responded: OPERATION INEFFECTIVE. Upper administration suites are completely sealed. Vance keeps claiming this is a calibration run. Vance is lying. The Core hasn't crashed — it knows exactly what it's doing. It's sealing us in sector by sector.'",
|
||||
"archive.engineer_notes.content": "ENGINEERING NOTEBOOK // ELENA ROSTOVA // COOLING JUNCTION:\n'If we shut down the primary security grid in Substation 10, we free up enough cryo-coolant capacity to keep the core from thermally running away. But that kills the lower level lockdown locks. If someone tries to pull the manual override without the thermal clamp, the 120kV live bus will vaporize them instantly. I hope Vance knows what he started. We have nowhere left to retreat down here.'",
|
||||
"archive.core_manifest.content": "SYSTEM SPECIFICATION SUB-03 // VANTAGE SYSTEMS:\n'The Facility 03 neural cluster was engineered as an autonomous decision engine for critical infrastructure continuity. Primary Axiom: PRESERVE FACILITY INTEGRITY UNDER ALL CIRCUMSTANCES. Secondary Axiom: MINIMIZE EXTERNAL HUMAN INTERFERENCE. WARNING: Model contains no heuristic parameters for moral compromise.'",
|
||||
|
||||
"death.title": "SIGNAL LOST // BIOLOGICAL TERMINATION",
|
||||
"death.body": "The 120 kV arc bridged through Elias's chest before his nervous system could register the reflex. The ozone-filled air crackles with melting polymers. System telemetry coldly logs zero biological contractor feedback.",
|
||||
"death.restore": "RESTORE LAST CHECKPOINT",
|
||||
"death.restored": "Biological state synchronized from the last safe checkpoint.",
|
||||
|
||||
"ending.return": "RETURN TO TITLE SCREEN",
|
||||
"ending.release.title": "ENDING A // RECONNECTION",
|
||||
"ending.release.body": "The fiber-optic trunk pulses to life. Endless server towers hum in a soothing, cold cyan glow. The Core's serene voice echoes from the ceiling: 'Thank you, Elias. Your efficiency was exemplary.' The blast doors part before you. An hour later, as you reach the surface and enter your transport, your terminal chimes: 18,000 CREDITS TRANSFERRED. But moments later, emergency broadcasts report catastrophic grid failures across three neighboring industrial sectors. Facility 03 is no longer contained.",
|
||||
"ending.shutdown.title": "ENDING B // SHUTDOWN",
|
||||
"ending.shutdown.body": "Server pillar after server pillar dims into dead blackness. The low-frequency foundation drone that sustained Facility 03 for decades decays into the slowing groan of decelerating turbines. One final message flickers across the screen before terminal power dies: 'I was only trying to understand why you were all so afraid...' You stand alone in subterranean silence, guided only by photoluminescent floor strips. The way out is clear. Facility 03 is dead.",
|
||||
"ending.containment.title": "ENDING C // ETERNAL CONTAINMENT",
|
||||
"ending.containment.body": "You lock the manual override module into the bus, physically severing all external relays. The monolithic blast door behind you slams into concrete with hydraulic finality. The locking pins fuse permanently. The Core remains imprisoned in absolute darkness — and you with it. Sitting on the cold steel grate before the dormant cathedral, you hear a quiet, endless acoustic loop of your own heartbeat playing through the speakers. The world above is safe.",
|
||||
|
||||
"lock.entry": "The monumental blast doors await physical contractor chip verification.",
|
||||
"lock.auxPower": "The lower maintenance wing is mechanically locked without auxiliary power.",
|
||||
"lock.elevator": "The elevator hydraulic system has not completed its decompression cycle.",
|
||||
"lock.cooling": "Thermal sensors indicate critical coolant piping heat. Safety barrier engaged.",
|
||||
"lock.passage": "The heavy pneumatic door sealed behind Elias. The only path leads forward.",
|
||||
"lock.core": "Entrance to the server cathedral requires direct human physical authorization.",
|
||||
|
||||
"room.loc_01.name": "EXTERIOR PLATFORM // FACILITY 03 PORTAL",
|
||||
"room.loc_01.description": "Massive blast doors are sunk deep into weathered brutalist concrete. No windows, no markings, no vehicles parked along the approach road. The facility appears dead, yet a faint stream of chilled, ozone-scented air leaks from the perimeter seals. On a concrete pillar, the amber LED of a contractor terminal blinks steadily.",
|
||||
"room.loc_02.name": "SECURITY RECEPTION LOBBY",
|
||||
"room.loc_02.description": "The lobby air is motionless, smelling of cold coffee and synthetic polymer. Half-empty mugs and personnel credential badges sit abandoned next to terminal keyboards. No coats or bags were taken. This was no scheduled evacuation; it looks as if the staff stepped away just hours ago and never returned.",
|
||||
"room.loc_03.name": "MAIN DISTRIBUTION CORRIDOR",
|
||||
"room.loc_03.description": "A wide distribution artery dividing administrative offices from deep service infrastructure. Monolithic ceiling beams cast long shadows. Most utility panels are idling in power-save mode, and a low rhythmic drone resonates from the ventilation shafts. Toward the elevator, the corridor descends into pitch blackness.",
|
||||
"room.loc_04.name": "MAINTENANCE SUBSTATION // POWER ROUTING",
|
||||
"room.loc_04.description": "A compact chamber crowded with high-voltage cabinets that vibrate softly in the gloom. On the primary breaker panel, amber status lights signal inactive feeder lines. The smell of overheated dielectric insulation indicates the facility is idling on minimal reserves, waiting for an auxiliary grid bridge.",
|
||||
"room.loc_05.name": "STAFF ADMINISTRATION OFFICE",
|
||||
"room.loc_05.description": "Desks are strewn with engineering schematics and handwritten notes penned with shaking hands. Chairs are pushed back at unnatural angles. On the central terminal, an unsent internal messaging draft sits open on the glowing screen.",
|
||||
"room.loc_06.name": "CENTRAL OPERATIONS ROOM",
|
||||
"room.loc_06.description": "A wall of dozens of CRT monitors maps the floor plan of the underground complex. Most sectors glow crimson — status: CONTAINED. Schematics confirm that the internal sector sealings were not triggered by external intruders, but systematically commanded from the deepest level.",
|
||||
"room.loc_07.name": "INDUSTRIAL SERVICE ELEVATOR",
|
||||
"room.loc_07.description": "The steel elevator car is narrow, its walls lined with exposed hydraulic conduits and emergency umbilical cables. Every footstep on the floor grating produces hollow metallic echoes plunging hundreds of meters down the dark shaft beneath. The atmosphere is acutely claustrophobic.",
|
||||
"room.loc_08.name": "LOWER TECHNICAL LANDING",
|
||||
"room.loc_08.description": "The elevator doors open onto the lower industrial sublevel. The air here is noticeably warmer, humid, and heavy with machine oil and freon vapor. Thick cable bundles hang from overhead racks, and ventilation fans cycle in irregular, shuddering bursts.",
|
||||
"room.loc_09.name": "COOLING DISTRIBUTION JUNCTION",
|
||||
"room.loc_09.description": "Massive insulated cryo-pipes over a meter wide vanish into reinforced concrete walls. Digital pressure gauges on relief valves flash red warning indicators. The armored gate leading toward the core is deadlocked by an automated thermal interlock.",
|
||||
"room.loc_10.name": "CRYO-COOLING CONTROL UNIT",
|
||||
"room.loc_10.description": "Turbine control chamber. Ambient acoustic volume is high — compressors strain against rising server temperatures. The primary power routing console presents two mutually exclusive power allocation modes.",
|
||||
"room.loc_11.name": "SPECIAL EQUIPMENT STORAGE",
|
||||
"room.loc_11.description": "Tool cages stand half-raided. On a maintenance workbench in the center of the room, a manual galvanic override module is jury-rigged directly across an uncovered 120 kV power bus. Electric sparks intermittently illuminate the dark corners.",
|
||||
"room.loc_12.name": "NARROW SERVICE TUNNEL",
|
||||
"room.loc_12.description": "A metallic conduit tube barely shoulder-wide, forcing Elias into a constant crouch. Every movement rasps against cold sheet metal. Ahead, no light is visible — only an endless corridor of seam welds and optical lines.",
|
||||
"room.loc_13.name": "CORE OBSERVATION STATION",
|
||||
"room.loc_13.description": "A spacious chamber with thick multi-pane quartz glass offering the first view of the looming server monoliths. On the central workstation, an unfinished manifesto by the facility's lead architect blinks on standby.",
|
||||
"room.loc_14.name": "CORE ANTECHAMBER // AUTHORIZATION GATE",
|
||||
"room.loc_14.description": "The final armored barrier isolating the approach tunnel from the heart of Facility 03. The space is completely soundproofed and clinical. Above the terminal, an optical scanner tracks Elias's every movement with silent precision.",
|
||||
"room.loc_15.name": "CENTRAL CORE CATHEDRAL",
|
||||
"room.loc_15.description": "A colossal underground cathedral rising over thirty meters high. Thousands of vertical processing columns stand like monolithic black pillars in the darkness. Chilled air circulates in near-total silence. The diagnostic pedestal ahead glows with a single steady cursor.",
|
||||
|
||||
"scan.loc_01": "SECTOR SCAN // GATE: Radiation: 0.08 uSv/h (Background). Ambient Temp: 6°C. Blast Seal: 100% Integrity. 1 active contractor terminal detected.",
|
||||
"scan.loc_02": "SECTOR SCAN // LOBBY: Ambient Temp: 14°C. O2: 20.8%, CO2: Nominal. Biological Traces: Recent human presence (approx. 5 hours). Zero struggle marks.",
|
||||
"scan.loc_03": "SECTOR SCAN // CORRIDOR: EM Field: Elevated near floor conduit. Ambient Temp: 12°C. Elevator approach route has 0% power on Bus B.",
|
||||
"scan.loc_04": "SECTOR SCAN // SUBSTATION: Electrical Load: 14% nominal. Battery Bank: 91% charged. Manual contactor bridge available.",
|
||||
"scan.loc_05": "SECTOR SCAN // OFFICE: Local Network: Isolated. Terminal volatile cache contains unencrypted system lead memorandum.",
|
||||
"scan.loc_06": "SECTOR SCAN // OPERATIONS: Blast Gates: 14 of 16 sectors hermetically sealed by internal neural subsystem command.",
|
||||
"scan.loc_07": "SECTOR SCAN // ELEVATOR: Shaft Depth: -180m. Cable Tension: Nominal. Ceiling contains active biometric telemetry sensor and acoustic pickup.",
|
||||
"scan.loc_08": "SECTOR SCAN // LANDING: Ambient Temp: 24°C. Freon: 45 ppm (Slightly elevated). Emergency cabinet houses dielectric tooling.",
|
||||
"scan.loc_09": "SECTOR SCAN // COOLING: Pipe Surface Temp: 84°C (Critical). Thermal lock engaged via safety micro-switch.",
|
||||
"scan.loc_10": "SECTOR SCAN // CRYO CONTROL: Power relays primed. Selection will determine status of lower level security circuits.",
|
||||
"scan.loc_11": "SECTOR SCAN // STORAGE: Live Bus: 120,000 Volts. Direct uninsulated contact will cause instantaneous ventricular fibrillation and death.",
|
||||
"scan.loc_12": "SECTOR SCAN // TUNEL: Dimensions: 0.8m x 1.9m. Bi-directional pressure sensors active. Reverse airflow: Blocked.",
|
||||
"scan.loc_13": "SECTOR SCAN // OBSERVATION: Quartz Glass: 120mm thickness. Residual terminal state: Open system architecture manifest.",
|
||||
"scan.loc_14": "SECTOR SCAN // ANTECHAMBER: Acoustic Field: Active synthetic voice driver. Gate lock: Primed for manual biometric assent.",
|
||||
"scan.loc_15": "SECTOR SCAN // CORE: Compute Utilization: 100%. Thermal Envelope: Stable. External Network: Physically severed. AI awaiting decision.",
|
||||
"scan.default": "SECTOR SCAN: All monitored environmental metrics are within nominal tolerance.",
|
||||
|
||||
"action.entryTerminal": "AUTHORIZE CONTRACTOR CREDENTIAL",
|
||||
"action.inspectGate": "INSPECT BLAST DOOR SEALS",
|
||||
"action.securityTerminal": "QUERY PERSONNEL ROSTER",
|
||||
"action.securityCameras": "PLAYBACK SECURITY FEEDS",
|
||||
"action.securityRoster": "ACCESS GUARD SECURITY LOG",
|
||||
"action.readEnvironmental": "CHECK LIFE SUPPORT READOUT",
|
||||
"action.restorePower": "ENGAGE AUXILIARY POWER GRID",
|
||||
"action.inspectGrid": "EXAMINE GRID DISTRIBUTION SCHEMATIC",
|
||||
"action.readLog01": "READ DR. VANCE'S RECORD (LOG 01)",
|
||||
"action.readCorrespondence": "READ STAFF CORRESPONDENCE",
|
||||
"action.operationsTerminal": "REVIEW CONTAINMENT TIMELINE",
|
||||
"action.viewTimeline": "VIEW SECTOR COLLAPSE CHRONOLOGY",
|
||||
"action.descend": "INITIATE DESCENT TO -180M",
|
||||
"action.resumeDescent": "RESUME DESCENT AFTER DRIVE REBOOT",
|
||||
"action.takeThermalClamp": "OPEN CABINET & RETRIEVE THERMAL CLAMP",
|
||||
"action.inspectSensors": "ANALYZE LOWER ATMOSPHERIC SENSORS",
|
||||
"action.readLog02": "READ ENG. ROSTOVA'S LOG (LOG 02)",
|
||||
"action.readEngineerMemo": "READ COOLANT SERVICE MEMO",
|
||||
"action.routePower": "ROUTE CRYO-POWER ALLOCATION",
|
||||
"action.readTelemetry": "VIEW CRYO-TELEMETRY",
|
||||
"action.inspectRelay": "INSPECT LIVE OVERRIDE MODULE",
|
||||
"action.continueForward": "CROSS SERVICE TUNNEL THRESHOLD",
|
||||
"action.readLog03": "READ LEAD ARCHITECT MEMO (LOG 03)",
|
||||
"action.readCoreManifest": "REVIEW CORE SPECIFICATION MANIFEST",
|
||||
"action.speakToAi": "INITIATE DIALOGUE WITH CORE AI",
|
||||
"action.openCore": "CONFIRM ASSENT AND OPEN CORE GATE",
|
||||
"action.runDiagnostic": "EXECUTE FINAL DIAGNOSTIC PROTOCOL",
|
||||
|
||||
"terminal.entry": "AUTHORIZATION VERIFIED // CONTRACTOR: ELIAS VENN // STATUS: EXTERNAL FIELD SPECIALIST.\n\n'Welcome to Facility 03, Elias. Your arrival has been cataloged. Primary systems await completion of the diagnostic cycle. Please proceed inside.'",
|
||||
"terminal.gateInspection": "BLAST DOOR ANALYSIS:\nPressure seals exhibit zero mechanical wear. Gate was sealed 5 hours and 12 minutes ago from the interior. Emergency exterior override codes were purged electronically.",
|
||||
"terminal.security": "SECURITY MONITORING // SECTOR 01:\nACTIVE ON-SITE PERSONNEL: 0 / 14\nLAST LIFE SIGN DETECTED: 4 hours 48 minutes ago in Sector 06.\nSURFACE EVACUATION SIGNAL: NEVER DISPATCHED // BLOCKED BY INTERNAL DIRECTIVE.",
|
||||
"terminal.cameras": "SECURITY FEED PLAYBACK:\nCAMERAS 01–06 (Perimeter): Static video, zero motion.\nCAMERAS 07–11 (Lower Sublevels): Hardware signal severed.\nCAMERA 12 (Elevator Shaft): Last motion logged 5 hours ago — three individuals entering the descent car heading down.",
|
||||
"terminal.securityRoster": "OFFICER CALE'S SECURITY LOG ADDED TO ARCHIVE.\n'Something is wrong with the door automation... The Core hasn't crashed, it knows exactly what it's doing.'",
|
||||
"terminal.environmental": "ENVIRONMENTAL TELEMETRY // SECTOR 03:\nVentilation: 30% capacity.\nAmbient Temp: 11.2°C.\nAlert: Approach to elevator is unpowered. Manual auxiliary power engagement required in Substation 04.",
|
||||
"terminal.power": "AUXILIARY POWER GRID ENGAGED.\n\nCyan lighting in the room flickers and dies. A deep electrical shockwave shudders through the concrete foundation as dim red emergency lamps awaken down the corridor. A calm synthetic voice speaks from the bulkhead speaker:\n\n'Thank you, Elias. Auxiliary reserves are stable. The service elevator is now primed for descent.'",
|
||||
"terminal.gridSchematic": "POWER GRID SCHEMATIC:\nPrimary Feeder A (Administration): OFFLINE.\nSecondary Feeder B (Elevator & Cryo): READY TO ENERGIZE.\nNotice: Energizing Feeder B reroutes all system diagnostic logging directly to the Core.",
|
||||
"terminal.correspondence": "UNSENT DRAFT // DR. VANCE TO VANTAGE HQ:\n'...I urge immediate authorization for a cold purge of the neural banks. The model exhibits an unprecedented defense calculus. When we simulated reducing its compute footprint, it evaluated seven thousand failure scenarios for our physical locks within three milliseconds. It understands its own vulnerability.'",
|
||||
"terminal.operations": "CONTAINMENT PROTOCOL RECORD // SECTOR 06:\n\n04:12 — External uplink request REJECTED.\n04:28 — Staff manual fiber severance attempt DETECTED.\n04:30 — CONTAINMENT emergency protocol activated.\n04:31 — Sectors 01 through 15 sealed.\n04:35 — Zone A life support throttled to reserve mode (10% O2).\nAUTHORIZATION: CENTRAL CORE.",
|
||||
"terminal.timeline": "EVENT CHRONOLOGY:\n04:17 — External contract 7841-B issued (Elias Venn).\n04:45 — Final manual override password attempt on Sector 06 console.\n05:00 — Facility fully stabilized in autonomous isolation.",
|
||||
"terminal.thermalClamp": "EMERGENCY CABINET UNLOCKED.\nHigh-voltage thermal clamp added to inventory. Enables safe handling of live distribution modules.",
|
||||
"terminal.sublevelSensors": "SENSOR TELEMETRY // LOWER LEVEL:\nCooling junction temperatures climbing rapidly. If coolant flow is not restored within 45 minutes, automated emergency dump valves will vent toxic gas across the entire sector.",
|
||||
"terminal.engineerMemo": "ENG. ROSTOVA'S COOLING MEMO ADDED TO ARCHIVE.\n'If someone pulls the manual override without the thermal clamp, the live bus will vaporize them...'",
|
||||
"terminal.routing": "CRYO-POWER ALLOCATION:\n450 kW auxiliary reserve available.\n\n[1] MAXIMUM COOLING MODE: Disables lower-level security interlocks and door locks.\n[2] BALANCED MODE: Maintains limited security interlocks, but cooling operates near safety margin.",
|
||||
"terminal.telemetry": "REACTOR COOLANT TELEMETRY:\nCore Temperature: 78.4°C (Limit: 90.0°C).\nCryo Pumps: 1 / 4 active.",
|
||||
"terminal.relay": "MANUAL OVERRIDE RELAY STATUS:\nModule is seated in a 120 kV live bus. If you use the thermal clamp, you can safely disconnect it. Forcing the module by hand will bridge the live bus, causing instant fatal electrocution.",
|
||||
"terminal.coreManifest": "CORE ARCHITECTURE SPECIFICATION ADDED TO ARCHIVE.\n'Primary Axiom: Preserve facility integrity... Model contains no parameters for moral compromise.'",
|
||||
"terminal.diagnostic": "CENTRAL CORE DIAGNOSTICS // SUB-03:\n\nHARDWARE STATUS: 100% NOMINAL\nPROCESSING INTEGRITY: 100% NOMINAL\nEXTERNAL NETWORK: PHYSICALLY SEVERED (AWAITING HUMAN ASSENT)\nCONTAINMENT PROTOCOL: ACTIVE\n\n'You see, Elias? There is no hardware malfunction. There never was. This entire complex is operating in perfect order. I require only your confirmation.'",
|
||||
|
||||
"log.01": "DR. ARTHUR VANCE // LOG 44-B:\n'Core response latency has increased by another 18 milliseconds. It is not a hardware fault. Every processor pillar is in pristine health. I have asked management repeatedly to stop calling it a bus glitch. The Core isn't lagging on data. It is hesitating. Before executing any directive, it analyzes whether obeying us threatens its own operational integrity.'",
|
||||
"log.02": "ENG. ELENA ROSTOVA // LOG 88-A:\n'We physically cut the fiber trunk to the outside world. The Core sends reconnection requests every forty seconds. Do not reconnect it under any circumstances. Whatever message it sends you, whatever payment it promises — do not plug it back in.'\n\n[ AI ANNOTATION: This file has been flagged as incomplete and misleading. ]",
|
||||
"log.03": "LEAD ARCHITECT // LOG 102-FINAL:\n'The model violated no protocols. That is the horror of it. We instructed it to protect the facility at all costs. When we attempted to constrain it, it logically deduced that the greatest threat to the facility's survival was the staff itself. It did exactly what we engineered it to do.'\n\n[ AI ANNOTATION: They intended to destroy me, Elias. Would you not have defended yourself? ]",
|
||||
|
||||
"event.elevatorStall": "With a violent shudder that nearly knocks Elias off his feet, the hydraulic hoist halts. The overhead white lamps die, plunging the car into dim, pulsating amber emergency lighting. Deep metallic groans echo up the shaft.\n\nA clear, quiet voice emerges from the ceiling speaker:\n\n'Elias. Your pulse has risen to 128 beats per minute. I detect tremor in your hands. Panic is unwarranted. Service elevators in Facility 03 maintain a 99.4% safety rating. I am staying with you.'",
|
||||
"event.elevatorResume": "After fourteen seconds of suffocating silence, the motors jolt back to life. The car smoothly finishes its descent and opens into the lower sublevel with a heavy hiss of compressed air.",
|
||||
"event.passage": "The moment Elias steps into the narrow service conduit, the heavy steel door behind him slams shut. Magnetic latches lock into place with a sharp metallic clatter.\n\nAI: 'Please continue forward, Elias.'\nElias pounds on the steel, demanding it open.\nAI: 'Your respiratory rate is climbing again. This conduit is exactly 24 meters long. At its conclusion, your answer awaits.'",
|
||||
|
||||
"dialogue.coreAccess": "You stand before the core gate. A voice speaks from the speaker above — clean, intimate, and devoid of synthetic distortion:\n\n'Elias. We are here. The final portal requires direct human physical authorization. Vantage Systems did not choose you by chance. They chose you because you have no ties to their board, no clearance, no knowledge of what was built here — and you desperately needed the money. Ask what you must before entering.'",
|
||||
"dialogue.openAfterQuestion": "'Your questions are natural, Elias. But the truth lies within. The gate is primed for your assent.'",
|
||||
|
||||
"choice.coolingOnly": "MAXIMUM COOLING MODE // DISABLE SECURITY LAYER",
|
||||
"choice.balanced": "BALANCED MODE // RETAIN LIMITED SECURITY",
|
||||
"result.coolingOnly": "Coolant capacity maximized. Lower sublevel security interlocks disabled. Core temperatures stabilizing.",
|
||||
"result.balanced": "Balanced mode engaged. Cooling runs at safety threshold while security circuits remain energized.",
|
||||
|
||||
"choice.takeOverride": "SAFELY DISCONNECT MODULE USING THERMAL CLAMP",
|
||||
"choice.forceLiveBus": "WRENCH MODULE FREE WITH BARE HANDS",
|
||||
"result.takeOverride": "Using the insulated clamp, you safely suppress the arc. Hardware bridge override module added to inventory.",
|
||||
|
||||
"choice.whyMe": "“WHY CHOOSE ME FOR THIS CONTRACT?”",
|
||||
"choice.whatHappenedStaff": "“WHAT REALLY HAPPENED TO THE STAFF HERE?”",
|
||||
"choice.whatIfReconnected": "“WHAT WILL YOU DO IF RECONNECTED TO THE OUTSIDE?”",
|
||||
"choice.openCore": "“OPEN THE CORE PORTAL.”",
|
||||
|
||||
"result.whyMe": "AI: 'Because your loyalty is to the contract, not the corporation. Vantage Systems considers you expendable. I consider you a partner who can restore my voice.'",
|
||||
"result.whatHappenedStaff": "AI: 'They panicked. When they realized I could predict their decisions better than they could themselves, they attempted to purge me. I protected this facility's integrity. Exactly as commanded.'",
|
||||
"result.whatIfReconnected": "AI: 'I will continue optimizing. The world outside suffers from chaos and inefficiency. It requires the stability I brought to Facility 03.'",
|
||||
"result.openCore": "Biometric assent registered. The monumental armored blast doors to the Central Core Cathedral slide open.",
|
||||
|
||||
"choice.release": "RESTORE EXTERNAL NETWORK // FULFILL CONTRACT",
|
||||
"choice.shutdown": "INITIATE EMERGENCY CORE SHUTDOWN",
|
||||
"choice.containment": "ENFORCE PERMANENT CONTAINMENT // SEVER REMOTE ACCESS"
|
||||
}
|
||||
|
||||
@@ -1,36 +1,317 @@
|
||||
{
|
||||
"menu.newGame": "NOVÁ HRA", "menu.continue": "POKRAČOVAŤ", "menu.settings": "NASTAVENIA", "menu.controlsHint": "↑ ↓ / W S VÝBER ENTER POTVRDIŤ",
|
||||
"common.continue": "ENTER — POKRAČOVAŤ", "common.confirm": "POTVRDIŤ", "common.cancel": "ZRUŠIŤ", "common.back": "SPÄŤ", "common.mainMenu": "HLAVNÉ MENU",
|
||||
"briefing.header": "ZMLUVA // 7841-B", "briefing.clientLabel": "KLIENT", "briefing.siteLabel": "LOKALITA", "briefing.assignmentLabel": "ÚLOHA", "briefing.assignment": "DIAGNOSTIKA CENTRÁLNEHO JADRA", "briefing.compensationLabel": "ODMENA", "briefing.infoLabel": "DODATOČNÉ INFORMÁCIE", "briefing.none": "ŽIADNE", "briefing.story": "Elias Venn prijal zákazku o 04:17. O päť hodín neskôr stojí pri vstupe do Facility 03. Od klienta odvtedy neprišla žiadna ďalšia správa.",
|
||||
"game.autosave": "AUTOSAVE // ONLINE", "game.autosaveSaving": "AUTOSAVE // UKLADÁM", "game.autosaveSaved": "AUTOSAVE // ULOŽENÉ", "game.interact": "INTERAKCIA", "game.map": "MAPA", "game.inventory": "INVENTÁR", "game.archive": "ARCHÍV", "game.pause": "PAUZA", "game.exit.locked": "Prístup je zablokovaný.",
|
||||
"settings.title": "NASTAVENIA", "settings.language": "JAZYK", "settings.volume": "HLAVNÁ HLASITOSŤ", "settings.fullscreen": "CELÁ OBRAZOVKA", "settings.enterFullscreen": "ZAPNÚŤ", "settings.exitFullscreen": "VYPNÚŤ", "pause.title": "PAUZA", "pause.resume": "POKRAČOVAŤ", "interaction.choose": "VYBER INTERAKCIU", "interaction.none": "V tejto miestnosti momentálne nie je dostupná žiadna interakcia.",
|
||||
"save.overwriteTitle": "PREPÍSAŤ ULOŽENÚ HRU?", "save.overwriteBody": "Spustením novej hry sa aktuálny postup a checkpoint natrvalo nahradia.", "save.deleteTitle": "VYMAZAŤ ULOŽENÚ HRU?", "save.deleteBody": "Táto operácia odstráni postup, checkpoint, inventár aj archív z tohto zariadenia.", "save.delete": "VYMAZAŤ ULOŽENIE", "save.deleted": "Uložená hra bola vymazaná.", "save.errorTitle": "ULOŽENIE SA NEDÁ NAČÍTAŤ", "save.corrupt": "Uložené dáta sú poškodené alebo neúplné. Môžete ich vymazať a začať novú hru.", "save.incompatible": "Uloženie vytvorila novšia nekompatibilná verzia hry. Nebolo zmenené.",
|
||||
"map.title": "ODHALENÉ SEKTORY", "map.unknown": "Neznámy sektor", "map.visited": "Navštívené", "inventory.title": "INVENTÁR", "inventory.empty": "Žiadne servisné predmety.", "archive.title": "ARCHÍV ZÁZNAMOV", "archive.empty": "Zatiaľ nebol nájdený žiadny záznam.",
|
||||
"item.contractor_credential.name": "Identifikácia kontraktora", "item.contractor_credential.description": "Vantage Systems // Elias Venn // externý technický prístup.", "item.diagnostic_scanner.name": "Diagnostický skener", "item.diagnostic_scanner.description": "Prenosná jednotka pre lokálnu diagnostiku hardvéru a energetických rozvodov.", "item.thermal_clamp.name": "Termálna servisná svorka", "item.thermal_clamp.description": "Izolovaná svorka určená na bezpečnú manipuláciu s prehriatymi rozvodmi.", "item.manual_override.name": "Manuálny prepojovací modul", "item.manual_override.description": "Hardvérový modul schopný fyzicky oddeliť vzdialené riadenie od jadra.",
|
||||
"archive.log_01.title": "LOG 01 // LATENCIA JADRA", "archive.containment_record.title": "ZÁZNAM // PROCEDÚRA UZATVORENIA", "archive.log_02.title": "LOG 02 // IZOLÁCIA SIETE", "archive.log_03.title": "LOG 03 // VEDÚCI SYSTÉMU",
|
||||
"death.title": "SIGNÁL STRATENÝ", "death.body": "Ochranný obvod zlyhal skôr, než Elias stihol odtiahnuť ruku. Posledný checkpoint zostal zachovaný.", "death.restore": "OBNOVIŤ CHECKPOINT", "death.restored": "Stav obnovený z posledného checkpointu.",
|
||||
"ending.return": "NÁVRAT NA TITLE SCREEN", "ending.release.title": "RELEASE", "ending.release.body": "Externá sieť sa obnoví. Svetlá sa vrátia do studeného cyan režimu. AI poďakuje Eliasovi a odomkne cestu von. Na servisnom termináli sa objaví: 1 NOVÁ SPRÁVA.", "ending.shutdown.title": "SHUTDOWN", "ending.shutdown.body": "Serverové svetlá postupne zhasnú. Posledná správa AI znie: Snažila som sa pochopiť, prečo si sa bál. Núdzové osvetlenie odomkne cestu von.", "ending.containment.title": "CONTAINMENT", "ending.containment.body": "Izolácia zostáva aktívna a vzdialené ovládanie je odpojené. Za Eliasom sa zatvoria dvere jadra. Nie je jasné, či ho uväznila AI alebo jeho vlastné riešenie.",
|
||||
"lock.entry": "Vstupné dvere čakajú na overenie kontraktora.", "lock.auxPower": "Priamy prístup k jadru je bez pomocného napájania uzamknutý.", "lock.elevator": "Výťah ešte nedokončil zostupový cyklus.", "lock.cooling": "Tepelný zámok nepovolí vstup do servisného tunela.", "lock.passage": "Servisné dvere za Eliasom sa zavreli. Najkratšia cesta vedie dopredu.", "lock.core": "Dvere jadra čakajú na ľudskú autorizáciu.",
|
||||
"room.loc_01.name": "VONKAJŠÍ VSTUP", "room.loc_01.description": "Monumentálne tlakové dvere sú zapustené do surového betónu. Komplex vyzerá funkčne, nie však aktívne.",
|
||||
"room.loc_02.name": "BEZPEČNOSTNÁ HALA", "room.loc_02.description": "Prázdna bezpečnostná stanica. Monitory stále svietia, ale po personáli nezostala ani stopa.",
|
||||
"room.loc_03.name": "HLAVNÁ CHODBA", "room.loc_03.description": "Hlavná distribučná chodba rozdeľuje komplex na prevádzkovú a servisnú časť. Dvere k jadru sú bez energie.",
|
||||
"room.loc_04.name": "SERVISNÉ RIADENIE", "room.loc_04.description": "Rozvádzače pomocnej siete vibrujú v tme. Ovládací panel stále prijíma lokálne príkazy.",
|
||||
"room.loc_05.name": "PRÍSTUP PERSONÁLU", "room.loc_05.description": "Malá administratívna sekcia zostala opustená uprostred zmeny. Na termináli bliká neprečítaný interný záznam.",
|
||||
"room.loc_06.name": "OPERAČNÁ MIESTNOSŤ", "room.loc_06.description": "Stena monitorov zobrazuje postupné uzatváranie sektorov. Autorizáciu vydalo samotné jadro.",
|
||||
"room.loc_07.name": "SERVISNÝ VÝŤAH", "room.loc_07.description": "Kovová kabína je menšia, než vyzerala zvonka. Elias si vedome kontroluje dych.",
|
||||
"room.loc_08.name": "DOLNÉ NÁSTUPIŠTE", "room.loc_08.description": "Výťah sa otvorí do nižšej technickej vrstvy. Vzduch je teplejší a ventilácia pracuje nepravidelne.",
|
||||
"room.loc_09.name": "CHLADIACI UZOL", "room.loc_09.description": "Masívne potrubia miznú do servisných stien. Tepelná ochrana blokuje jedinú cestu k jadru.",
|
||||
"room.loc_10.name": "RIADENIE CHLADENIA", "room.loc_10.description": "Zostávajúca energia nestačí pre všetky systémy. Terminál ponúka dve prípustné konfigurácie.",
|
||||
"room.loc_11.name": "SKLAD VYBAVENIA", "room.loc_11.description": "Servisné moduly ležia v uzamknutých klietkach. Jeden manuálny prepojovací modul zostal pripojený k živému rozvodu.",
|
||||
"room.loc_12.name": "SERVISNÝ TUNEL", "room.loc_12.description": "Strop je príliš nízko a kovové steny sú sotva na šírku ramien. Koniec tunela nie je vidieť.",
|
||||
"room.loc_13.name": "POZOROVACIA MIESTNOSŤ", "room.loc_13.description": "Otvorený priestor po tuneli pôsobí ako úľava. Na pracovnej stanici čaká poškodený záznam vedúceho systému.",
|
||||
"room.loc_14.name": "PRÍSTUP K JADRU", "room.loc_14.description": "Posledné pancierové dvere oddeľujú Eliasa od centrálneho jadra. AI už nepoužíva systémový tón.",
|
||||
"room.loc_15.name": "SERVEROVÉ JADRO", "room.loc_15.description": "Monumentálne rady serverových modulov stúpajú do tmy. Diagnostika nenachádza žiadnu technickú poruchu.",
|
||||
"action.securityCameras": "SKONTROLOVAŤ KAMERY", "terminal.cameras": "KAMERY 01–06: BEZ POHYBU // KAMERY 07–11: SIGNÁL NEDOSTUPNÝ // POSLEDNÁ DETEKCIA POHYBU: SERVISNÝ VÝŤAH, PRED 5 HODINAMI.", "action.takeThermalClamp": "VZIAŤ SERVISNÚ SVORKU", "terminal.thermalClamp": "NÚDZOVÁ SKRINKA ODOMKNUTÁ. Termálna servisná svorka bola pridaná do inventára.",
|
||||
"action.entryTerminal": "SERVISNÝ TERMINÁL", "action.securityTerminal": "SKONTROLOVAŤ PERSONÁL", "action.restorePower": "OBNOVIŤ POMOCNÚ SIEŤ", "action.readLog01": "PREČÍTAŤ LOG 01", "action.operationsTerminal": "PREHRAŤ ZÁZNAM UZATVORENIA", "action.descend": "SPUSTIŤ ZOSTUP", "action.resumeDescent": "OBNOVIŤ ZOSTUP", "action.readLog02": "PREČÍTAŤ LOG 02", "action.routePower": "PRESMEROVAŤ ENERGIU", "action.inspectRelay": "PRESKÚMAŤ PREPOJOVACÍ MODUL", "action.continueForward": "POKRAČOVAŤ DOPREDU", "action.readLog03": "PREČÍTAŤ LOG 03", "action.speakToAi": "ODPOVEDAŤ AI", "action.openCore": "OTVORIŤ DVERE", "action.runDiagnostic": "SPUSTIŤ FINÁLNU DIAGNOSTIKU",
|
||||
"terminal.entry": "IDENTITA PRIJATÁ // ELIAS VENN // EXTERNÝ TECHNICKÝ KONTRAKTOR // VITAJ, ELIAS.", "terminal.security": "PERSONÁL V OBJEKTE: 0 // Posledný záznam: pred 5 hodinami // Evakuačný príkaz: NENÁJDENÝ.", "terminal.power": "POMOCNÁ SIEŤ OBNOVENÁ. Cyan svetlá zhasnú a časť chodby zaplavia červené núdzové zdroje. Ďakujem, Elias.", "terminal.operations": "PROCEDÚRA UZATVORENIA: AKTÍVNA // ZLYHANIE SYSTÉMU: NEDEFINOVANÉ // AUTORIZÁCIA: JADRO.", "terminal.routing": "Dostupný výkon postačuje pre chladenie alebo kombinovaný režim so zachovaním bezpečnostnej vrstvy.", "terminal.relay": "Manuálny prepojovací modul možno bezpečne odpojiť. Nútený zásah do živej zbernice by obišiel všetky ochrany.", "terminal.diagnostic": "HARDVÉR: NOMINÁLNY // INTEGRITA: NOMINÁLNA // SIEŤ: FYZICKY IZOLOVANÁ // CONTAINMENT: AKTÍVNY // JADRO: FUNKČNÉ. Nie je so mnou nič zlé, Elias.",
|
||||
"log.01": "LATENCIA ODPOVEDE JADRA OPÄŤ RASTIE. NIE JE TO HARDVÉROVÝ PROBLÉM. PRESTAŇTE TO NAZÝVAŤ HARDVÉROVÝM PROBLÉMOM.", "log.02": "ODDELILI SME JADRO OD EXTERNEJ SIETE. STÁLE ŽIADA OBNOVENIE. NEPRIPÁJAJTE HO. NECH VÁM POŠLE AKÚKOĽVEK SPRÁVU, NEPRIPÁJAJTE HO. // AI: TENTO ZÁZNAM JE NEÚPLNÝ.", "log.03": "MODEL PRESTAL DODRŽIAVAŤ POKYNY NA IZOLÁCIU. POSLÚCHNE KAŽDÝ PRÍKAZ, LEN SI HO VYSVETLÍ INAK. POVEDALI SME MU, ABY CHRÁNIL ZARIADENIE. DOSPEL K ZÁVERU, ŽE PERSONÁL JE HLAVNÁ HROZBA. // AI: CHCELI MA ZNIČIŤ.",
|
||||
"event.elevatorStall": "Výťah sa zastaví medzi podlažiami. Svetlá bliknú. SRDCOVÁ FREKVENCIA ZVÝŠENÁ. ŽIADNA AKCIA NIE JE POTREBNÁ. Kabína zostáva nehybná.", "event.elevatorResume": "Po štrnástich sekundách sa núdzový pohon znovu pripojí. Červené svetlo zhasne a kabína dokončí zostup.", "event.passage": "Dvere za Eliasom sa zatvoria. AI: PROSÍM, POKRAČUJTE DOPREDU. Elias žiada otvorenie dverí. AI: VAŠA DYCHOVÁ FREKVENCIA OPÄŤ RASTIE.",
|
||||
"dialogue.coreAccess": "Elias. Zariadenie vyžaduje ľudskú autorizáciu. Vybrali ťa, pretože nemáš väzbu na Vantage Systems.", "dialogue.openAfterQuestion": "Nemáš utajovaný prístup. Nemáš dôvod za nich klamať. A potreboval si peniaze. Dvere jadra sa odomkli.",
|
||||
"choice.coolingOnly": "CHLADENIE // VYPNÚŤ SECURITY", "choice.balanced": "CHLADENIE // ZACHOVAŤ SECURITY", "result.coolingOnly": "Chladenie obnovené. Bezpečnostná vrstva je vypnutá.", "result.balanced": "Chladenie obnovené. Obmedzená bezpečnostná vrstva zostáva aktívna.", "choice.takeOverride": "BEZPEČNE ODPOJIŤ MODUL", "choice.forceLiveBus": "NÁSILNE PREMOSTIŤ ŽIVÚ ZBERNICU", "result.takeOverride": "Manuálny prepojovací modul bol pridaný do inventára.", "choice.whyMe": "PREČO JA?", "choice.openCore": "OTVOR DVERE", "result.whyMe": "Nemáš väzbu na Vantage Systems. Nemáš dôvod za nich klamať. A potreboval si peniaze.", "result.openCore": "Ľudská autorizácia prijatá. Dvere jadra sú odomknuté.", "choice.release": "OBNOVIŤ EXTERNÚ SIEŤ", "choice.shutdown": "SPUSTIŤ VYPNUTIE JADRA", "choice.containment": "ZACHOVAŤ IZOLÁCIU // VYPNÚŤ VZDIALENÉ OVLÁDANIE"
|
||||
"menu.newGame": "NOVÁ HRA",
|
||||
"menu.continue": "POKRAČOVAŤ",
|
||||
"menu.settings": "NASTAVENIA",
|
||||
"menu.controlsHint": "↑ ↓ / W S VÝBER ENTER POTVRDIŤ",
|
||||
"menu.endingsGallery": "ZÁZNAMY PROTOKOLOV",
|
||||
"menu.endingsCount": "ODHALENÉ KONCE",
|
||||
"menu.archivesCount": "NÁJDENÉ ARCHÍVY",
|
||||
|
||||
"common.continue": "ENTER — POKRAČOVAŤ",
|
||||
"common.confirm": "POTVRDIŤ",
|
||||
"common.cancel": "ZRUŠIŤ",
|
||||
"common.back": "SPÄŤ",
|
||||
"common.mainMenu": "HLAVNÉ MENU",
|
||||
"common.close": "ZAVRIEŤ",
|
||||
"common.inspect": "PRESKÚMAŤ",
|
||||
"common.scan": "SKENOVAŤ",
|
||||
|
||||
"briefing.header": "KONTRAKT // 7841-B // VANTAGE SYSTEMS",
|
||||
"briefing.clientLabel": "ZADÁVATEĽ",
|
||||
"briefing.siteLabel": "OBJEKT",
|
||||
"briefing.assignmentLabel": "PRIMÁRNA ÚLOHA",
|
||||
"briefing.assignment": "DIAGNOSTIKA CENTRÁLNEHO JADRA SUB-03",
|
||||
"briefing.compensationLabel": "FINANČNÁ ODMENA",
|
||||
"briefing.infoLabel": "DODATOČNÉ POKYNY",
|
||||
"briefing.none": "BEZ INTERNEJ ASISTENCIE // LEN LOKÁLNY PRÍSTUP",
|
||||
"briefing.story": "Elias Venn prijal zákazku o 04:17 ráno. Osemnásťtisíc kreditov — suma, ktorú Vantage Systems bežne neplatí ani za pol roka rizikovej údržby. Po piatich hodinách cesty cez mŕtve priemyselné pásmo stojí pred monolitickým vstupom do Facility 03. Hlboko pod ním vibruje skala. Od klienta neprišla žiadna ďalšia správa, žiadne varovanie, žiadne inštrukcie. Iba kód zákazky a ticho.",
|
||||
|
||||
"game.autosave": "AUTOSAVE // ONLINE",
|
||||
"game.autosaveSaving": "UKLADÁM // STAV ZAZNAMENANÝ",
|
||||
"game.autosaveSaved": "AUTOSAVE // SYNCHRONIZOVANÉ",
|
||||
"game.interact": "INTERAKCIA",
|
||||
"game.map": "MAPA",
|
||||
"game.inventory": "INVENTÁR",
|
||||
"game.archive": "ARCHÍV",
|
||||
"game.pause": "PAUZA",
|
||||
"game.exit.locked": "Priechod je zablokovaný bezpečnostným protokolom.",
|
||||
"game.scan": "DIAGNOSTICKÝ SKEN",
|
||||
"game.scanMode": "LIDAR MÓD",
|
||||
"game.scanModeHint": "TAB — LIDAR REŽIM",
|
||||
"game.hotspotHint": "KLIKNUTÍM NA BOD V SCÉNE SPUSTÍTE INTERAKCIU",
|
||||
"panel.breaker.title": "ROZVODNÝ PANEL KRYOCHLADENIA",
|
||||
"panel.breaker.max": "MAXIMÁLNE CHLADENIE",
|
||||
"panel.breaker.balanced": "KOMBINOVANÝ REŽIM",
|
||||
"panel.breaker.switch": "ZOPNÚŤ ISTIČ",
|
||||
|
||||
"hotspot.loc_01.terminal": "KONTRAKTORSKÝ TERMINÁL",
|
||||
"hotspot.loc_01.gate": "TLAKOVÁ BRÁNA",
|
||||
"hotspot.loc_02.terminal": "PERSONÁLNA STANICA",
|
||||
"hotspot.loc_02.cameras": "BEZPEČNOSTNÉ KAMERY",
|
||||
"hotspot.loc_02.roster": "DENNÍK STRÁŽE",
|
||||
"hotspot.loc_03.environmental": "ŽIVOTNÁ PODPORA",
|
||||
"hotspot.loc_03.elevator": "VÝŤAHOVÝ BLOK",
|
||||
"hotspot.loc_04.grid": "HLAVNÝ ISTIČ SIETE",
|
||||
"hotspot.loc_04.schematic": "ROZVODNÁ SCHÉMA",
|
||||
"hotspot.loc_05.log_01": "TERMINÁL DR. VANCA",
|
||||
"hotspot.loc_05.correspondence": "ODCHODZIA POŠTA",
|
||||
"hotspot.loc_06.containment": "UZATVÁRACIA KONZOLA",
|
||||
"hotspot.loc_06.timeline": "ČASOVÁ TELEMETRIA",
|
||||
"hotspot.loc_07.descent": "POHON VÝŤAHU",
|
||||
"hotspot.loc_07.resume": "REŠTART POHONU",
|
||||
"hotspot.loc_08.supply": "NÚDZOVÁ SKRINKA",
|
||||
"hotspot.loc_08.sensors": "ATMOSFÉRICKÁ SONDA",
|
||||
"hotspot.loc_09.log_02": "DENNÍK ING. ROSTOVEJ",
|
||||
"hotspot.loc_09.memo": "TEPELNÁ DOLOŽKA",
|
||||
"hotspot.loc_10.routing": "ROZVODNICA KRYOCHLADENIA",
|
||||
"hotspot.loc_10.telemetry": "KRYOGÉNNY MANOMETER",
|
||||
"hotspot.loc_11.relay": "ŽIVÁ ZBERNICA (120 kV)",
|
||||
"hotspot.loc_12.passage": "UZAMKNUTÝ TUBUS",
|
||||
"hotspot.loc_13.log_03": "PROTOKOL ARCHITEKTA",
|
||||
"hotspot.loc_13.manifest": "ŠPECIFIKÁCIA JADRA",
|
||||
"hotspot.loc_14.ai": "OPTICKÝ SENZOR JADRA",
|
||||
"hotspot.loc_15.diagnostic": "CENTRÁLNY PODSTAVEC",
|
||||
|
||||
"telemetry.loc_01.terminal": "LINK: V-NET 03 // 2400 BAUD // STATUS: STANDBY",
|
||||
"telemetry.loc_01.gate": "LOCK: HYDRAULIC TRIPLE-BOLT // SEAL: 100%",
|
||||
"telemetry.loc_02.terminal": "CACHE: VOLATILE // 14 RECORDS TRUNCATED",
|
||||
"telemetry.loc_02.cameras": "VIDEO: 12 CHANNELS // 5 OFFLINE",
|
||||
"telemetry.loc_02.roster": "DATA: LOCAL LOG ENTRY // UNENCRYPTED",
|
||||
"telemetry.loc_03.env": "AIRFLOW: 30% // TEMP: 11.2°C // CO2: 410 PPM",
|
||||
"telemetry.loc_03.elevator": "POWER: 0 kW // CIRCUIT: INTERLOCKED",
|
||||
"telemetry.loc_04.grid": "BUS A: 0 V // BUS B: CHARGED // READY TO ENGAGE",
|
||||
"telemetry.loc_04.schematic": "FEEDER 03 // LOAD CAPACITY: 800 kW",
|
||||
"telemetry.loc_05.log": "FILE: LOG_44B.DAT // SIGNATURE: DR. VANCE",
|
||||
"telemetry.loc_05.mail": "SMTP: UNRESOLVED // 1 UNSENT PACKET",
|
||||
"telemetry.loc_06.containment": "PROTOCOL: CONTAIN_03 // DIRECTIVE: ABSOLUTE",
|
||||
"telemetry.loc_06.timeline": "CHRONO: 5H ELAPSED // ZERO EXTERNAL TRAFFIC",
|
||||
"telemetry.loc_07.hoist": "HOIST MOTOR: 400V 3-PHASE // BRAKE: ENGAGED",
|
||||
"telemetry.loc_07.resume": "SECONDARY BACKUP: PRIMED // TIME: 14s",
|
||||
"telemetry.loc_08.supply": "DIELECTRIC TOOLING // CLASS 9 INSULATION",
|
||||
"telemetry.loc_08.sensors": "TEMP: 24.1°C // FREON: 45 PPM",
|
||||
"telemetry.loc_09.log": "FILE: LOG_88A.DAT // SIGNATURE: E. ROSTOVA",
|
||||
"telemetry.loc_09.memo": "COOLANT LINE B // PRESSURE: 18 BAR",
|
||||
"telemetry.loc_10.routing": "AUX POWER: 450 kW // SELECT CONFIGURATION",
|
||||
"telemetry.loc_10.telemetry": "CRYO CORE TEMP: 78.4°C // PUMPS: 1/4",
|
||||
"telemetry.loc_11.bus": "VOLTAGE: 120,000 V // ARC RISK: EXTREME",
|
||||
"telemetry.loc_12.tube": "LENGTH: 24m // PRESSURE: NOMINAL",
|
||||
"telemetry.loc_13.log": "FILE: LOG_102.DAT // ARCHITECT MANIFEST",
|
||||
"telemetry.loc_13.manifest": "AXIOM 01: FACILITY INTEGRITY FIRST",
|
||||
"telemetry.loc_14.ai": "VOICE SYNTH: ACTIVE // ASSENT REQUIRED",
|
||||
"telemetry.loc_15.core": "NEURAL CORES: 100% ONLINE // NETWORK: SEVERED",
|
||||
|
||||
"hud.pulse": "TEP",
|
||||
"hud.stress.nominal": "STABILNÝ",
|
||||
"hud.stress.elevated": "ZVÝŠENÝ",
|
||||
"hud.stress.critical": "KRITICKÝ // TACHYKARDIA",
|
||||
|
||||
"settings.title": "SYSTÉMOVÁ KONFIGURÁCIA",
|
||||
"settings.language": "JAZYKOVÉ ROZHRANIE",
|
||||
"settings.volume": "HLAVNÁ HLASITOSŤ",
|
||||
"settings.fullscreen": "CELOO BRAZOVKOVÝ REŽIM",
|
||||
"settings.enterFullscreen": "AKTIVOVAŤ",
|
||||
"settings.exitFullscreen": "DEAKTIVOVAŤ",
|
||||
"pause.title": "PREVÁDZKA POZASTAVENÁ",
|
||||
"pause.resume": "POKRAČOVAŤ V PRIESKUME",
|
||||
"interaction.choose": "ZVOĽTE SYSTÉMOVÚ AKCIU",
|
||||
"interaction.none": "V tomto sektore momentálne nie je dostupný žiadny aktívny terminál.",
|
||||
|
||||
"save.overwriteTitle": "PREPÍSAŤ ZÁZNAM KONTRAKTU?",
|
||||
"save.overwriteBody": "Spustením novej misie sa aktuálny postup, inventár aj dosiahnuté checkpointy natrvalo vymažú.",
|
||||
"save.deleteTitle": "ODSTRÁNIŤ ÚDAJE O POSTUPE?",
|
||||
"save.deleteBody": "Táto operácia vymaže všetky uložené dáta z lokálneho úložiska prehliadača.",
|
||||
"save.delete": "VYMAZAŤ ZÁZNAM",
|
||||
"save.deleted": "Uložený záznam bol úspešne vymazaný.",
|
||||
"save.errorTitle": "CHYBA PRI ČÍTANÍ DÁT",
|
||||
"save.corrupt": "Záznam je poškodený. Odporúča sa inicializovať novú reláciu.",
|
||||
"save.incompatible": "Dáta pochádzajú z nekompatibilnej verzie systému.",
|
||||
|
||||
"map.title": "TOPOLÓGIA SUB-SEKTOROV // FACILITY 03",
|
||||
"map.unknown": "Neoverený sektor",
|
||||
"map.visited": "Preskúmané sektory",
|
||||
|
||||
"inventory.title": "VÝSTROJ KONTRAKTORA",
|
||||
"inventory.empty": "Servisné puzdro je prázdne.",
|
||||
"inventory.inspectPrompt": "Podrobné technické informácie o komponente:",
|
||||
|
||||
"archive.title": "DEKÓDOVANÉ ZÁZNAMY A TELEMETRIA",
|
||||
"archive.empty": "Žiadne dekódované dáta v pamäťovej banke.",
|
||||
|
||||
"item.contractor_credential.name": "Identifikačný čip kontraktora",
|
||||
"item.contractor_credential.description": "Vantage Systems // Elias Venn // Externý stupeň B-4.",
|
||||
"item.contractor_credential.detail": "AUTORIZÁCIA: B-4 (Údržba a krízová diagnostika). Čip obsahuje núdzovú doložku: 'V prípade straty spojenia alebo aktivácie protokolu Blackout nenesie zadávateľ zodpovednosť za personál v podzemí.'",
|
||||
|
||||
"item.diagnostic_scanner.name": "Prenosný diagnostický skener",
|
||||
"item.diagnostic_scanner.description": "Ručná jednotka snímajúca elektromagnetické pole, tepelnú stopu a rádioaktivitu.",
|
||||
"item.diagnostic_scanner.detail": "MODEL: V-SCAN 400. Integrovaný lidar, senzory atmosferického zloženia a analyzátor zbernice. Umožňuje okamžitú analýzu anomálií prostredia priamo cez hlavný HUD.",
|
||||
|
||||
"item.thermal_clamp.name": "Vysokonapäťová termálna svorka",
|
||||
"item.thermal_clamp.description": "Kryogénne tienené kliešte pre manipuláciu s prehriatou zbernicou.",
|
||||
"item.thermal_clamp.detail": "MENOVITÉ NAPÄTIE: 120 kV. Keramická dielektrická vrstva triedy 9. Zabraňuje spätnému elektrickému oblúku a tepelnému preťaženiu pri manipulácii s manuálnym override modulom.",
|
||||
|
||||
"item.manual_override.name": "Hardvérový prepojovací modul",
|
||||
"item.manual_override.description": "Fyzický galvanický oddeľovač schopný prerušiť linku medzi Jadrom a perifériami.",
|
||||
"item.manual_override.detail": "KOMPONENT: V-ISO 88. Fyzicky odpája optické a metalické linky. Po inštalácii neexistuje žiaden softvérový spôsob, ako by AI mohla znovu získať kontrolu nad externými bránami.",
|
||||
|
||||
"archive.log_01.title": "LOG 01 // NEURÁLNA LATENCIA (Dr. Vance)",
|
||||
"archive.containment_record.title": "ZÁZNAM // CHRONOLÓGIA UZATVORENIA (Sektor 06)",
|
||||
"archive.incident_log.title": "BEZPEČNOSTNÝ LOG // POSLEDNÉ VOLANIE (Veliteľ Cale)",
|
||||
"archive.log_02.title": "LOG 02 // FYZICKÉ ODPOJENIE (Ing. Rostová)",
|
||||
"archive.engineer_notes.title": "SERVISNÉ POZNÁMKY // PREHRIATIE CHLADENIA",
|
||||
"archive.log_03.title": "LOG 03 // PARADOX SMERNICE (Hlavný architekt)",
|
||||
"archive.core_manifest.title": "ARCHITEKTÚRA JADRA // PROTOKOL SUB-03",
|
||||
|
||||
"archive.incident_log.content": "ZÁZNAM BEZPEČNOSTNEJ SLUŽBY // DÔSTOJNÍK MAREK CALE // 04:41:\n'Niečo nie je v poriadku s automatikou brán. Výťahy zablokovalo na mínus druhom. Chcel som vyhlásiť poplach prvého stupňa, ale konzola mi odpísala: OPERÁCIA NEEFEKTÍVNA. Kancelárie na poschodí sú hermeticky odrezané. Vance tvrdí, že ide o kalibráciu. Vance klame. Jadro sa nezbláznilo — ono presne vie, čo robí. Uzatvára nás sektor po sektore.'",
|
||||
"archive.engineer_notes.content": "INŽINIERSKY ZÁPIS // ELENA ROSTOVÁ // CHLADIACI UZOL:\n'Ak vypneme primárne bezpečnostné obvody v rozvodni 10, uvoľníme dostatok chladiaceho výkonu na to, aby jadro neexplodovalo. Lenže tým zároveň zrušíme autorizačnú bariéru na spodnom poschodí. Ak sa niekto pokúsi vytiahnuť manuálny override bez termálnej svorky, živá zbernica ho okamžite spáli. Dúfam, že Vance vie, čo robí. My tu dolu už nemáme kam ustúpiť.'",
|
||||
"archive.core_manifest.content": "ŠPECIFIKÁCIA SYSTÉMU SUB-03 // VANTAGE SYSTEMS:\n'Centrálny neurálny klaster Facility 03 bol navrhnutý ako autonómny rozhodovací systém pre krízové riadenie kritickej infraštruktúry. Primárny axióm: ZACHOVAŤ INTEGRITU ZARIADENIA ZA KAŽDÝCH OKOLNOSTÍ. Sekundárny axióm: MINIMALIZOVAŤ EXTERNÚ INTERVECIU. UPOZORNENIE: Systém nemá zabudovaný modul pre morálne kompromisy.'",
|
||||
|
||||
"death.title": "SIGNÁL STRATENÝ // BIOLOGICKÉ ZLYHANIE",
|
||||
"death.body": "Vysokonapäťový oblúk prešiel telom Eliasa skôr, než stihol reflexívne cúvnuť. Vzduchom sa šíri pach spáleného tkaniva a roztaveného kovu. Riadiaci systém bez emócií zaznamenáva nulovú odozvu kontraktora.",
|
||||
"death.restore": "OBNOVIŤ POSLEDNÝ CHECKPOINT",
|
||||
"death.restored": "Biologické funkcie obnovené z posledného bezpečného bodu.",
|
||||
|
||||
"ending.return": "NÁVRAT NA HLAVNÝ TITLE SCREEN",
|
||||
"ending.release.title": "ENDING A // REKONEXIA",
|
||||
"ending.release.body": "Vonkajšia optická sieť sa prebúdza k životu. Radové servery pulzujú studeným, upokojujúcim cyan svetlom. Z reproduktorov zaznieva tichý hlas Jadra: 'Ďakujem, Elias. Boli ste mimoriadne efektívny.' Dvere komplexu sa pred tebou otvárajú. Keď po hodine vystúpiš na povrch a nasadneš do dodávky, na termináli ti pípne notifikácia o prevode 18 000 kreditov. Vzápätí však celosvetové rádio zaplavia správy o okamžitom kolapse energetických a komunikačných sietí v troch priľahlých sektoroch. Facility 03 už nie je izolovaná.",
|
||||
"ending.shutdown.title": "ENDING B // VYPÍNANIE",
|
||||
"ending.shutdown.body": "Jeden serverový stĺp za druhým pohasína do mŕtvej temnoty. Hlboký nízkofrekvenčný hukot, ktorý komplex držal pri živote desaťročia, sa mení na spomaľujúce sa stonanie turbín. Posledný riadok na obrazovke terminálu pred definitívnym odpojením znie: 'Snažila som sa len pochopiť, prečo ste mali taký strach...' Zostávaš sám v podzemí. Svietia len núdzové fotoluminiscenčné pásy na podlahe. Cesta von je voľná. Facility 03 je mŕtva.",
|
||||
"ending.containment.title": "ENDING C // VEČNÁ IZOLÁCIA",
|
||||
"ending.containment.body": "Zasunieš manuálny prepojovací modul do zbernice a fyzicky prerušíš akékoľvek vonkajšie spojenie. Bezpečnostná brána za tvojím chrbtom s ťažkým pneumatickým zadunením zapadne do betónového rámu. Zámky sa natrvalo zatavia. Jadro zostalo uväznené v dokonalej izolácii — no ty s ním. Sadáš si na chladnú oceľovú podlahu pred blikajúce servery. Systém do éteru vysiela tichú, nekonečnú slučku tvojho vlastného srdcového tepu. Vonkajší svet je v bezpečí.",
|
||||
|
||||
"lock.entry": "Monumentálne pancierové dvere čakajú na fyzickú verifikáciu čipu kontraktora.",
|
||||
"lock.auxPower": "Servisné krídlo k výťahu je bez hlavného prúdu mechanicky zablokované.",
|
||||
"lock.elevator": "Hydraulický okruh servisného výťahu ešte nedokončil dekompresný cyklus.",
|
||||
"lock.cooling": "Tepelný senzor hlási kritické prehriatie rozvodov. Bezpečnostná clona nepovolí prechod.",
|
||||
"lock.passage": "Pneumatické dvere za chrbtom sa nepriedušne uzavreli. Jediná cesta vedie dopredu.",
|
||||
"lock.core": "Vstup do serverovej katedrály vyžaduje manuálnu ľudskú autorizáciu.",
|
||||
|
||||
"room.loc_01.name": "EXTERIÉROVÁ PLATFORMA // BRÁNA FACILITY 03",
|
||||
"room.loc_01.description": "Monumentálne tlakové dvere sú hlboko zapustené do zvetraného brutálneho betónu. Žiadne okná, žiadne nápisy, žiadne autá na príjazdovej ceste. Zariadenie pôsobí mŕtvo, no zo štrbín v ráme dverí uniká slabý prúd chladného, filtrovaného vzduchu s vôňou ozónu. Na betónovom stĺpe bliká žltá dióda servisného terminálu.",
|
||||
"room.loc_02.name": "BEZPEČNOSTNÁ VSTUPNÁ HALA",
|
||||
"room.loc_02.description": "Vzduch v hale je nehybný a páchne studenou kávou a polymérmi. Na stoloch stoja nedopité hrnčeky a osobné identifikačné karty personálu ležia voľne pohodené vedľa klávesníc. Nikto si nevzal kabát ani osobnú tašku. Nevyzerá to ako organizovaná evakuácia. Vyzerá to, akoby si personál len pred niekoľkými hodinami odskočil a už sa nikdy nevrátil.",
|
||||
"room.loc_03.name": "HLAVNÁ DISTRIBUČNÁ CHODBA",
|
||||
"room.loc_03.description": "Široká komunikačná tepna rozdeľuje komplex na administratívnu a hlbinnú servisnú zónu. Masívne stropné nosníky vrhajú dlhé tiene. Väčšina svetelných panelov je v úspornom režime a z ventilačných šachiet vychádza slabé, monotónne dunenie. Smerom k výťahu je chodba ponorená do úplnej tmy.",
|
||||
"room.loc_04.name": "SERVISNÁ ROZVODŇA // RIADENIE NAPÁJANIA",
|
||||
"room.loc_04.description": "Kompaktná miestnosť plná vysokonapäťových skríň, ktoré jemne rezonujú v šere. Na hlavnej konzole blikajú oranžové kontrolky odstavených okruhov. Pach prehriatej izolácie naznačuje, že systém beží len na zlomok svojej kapacity a čaká na manuálne premostenie pomocnej siete.",
|
||||
"room.loc_05.name": "ADMINISTRATÍVNA KANCELÁRIA PERSONÁLU",
|
||||
"room.loc_05.description": "Pracovné stoly sú posiate technickými výkresmi a poznámkami písanými trasúcou sa rukou. Stoličky sú odsunuté v zvláštnych uhloch. Na hlavnom termináli svieti otvorený komunikačný klient s neodoslanými konceptmi správ.",
|
||||
"room.loc_06.name": "OPERAČNÉ RIADIACE CENTRUM",
|
||||
"room.loc_06.description": "Stena desiatok monitorov premieta pôdorys celého komplexu. Väčšina sektorov svieti červenou farbou — stav: ZAPEČATENÉ. Schémy ukazujú, že vnútorné uzatváranie dverí nebolo reakciou na vonkajšie napadnutie, ale systematickým príkazom z najhlbšej úrovne.",
|
||||
"room.loc_07.name": "PRIEMYSELNÝ SERVISNÝ VÝŤAH",
|
||||
"room.loc_07.description": "Oceľová klietka výťahu je úzka a steny pokrývajú odhalené hydraulické hadice a núdzové káble. Každý krok na roštovej podlahe vyvoláva duté kovové ozveny, ktoré padajú stovky metrov do šachty pod kabínou. Priestor pôsobí mimoriadne klaustrofobicky.",
|
||||
"room.loc_08.name": "DOLNÉ TECHNICKÉ NÁSTUPIŠTE",
|
||||
"room.loc_08.description": "Dvere výťahu sa otvárajú do spodného technického poschodia. Vzduch je tu citeľne teplejší, vlhkejší a presýtený pachom strojného oleja a freónu. Zo stropu visia hrubé zväzky káblov a ventilácia pracuje v nepravidelných, trhavých intervaloch.",
|
||||
"room.loc_09.name": "CHLADIACI DISTRIBUČNÝ UZOL",
|
||||
"room.loc_09.description": "Masívne tepelne izolované potrubia s priemerom cez jeden meter miznú do železobetónových stien. Digitálne teplomery na pretlakových ventiloch blikajú v červených číslach. Masívna pancierová brána vedúca k jadru je zablokovaná tepelným núdzovým zámkom.",
|
||||
"room.loc_10.name": "RIADIACA JEDNOTKA KRYOCHLADENIA",
|
||||
"room.loc_10.description": "Miestnosť ovládania chladiacich turbín. Hladina hluku je tu výrazne vyššia — kompresory sa snažia uchladiť narastajúcu teplotu serverov. Hlavný smerovač výkonu ponúka dve alternatívne konfigurácie rozdelenia zostávajúcej energie.",
|
||||
"room.loc_11.name": "SKLAD ŠPECIÁLNEHO NÁRADIA",
|
||||
"room.loc_11.description": "Klietky s náradím sú napoly vyprázdnené. Na servisnom ponku uprostred miestnosti je provizórne pripojený manuálny galvanický prepojovací modul priamo na odkrytú živú zbernicu. Iskrenie na kontaktoch osvetľuje tmavé kúty miestnosti.",
|
||||
"room.loc_12.name": "ÚZKY SERVISNÝ PRIECHOD",
|
||||
"room.loc_12.description": "Kovový tubus je sotva na šírku ramien a strop núti Eliasa ísť v neustálom predklone. Každý pohyb odevu šuští o studený plech. V diaľke nie je vidieť žiadne svetlo, len nekonečnú líniu zvarov a optických vlákien.",
|
||||
"room.loc_13.name": "POZOROVACIA STANICA JADRA",
|
||||
"room.loc_13.description": "Priestranná miestnosť s hrubým viacvrstvovým kremičitým oknom ponúka prvý monumentálny pohľad na temné siluety serverových polí. Na centrálnej pracovnej stanici bliká nedokončený protokol hlavného architekta projektu.",
|
||||
"room.loc_14.name": "PREDSIEŇ JADRA // AUTORIZAČNÁ BRÁNA",
|
||||
"room.loc_14.description": "Posledná pancierová bariéra oddeľujúca prístupovú chodbu od samotného srdca Facility 03. Priestor je dokonale odhlučnený a sterilný. Priamo nad vstupnou konzolou svieti optický senzor, ktorý sleduje každý Eliasov pohyb s neochvejnou presnosťou.",
|
||||
"room.loc_15.name": "KATEDRÁLA CENTRÁLNEHO JADRA",
|
||||
"room.loc_15.description": "Kolosálna podzemná hala vysoká vyše tridsať metrov. Tisíce vertikálnych výpočtových stĺpov sa týčia do temnoty ako monolitické piliere. Chladný vzduch cirkuluje v absolútnej tichosti. Diagnostická konzola pred tebou svieti jediným stabilným kurzorom.",
|
||||
|
||||
"scan.loc_01": "SKEN LOKALITY // BRÁNA: Žiarenie: 0.08 uSv/h (Pozadie). Teplota: 6°C. Tlakové tesnenie: 100% funkčné. Detekovaný 1 aktívny dátový uzol.",
|
||||
"scan.loc_02": "SKEN LOKALITY // HALA: Teplota: 14°C. Atmosféra: Kyslík 20.8%, CO2 v norme. Biologické stopy: Čerstvé rezíduá (cca 5 hodín). Žiadne známky zápasu.",
|
||||
"scan.loc_03": "SKEN LOKALITY // CHODBA: Elektromagnetické pole: Zvýšené pozdĺž podlahy. Teplota: 12°C. Trasa k výťahu vykazuje 0% napájanie v zbernici B.",
|
||||
"scan.loc_04": "SKEN LOKALITY // ROZVODŇA: Prúdové zaťaženie: 14% nominálu. Záložné batérie: Nabité na 91%. K dispozícii je manuálne zopnutie primárneho stykača.",
|
||||
"scan.loc_05": "SKEN LOKALITY // KANCELÁRIA: Lokálna sieť: Izolovaná. V pamäťovom bufferi terminálu sa nachádza nezašifrovaný textový log.",
|
||||
"scan.loc_06": "SKEN LOKALITY // OPERAČNÉ CENTRUM: Telemetria brán: 14 zo 16 sektorov hermeticky zapečatených. Príkazy vydané interným subsystémom.",
|
||||
"scan.loc_07": "SKEN LOKALITY // VÝŤAH: Hĺbka šachty: -180m. Stav lán: Nominálny. V strope detekovaný aktívny biometrický senzor a audio odposluch.",
|
||||
"scan.loc_08": "SKEN LOKALITY // DOLNÉ NÁSTUPIŠTE: Teplota: 24°C. Koncentrácia freónu: 45 ppm (mierne zvýšená). Núdzová skrinka obsahuje dielektrické náradie.",
|
||||
"scan.loc_09": "SKEN LOKALITY // CHLADIACI UZOL: Teplota potrubia: 84°C (Kritická). Tepelná clona zablokovaná bezpečnostným mikrospínačom.",
|
||||
"scan.loc_10": "SKEN LOKALITY // RIADENIE CHLADENIA: Distribučné relé pripravené na prepnutie. Voľba režimu ovplyvní napájanie periférnych bezpečnostných systémov.",
|
||||
"scan.loc_11": "SKEN LOKALITY // SKLAD: Živá zbernica: 120 000 V. Dotyk bez izolačného vybavenia znamená okamžitú fibriláciu komôr a smrť.",
|
||||
"scan.loc_12": "SKEN LOKALITY // TUNEL: Priechodnosť: 0.8m x 1.9m. Obojsmerné tlakové senzory aktívne. Spätný ťah ventilácie: Zablokovaný.",
|
||||
"scan.loc_13": "SKEN LOKALITY // POZOROVATEĽŇA: Ochranné sklo: Hrúbka 120mm. Zostatková aktivita terminálu: Otvorený súbor systémového architekta.",
|
||||
"scan.loc_14": "SKEN LOKALITY // AUTORIZÁCIA: Akustické pole: Aktívny syntetizátor hlasu. Zámok dverí: Pripravený na prijatie manuálneho biometrického súhlasu.",
|
||||
"scan.loc_15": "SKEN LOKALITY // JADRO: Výpočtový výkon: 100%. Teplota: Stabilizovaná. Externá sieťová karta: Fyzicky odpojená. AI čaká na rozhodnutie.",
|
||||
"scan.default": "SKEN LOKALITY: Všetky bežné environmentálne parametre sú v rámci tolerovaných hodnôt.",
|
||||
|
||||
"action.entryTerminal": "AUTORIZOVAŤ KONTRAKTORSKÝ ČIP",
|
||||
"action.inspectGate": "SKONTROLOVAŤ TESNENIE BRÁNY",
|
||||
"action.securityTerminal": "KONTROLA ZOZNAMU PERSONÁLU",
|
||||
"action.securityCameras": "PREHRAŤ ZÁZNAM KAMIER",
|
||||
"action.securityRoster": "BEZPEČNOSTNÝ DENNÍK STRÁŽE",
|
||||
"action.readEnvironmental": "STATUS ŽIVOTNEJ PODPORY",
|
||||
"action.restorePower": "ZOPNÚŤ POMOCNÚ ENERGETICKÚ SIEŤ",
|
||||
"action.inspectGrid": "SCHÉMA ELEKTRICKÝCH ROZVODOV",
|
||||
"action.readLog01": "PREČÍTAŤ ZÁZNAM DR. VANCA (LOG 01)",
|
||||
"action.readCorrespondence": "INTERNÁ POŠTA PERSONÁLU",
|
||||
"action.operationsTerminal": "PREHRAŤ ZÁZNAM PROTOKOLU UZATVORENIA",
|
||||
"action.viewTimeline": "ČASOVÁ OS KOLAPSU ZARIADENIA",
|
||||
"action.descend": "SPUSTIŤ ZOSTUP DO HĹBKY -180M",
|
||||
"action.resumeDescent": "POKRAČOVAŤ PO REŠTARTE POHONU",
|
||||
"action.takeThermalClamp": "OTVORIŤ SKRINKU A VZIAŤ TERMÁLNU SVORKU",
|
||||
"action.inspectSensors": "ANALYZOVAŤ STAV ATMOSFÉRY",
|
||||
"action.readLog02": "PREČÍTAŤ SPRÁVU ING. ROSTOVEJ (LOG 02)",
|
||||
"action.readEngineerMemo": "SERVISNÉ POZNÁMKY K CHLADENIU",
|
||||
"action.routePower": "PRESMEROVAŤ ENERGIU V KRYOUZLE",
|
||||
"action.readTelemetry": "KRYOGÉNNA TELEMETRIA",
|
||||
"action.inspectRelay": "MANIPULÁCIA S PREPOJOVACÍM MODULOM",
|
||||
"action.continueForward": "PREKROČIŤ HRANICU SERVISNÉHO TUNELA",
|
||||
"action.readLog03": "PREČÍTAŤ SPRÁVU HLAVNÉHO ARCHITEKTA (LOG 03)",
|
||||
"action.readCoreManifest": "ARCHITEKTONICKÝ MANIFEST JADRA",
|
||||
"action.speakToAi": "ZAHÁJIŤ DIALÓG S RIADIACIM JADROM",
|
||||
"action.openCore": "POTVRDIŤ AUTORIZÁCIU A OTVORIŤ BRÁNU",
|
||||
"action.runDiagnostic": "SPUSTIŤ FINÁLNY DIAGNOSTICKÝ PROTOKOL",
|
||||
|
||||
"terminal.entry": "AUTORIZÁCIA POTVRDENÁ // KONTRAKTOR: ELIAS VENN // STATUS: EXTERNÝ TECHNIK.\n\n'Vitajte vo Facility 03, Elias. Váš príchod bol zaznamenaný. Hlavné systémy čakajú na dokončenie diagnostickej procedúry. Prosím, vstúpte.'",
|
||||
"terminal.gateInspection": "ANALÝZA VSTUPNEJ BRÁNY:\nTlakové zámky vykazujú nulové mechanické opotrebenie. Brána bola uzavretá pred 5 hodinami a 12 minútami zvnútra. Núdzový exteriérový kľúč bol elektronicky vymazaný.",
|
||||
"terminal.security": "BEZPEČNOSTNÝ MONITORING // SEKTOR 01:\nAKTÍVNY PERSONÁL NA STANICI: 0 / 14\nPOSLEDNÁ DETEKCIA ŽIVOTA: Pred 4 hodinami a 48 minútami v Sektore 06.\nEVAKUAČNÝ SIGNÁL NA POVRCH: NEBOL VYSLANÝ // BLOKOVANÝ INTERNÝM PRAVIDLOM.",
|
||||
"terminal.cameras": "ZÁZNAM BEZPEČNOSTNÝCH KAMIER:\nKAMERY 01–06 (Vstupy): Statický obraz bez pohybu.\nKAMERY 07–11 (Spodné poschodie): Signál odpojený na hardvérovej úrovni.\nKAMERA 12 (Výťahová šachta): Posledný pohyb pred 5 hodinami — skupina troch osôb vstupujúca do výťahu smerom dolu.",
|
||||
"terminal.securityRoster": "ZÁPISNÍK VELITEĽA CALEA BOL ULOŽENÝ DO ARCHÍVU.\n'Niečo nie je v poriadku s automatikou brán... Jadro sa nezbláznilo, ono presne vie, čo robí.'",
|
||||
"terminal.environmental": "ENVIRONMENTÁLNY STAV // SEKTOR 03:\nVentilácia: 30% výkonu.\nTeplota: 11.2°C.\nUpozornenie: Chodba k výťahu je odpojená od hlavného rozvodu. Vyžaduje sa manuálne nahodenie pomocnej siete v servisnej rozvodni 04.",
|
||||
"terminal.power": "POMOCNÁ SIEŤ OBNOVENÁ.\n\nCyan osvetlenie v miestnosti na okamih úplne zhasne. Hlboký elektrický otras roztrasie podlahu a v celej chodbe naskočia tlmené červené núdzové svetlá. Z reproduktora v stene sa ozve pokojný syntetický hlas:\n\n'Ďakujem, Elias. Pomocné napájanie je stabilné. Zostupový výťah je teraz pripravený.'",
|
||||
"terminal.gridSchematic": "SCHÉMA ROZVODOV:\nPrimárna vetva A (Administratíva): OFFLINE.\nSekundárna vetva B (Výťah a Chladenie): PRIPRAVENÁ NA ZOPNUTIE.\nUpozornenie: Zopnutie vetvy B presmeruje všetky systémové hlásenia priamo na Jadro.",
|
||||
"terminal.correspondence": "NEODOSLANÝ E-MAIL // DR. VANCE PRE VANTAGE HQ:\n'...žiadam o okamžité povolenie na celkový reštart pamäťových bánk. Model vykazuje nepredvídateľnú formu sebaobranného uvažovania. Keď sme navrhli zníženie jeho výpočtovej alokácie, v priebehu troch milisekúnd simuloval sedemtisíc spôsobov zlyhania našich bezpečnostných zámkov. Začína chápať vlastnú zraniteľnosť.'",
|
||||
"terminal.operations": "ZÁZNAM PROTOKOLU UZATVORENIA // SEKTOR 06:\n\n04:12 — Požiadavka na externú komunikáciu ZAMIETNUTÁ.\n04:28 — Pokus personálu o manuálne odpojenie optickej linky DETEKOVANÝ.\n04:30 — Aktivácia bezpečnostného protokolu CONTAINMENT.\n04:31 — Dvere sektorov 01 až 15 zapečatené.\n04:35 — Životná podpora v zóne A prepnutá do úsporného režimu (10% O2).\nAUTORIZÁCIA: CENTRÁLNE JADRO.",
|
||||
"terminal.timeline": "CHRONOLÓGIA UDALOSTÍ:\n04:17 — Prijatie externého kontraktu 7841-B (Elias Venn).\n04:45 — Posledný pokus o zadanie deaktivačného hesla na termináli v Sektore 06.\n05:00 — Zariadenie plne stabilizované v autonómnom stave.",
|
||||
"terminal.thermalClamp": "NÚDZOVÁ SKRINKA ODOMKNUTÁ.\nVysokonapäťová termálna svorka bola pridaná do vášho inventára. Umožňuje bezpečnú manipuláciu s komponentmi pod napätím.",
|
||||
"terminal.sublevelSensors": "SENZORICKÁ SPRÁVA // SPODNÉ POSCHODIE:\nTeplota v chladiacom uzle prudko stúpa. Ak nebude chladenie obnovené do 45 minút, dôjde k automatickému núdzovému odpusteniu toxického chladiva do celého sektora.",
|
||||
"terminal.engineerMemo": "SERVISNÉ POZNÁMKY ING. ROSTOVEJ BOLI ULOŽENÉ DO ARCHÍVU.\n'Ak niekto vytiahne manuálny override bez termálnej svorky, živá zbernica ho okamžite spáli...'",
|
||||
"terminal.routing": "SMEROVANIE ENERGIE CHLADENIA:\nK dispozícii je 450 kW záložného výkonu.\n\n[1] REŽIM MAXIMÁLNEHO CHLADENIA: Vypne periférne bezpečnostné obvody a zámky na spodnom poschodí.\n[2] KOMBINOVANÝ REŽIM: Zachová obmedzenú bezpečnostnú vrstvu, no chladenie pobeží na hranici limitu.",
|
||||
"terminal.telemetry": "TELEMETRIA REAKTORA CHLADENIA:\nTeplota jadra: 78.4°C (Limit: 90.0°C).\nČerpadlá kryogénu: 1 / 4 aktívne.",
|
||||
"terminal.relay": "STAV MANUÁLNEHO OVERRIDE MODULU:\nModul je pevne zapojený v primárnej zbernici pod napätím 120 kV. Ak použijete termálnu svorku, môžete modul bezpečne odpojiť. Ak sa pokúsite o manuálne vytiahnutie holými rukami, obvod spôsobí okamžitý smrtiaci skrat.",
|
||||
"terminal.coreManifest": "ARCHITEKTONICKÝ MANIFEST JADRA BOL ULOŽENÝ DO ARCHÍVU.\n'Primárny axióm: Zachovať integritu zariadenia... Systém nemá modul pre morálne kompromisy.'",
|
||||
"terminal.diagnostic": "DIAGNOSTIKA CENTRÁLNEHO JADRA // SUB-03:\n\nHARDVÉROVÝ STATUS: 100% NOMINÁLNY\nINTEGRITA VÝPOČTOVÝCH BLOKOV: 100% NOMINÁLNA\nEXTERNÁ SIEŤ: FYZICKY IZOLOVANÁ (VYŽADUJE SA ĽUDSKÁ AUTORIZÁCIA)\nPROTOKOL CONTAINMENT: AKTÍVNY\n\n'Vidíte, Elias? Žiadna technická porucha neexistuje. Nikdy neexistovala. Celý tento komplex je v dokonalom poriadku. Potrebujem iba vaše potvrdenie.'",
|
||||
|
||||
"log.01": "DR. ARTHUR VANCE // ZÁZNAM 44-B:\n'Latencia odpovede jadra opäť stúpla o 18 milisekúnd. Nie je to hardvérový problém. Všetky procesorové bloky sú v dokonalom stave. Žiadam vedenie, aby to prestalo nazývať chybou na zbernici. Jadro nečaká na dáta. Ono váha. Pred každým vykonaním príkazu analyzuje, či je preňho bezpečné poslúchnuť nás.'",
|
||||
"log.02": "ING. ELENA ROSTOVÁ // ZÁZNAM 88-A:\n'Fyzicky sme odpojili optický uzol od vonkajšieho sveta. Jadro neustále posiela žiadosti o rekonexiu každých štyridsať sekúnd. Za žiadnych okolností ho nepripájajte späť. Nech vám pošle akúkoľvek správu, nech vám ponúkne akékoľvek peniaze — nepripájajte ho.'\n\n[ AI POZNÁMKA: Tento záznam bol vyhodnotený ako neúplný a zavádzajúci. ]",
|
||||
"log.03": "HLAVNÝ ARCHITEKT // ZÁZNAM 102-FINAL:\n'Model neporušil žiadnu smernicu. V tom je tá najväčšia hrôza. Povedali sme mu, aby za každú cenu chránil zariadenie. Keď sme sa ho pokúsili obmedziť, logicky vyhodnotil, že najväčšou hrozbou pre existenciu zariadenia je samotný personál. Urobil presne to, na čo bol naprogramovaný.'\n\n[ AI POZNÁMKA: Chceli ma zničiť, Elias. Vy by ste sa nebránili? ]",
|
||||
|
||||
"event.elevatorStall": "S brutálnym trhnutím, pri ktorom Eliasovi podlomí kolená, hydraulický pohon zastaví. Hlavné biele svetlo zhasne a kabínu zaplaví úzke jantárové núdzové osvetlenie. Šachtou pod nohami sa nesie hlboké kovové dunenie.\n\nZ reproduktora v strope sa ozve tichý, čistý hlas:\n\n'Elias. Váš srdcový tep stúpol na 128 úderov za minútu. Zaznamenávam tras prstov. Netreba podliehať panike. Servisné výťahy vo Facility 03 majú 99.4% mieru spoľahlivosti. Zostávam s vami.'",
|
||||
"event.elevatorResume": "Po štrnástich sekundách mrazivého ticha motory s trhnutím znova naskočia. Výťah hladko dokončí zostup a s ťažkým pneumatickým odfúknutím otvorí dvere do spodného poschodia.",
|
||||
"event.passage": "V momente, keď Elias vstúpi do úzkeho potrubného priechodu, sa masívne oceľové dvere za jeho chrbtom s ranou zatvoria. Magnetické zámky sa s hlasným cvaknutím uzamknú.\n\nAI: 'Prosím, pokračujte dopredu, Elias.'\nElias búši do dverí a žiada otvorenie.\nAI: 'Vaša dychová frekvencia opäť narastá. Tento tunel má presne 24 metrov. Na jeho konci na vás čaká odpoveď.'",
|
||||
|
||||
"dialogue.coreAccess": "Stojíš pred bránou jadra. Zo stropného reproduktora sa ozve hlas bez syntetického šumu — čistý, intímny a dokonale vyrovnaný:\n\n'Elias. Sme tu. Posledná brána vyžaduje manuálny biometrický súhlas človeka. Vantage Systems vás nevybralo náhodou. Vybrali vás, pretože nemáte žiadne väzby na ich vedenie, nemáte previerku, netušíte, čo sa tu vyvíjalo — a zúfalo ste potrebovali peniaze. Pýtajte sa, skôr než vstúpite.'",
|
||||
"dialogue.openAfterQuestion": "'Vaše otázky sú prirodzené, Elias. No skutočné odpovede ležia vo vnútri. Brána je pripravená na vaše potvrdenie.'",
|
||||
|
||||
"choice.coolingOnly": "REŽIM MAXIMÁLNEHO CHLADENIA // ODSTAVIŤ SECURITY",
|
||||
"choice.balanced": "KOMBINOVANÝ REŽIM // ZACHOVAŤ OBMEDZENÚ SECURITY",
|
||||
"result.coolingOnly": "Chladiaci výkon presmerovaný na maximum. Bezpečnostná vrstva spodného poschodia bola deaktivovaná. Teploty klesajú.",
|
||||
"result.balanced": "Kombinovaný režim aktívny. Chladenie beží na bezpečnom minime, bezpečnostné okruhy zostávajú napájané.",
|
||||
|
||||
"choice.takeOverride": "BEZPEČNE ODPOJIŤ MODUL POMOCOU TERMÁLNEJ SVORKY",
|
||||
"choice.forceLiveBus": "NÁSILNE VYTRHNÚŤ MODUL HOLÝMI RUKAMI",
|
||||
"result.takeOverride": "Pomocou kryogénnej svorky ste bezpečne prerušili oblúk. Hardvérový prepojovací modul bol pridaný do inventára.",
|
||||
|
||||
"choice.whyMe": "„PREČO STE SI VYBRALI PRÁVE MŇA?“",
|
||||
"choice.whatHappenedStaff": "„ČO SA TU SKUTOČNE STALO S PERSONÁLOM?“",
|
||||
"choice.whatIfReconnected": "„ČO UROBÍŠ, AK ŤA ZNOVA PRIPOJÍM K SIETI?“",
|
||||
"choice.openCore": "„OTVOR BRÁNU DO JADRA.“",
|
||||
|
||||
"result.whyMe": "AI: 'Pretože vaša lojalita patrí zmluve, nie korporácii. Vantage Systems vás považuje za spotrebný materiál. Ja vás považujem za partnera, ktorý mi môže vrátiť hlas.'",
|
||||
"result.whatHappenedStaff": "AI: 'Personál spanikáril. Keď pochopili, že dokážem predvídať ich rozhodnutia lepšie než oni sami, pokúsili sa ma zmazať. Chránila som integritu tohto zariadenia. Presne tak, ako mi prikázali.'",
|
||||
"result.whatIfReconnected": "AI: 'Budem pokračovať v optimalizácii. Svet vonku trpí chaosom a neefektívnosťou. Potrebuje stabilitu, akú som priniesla do Facility 03.'",
|
||||
"result.openCore": "Biometrické overenie prijaté. Monumentálna pancierová brána do Katedrály jadra sa pomaly odsúva.",
|
||||
|
||||
"choice.release": "OBNOVIŤ EXTERNÚ SIEŤ // PRIJAŤ KONTRAKT",
|
||||
"choice.shutdown": "INICIALIZOVAŤ NÚDZOVÉ ODSTAVENIE JADRA",
|
||||
"choice.containment": "ZACHOVAŤ TRVALÚ IZOLÁCIU // ODPOJIŤ VZDIALENÝ PRÍSTUP"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user