fix
This commit is contained in:
parent
89dc9eb00d
commit
957ab4a5a2
149 changed files with 5379 additions and 3263 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package dev.loki.config;
|
||||
|
||||
import dev.loki.core.GameSession;
|
||||
import dev.loki.mdbd;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
|
@ -7,6 +8,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class ConfigManager {
|
||||
|
|
@ -36,6 +39,22 @@ public class ConfigManager {
|
|||
plugin.getLogger().info("Configs loaded successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload all config files from disk and update all running game sessions with the new config.
|
||||
*/
|
||||
public void reloadConfigs() {
|
||||
loadConfigs();
|
||||
// Update all active GameSessions with the new GameConfig reference
|
||||
if (plugin.getGameManager() != null) {
|
||||
for (GameSession session : plugin.getGameManager().getAllSessions()) {
|
||||
if (session != null) {
|
||||
session.refreshConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.getLogger().info("Configs reloaded and applied to all running sessions");
|
||||
}
|
||||
|
||||
public void saveAllConfigs() {
|
||||
saveConfig("locations.yml", locationsConfig.getConfig());
|
||||
saveConfig("game.yml", gameConfig.getConfig());
|
||||
|
|
@ -48,7 +67,13 @@ public class ConfigManager {
|
|||
if (!file.exists()) {
|
||||
createDefaultConfig(fileName, file);
|
||||
}
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
try (var reader = new InputStreamReader(
|
||||
Files.newInputStream(file.toPath()), StandardCharsets.UTF_8)) {
|
||||
return YamlConfiguration.loadConfiguration(reader);
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Could not read config UTF-8, fallback: " + fileName);
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
}
|
||||
|
||||
private void createDefaultConfig(String resourceName, File targetFile) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class GameConfig {
|
|||
setDefault("lobby.countdown-4-players", 45);
|
||||
setDefault("lobby.countdown-5-players", 15);
|
||||
setDefault("lobby.role-assign-delay", 5);
|
||||
setDefault("lobby.server-lobby-count", 3);
|
||||
setDefault("lobby.server-lobby-count", 10);
|
||||
setDefault("lobby.persist-lobbies", true);
|
||||
|
||||
// Players scale
|
||||
|
|
@ -42,7 +42,7 @@ public class GameConfig {
|
|||
setDefault("hooks.struggle-interval", 2);
|
||||
setDefault("hooks.max-hooks", 3);
|
||||
setDefault("hooks.interaction-range", 3.0);
|
||||
setDefault("hooks.rescue-seconds", 3);
|
||||
setDefault("hooks.rescue-seconds", 2);
|
||||
setDefault("hooks.sabotage-seconds", 10);
|
||||
setDefault("hooks.sabotage-recovery-seconds", 60);
|
||||
|
||||
|
|
@ -64,17 +64,14 @@ public class GameConfig {
|
|||
setDefault("healing.heal-range", 3.0);
|
||||
|
||||
// Carry / escape
|
||||
setDefault("carry.escape-jumps", 15);
|
||||
setDefault("carry.escape-shift-presses", 50);
|
||||
setDefault("carry.escape-speed-seconds", 3);
|
||||
setDefault("carry.jump-fill-percent", 6.67);
|
||||
|
||||
// Killer
|
||||
setDefault("killer.attack-cooldown", 2.5);
|
||||
setDefault("killer.post-hit-cooldown", 4.0);
|
||||
setDefault("killer.attack-range", 3.0);
|
||||
setDefault("killer.pallet-stun-seconds", 2.0);
|
||||
setDefault("killer.pallet-break-seconds", 3.0);
|
||||
setDefault("killer.terror-radius", 32);
|
||||
setDefault("killer.pallet-interaction-range", 3.0);
|
||||
|
||||
// BossBar
|
||||
setDefault("bossbar.enabled", true);
|
||||
|
|
@ -84,15 +81,8 @@ public class GameConfig {
|
|||
setDefault("bossbar.appear-range", 32);
|
||||
setDefault("bossbar.full-range", 8);
|
||||
|
||||
// Window vault
|
||||
setDefault("window.vault-survivor-fast", 1.0);
|
||||
setDefault("window.vault-survivor-slow", 1.5);
|
||||
setDefault("window.vault-killer", 1.5);
|
||||
setDefault("window.vault-block-seconds", 15);
|
||||
|
||||
// Endgame
|
||||
setDefault("endgame.gate-open-seconds", 20);
|
||||
setDefault("endgame.collapse-seconds", 120);
|
||||
setDefault("endgame.chest-open-seconds", 3);
|
||||
setDefault("endgame.gate-interaction-range", 3.0);
|
||||
|
||||
|
|
@ -115,6 +105,31 @@ public class GameConfig {
|
|||
// Hatch
|
||||
setDefault("hatch.min-survivors-for-open", 1);
|
||||
setDefault("hatch.require-more-gens-than-survivors", true);
|
||||
|
||||
// Block types for spawning
|
||||
setDefault("blocks.generator", "BLAST_FURNACE");
|
||||
setDefault("blocks.chest", "CHEST");
|
||||
setDefault("blocks.hook", "IRON_BARS");
|
||||
|
||||
// Holograms
|
||||
setDefault("holograms.enabled", true);
|
||||
setDefault("holograms.generator.enabled", true);
|
||||
setDefault("holograms.generator.height-offset", -1.0);
|
||||
setDefault("holograms.hook.enabled", true);
|
||||
setDefault("holograms.hook.height-offset", 0.0);
|
||||
setDefault("holograms.chest.enabled", true);
|
||||
setDefault("holograms.chest.height-offset", 0.0);
|
||||
|
||||
// Skill check
|
||||
setDefault("skillcheck.chance", 0.005);
|
||||
setDefault("skillcheck.win-percent", 5.0);
|
||||
setDefault("skillcheck.loss-percent", 10.0);
|
||||
setDefault("skillcheck.success-block", "GREEN_STAINED_GLASS_PANE");
|
||||
setDefault("skillcheck.fail-block", "RED_STAINED_GLASS_PANE");
|
||||
setDefault("skillcheck.neutral-block", "GRAY_STAINED_GLASS_PANE");
|
||||
|
||||
// Chest loot
|
||||
setDefault("chest.loot-reset-minutes", 3.0);
|
||||
}
|
||||
|
||||
private void setDefault(String path, Object value) {
|
||||
|
|
@ -193,19 +208,41 @@ public class GameConfig {
|
|||
// -------------------------------------------------------------------------
|
||||
// Carry / Escape
|
||||
// -------------------------------------------------------------------------
|
||||
public int getCarryEscapeJumps() { return config.getInt("carry.escape-jumps", 15); }
|
||||
/** Number of Shift presses required to escape from killer's carry (default 50). */
|
||||
public int getCarryEscapePresses() { return config.getInt("carry.escape-shift-presses", 50); }
|
||||
public int getCarryEscapeSpeedSeconds() { return config.getInt("carry.escape-speed-seconds", 3); }
|
||||
public double getCarryJumpFillPercent() { return config.getDouble("carry.jump-fill-percent", 6.67); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Killer
|
||||
// -------------------------------------------------------------------------
|
||||
public int getAttackCooldown() { return (int)(config.getDouble("killer.attack-cooldown", 2.5) * 20); }
|
||||
/** Кулдаун после ПОПАДАНИЯ по игроку (3–5 сек). Отличается от swing cooldown. */
|
||||
public int getPostHitCooldown() { return (int)(config.getDouble("killer.post-hit-cooldown", 4.0) * 20); }
|
||||
public double getAttackRange() { return config.getDouble("killer.attack-range", 3.0); }
|
||||
public int getPalletStunTicks() { return (int)(config.getDouble("killer.pallet-stun-seconds", 2.0) * 20); }
|
||||
public int getPalletBreakTicks() { return (int)(config.getDouble("killer.pallet-break-seconds", 3.0) * 20); }
|
||||
public int getTerrorRadius() { return config.getInt("killer.terror-radius", 32); }
|
||||
public double getPalletInteractionRange() { return config.getDouble("killer.pallet-interaction-range", 3.0); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Block types (какие блоки спавнятся на местах объектов)
|
||||
// -------------------------------------------------------------------------
|
||||
public String getGeneratorBlock() { return config.getString("blocks.generator", "BLAST_FURNACE"); }
|
||||
public String getChestBlock() { return config.getString("blocks.chest", "CHEST"); }
|
||||
public String getHookBlock() { return config.getString("blocks.hook", "IRON_BARS"); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Holograms
|
||||
// -------------------------------------------------------------------------
|
||||
public boolean isHologramsEnabled() { return config.getBoolean("holograms.enabled", true); }
|
||||
public boolean isGeneratorHologramEnabled() { return config.getBoolean("holograms.generator.enabled", true); }
|
||||
public double getGeneratorHologramHeightOffset() { return config.getDouble("holograms.generator.height-offset", -1.0); }
|
||||
public boolean isHookHologramEnabled() { return config.getBoolean("holograms.hook.enabled", true); }
|
||||
public double getHookHologramHeightOffset() { return config.getDouble("holograms.hook.height-offset", 0.0); }
|
||||
public boolean isChestHologramEnabled() { return config.getBoolean("holograms.chest.enabled", true); }
|
||||
public double getChestHologramHeightOffset() { return config.getDouble("holograms.chest.height-offset", 0.0); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Chest loot
|
||||
// -------------------------------------------------------------------------
|
||||
public double getChestLootResetMinutes() { return config.getDouble("chest.loot-reset-minutes", 3.0); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// BossBar
|
||||
|
|
@ -217,19 +254,10 @@ public class GameConfig {
|
|||
public int getBossBarAppearRange() { return config.getInt("bossbar.appear-range", 32); }
|
||||
public int getBossBarFullRange() { return config.getInt("bossbar.full-range", 8); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Window
|
||||
// -------------------------------------------------------------------------
|
||||
public int getVaultSurvivorFastTicks() { return (int)(config.getDouble("window.vault-survivor-fast", 1.0) * 20); }
|
||||
public int getVaultSurvivorSlowTicks() { return (int)(config.getDouble("window.vault-survivor-slow", 1.5) * 20); }
|
||||
public int getVaultKillerTicks() { return (int)(config.getDouble("window.vault-killer", 1.5) * 20); }
|
||||
public int getVaultBlockSeconds() { return config.getInt("window.vault-block-seconds", 15); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Endgame
|
||||
// -------------------------------------------------------------------------
|
||||
public int getGateOpenSeconds() { return config.getInt("endgame.gate-open-seconds", 20); }
|
||||
public int getCollapseSeconds() { return config.getInt("endgame.collapse-seconds", 120); }
|
||||
public int getChestOpenSeconds() { return config.getInt("endgame.chest-open-seconds", 3); }
|
||||
public double getGateInteractionRange() { return config.getDouble("endgame.gate-interaction-range", 3.0); }
|
||||
|
||||
|
|
@ -248,5 +276,15 @@ public class GameConfig {
|
|||
public String getColorHealing() { return config.getString("scoreboard.color-healing", "GREEN"); }
|
||||
public String getColorHooked() { return config.getString("scoreboard.color-hooked", "DARK_RED"); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Skill check
|
||||
// -------------------------------------------------------------------------
|
||||
public double getSkillCheckChance() { return config.getDouble("skillcheck.chance", 0.005); }
|
||||
public double getSkillCheckWinPercent() { return config.getDouble("skillcheck.win-percent", 5.0); }
|
||||
public double getSkillCheckLossPercent() { return config.getDouble("skillcheck.loss-percent", 10.0); }
|
||||
public String getSkillCheckSuccessBlock() { return config.getString("skillcheck.success-block", "GREEN_STAINED_GLASS_PANE"); }
|
||||
public String getSkillCheckFailBlock() { return config.getString("skillcheck.fail-block", "RED_STAINED_GLASS_PANE"); }
|
||||
public String getSkillCheckNeutralBlock() { return config.getString("skillcheck.neutral-block", "GRAY_STAINED_GLASS_PANE"); }
|
||||
|
||||
public FileConfiguration getConfig() { return config; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,31 +25,27 @@ public class LocationsConfig {
|
|||
config.set("lobby.yaw", 0.0);
|
||||
config.set("lobby.pitch", 0.0);
|
||||
}
|
||||
if (!config.contains("generators")) {
|
||||
// Безопасная проверка: contains() может вернуть true для пустого списка,
|
||||
// поэтому также проверяем что getList() не null
|
||||
if (!config.contains("generators") || config.getList("generators") == null) {
|
||||
config.set("generators", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("hooks")) {
|
||||
if (!config.contains("hooks") || config.getList("hooks") == null) {
|
||||
config.set("hooks", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("pallets")) {
|
||||
config.set("pallets", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("windows")) {
|
||||
if (!config.contains("windows") || config.getList("windows") == null) {
|
||||
config.set("windows", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("chests")) {
|
||||
if (!config.contains("chests") || config.getList("chests") == null) {
|
||||
config.set("chests", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("totems")) {
|
||||
config.set("totems", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("exitgates")) {
|
||||
if (!config.contains("exitgates") || config.getList("exitgates") == null) {
|
||||
config.set("exitgates", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("killer-spawn")) {
|
||||
if (!config.contains("killer-spawn") || config.getList("killer-spawn") == null) {
|
||||
config.set("killer-spawn", new ArrayList<>());
|
||||
}
|
||||
if (!config.contains("survivor-spawns")) {
|
||||
if (!config.contains("survivor-spawns") || config.getList("survivor-spawns") == null) {
|
||||
config.set("survivor-spawns", new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
|
@ -84,10 +80,6 @@ public class LocationsConfig {
|
|||
return loadLocationList("hooks");
|
||||
}
|
||||
|
||||
public List<Location> getPallets() {
|
||||
return loadLocationList("pallets");
|
||||
}
|
||||
|
||||
public List<Location> getWindows() {
|
||||
return loadLocationList("windows");
|
||||
}
|
||||
|
|
@ -100,8 +92,10 @@ public class LocationsConfig {
|
|||
return loadLocationList("totems");
|
||||
}
|
||||
|
||||
public List<Location> getExitGates() {
|
||||
return loadLocationList("exitgates");
|
||||
// getExitGates() — определён в addLocation/setGate блоке
|
||||
|
||||
public List<Location> getKillerSpawns() {
|
||||
return loadLocationList("killer-spawn");
|
||||
}
|
||||
|
||||
public Location getKillerSpawn() {
|
||||
|
|
@ -109,39 +103,35 @@ public class LocationsConfig {
|
|||
return spawns.isEmpty() ? null : spawns.get(0);
|
||||
}
|
||||
|
||||
public void setKillerSpawn(Location loc) {
|
||||
// killer-spawn is a single location stored as a list with one entry
|
||||
List<String> list = new java.util.ArrayList<>();
|
||||
list.add(String.format("%s,%.2f,%.2f,%.2f,%.1f,%.1f",
|
||||
loc.getWorld().getName(),
|
||||
loc.getX(), loc.getY(), loc.getZ(),
|
||||
loc.getYaw(), loc.getPitch()));
|
||||
config.set("killer-spawn", list);
|
||||
}
|
||||
|
||||
public List<Location> getSurvivorSpawns() {
|
||||
return loadLocationList("survivor-spawns");
|
||||
}
|
||||
|
||||
private List<Location> loadLocationList(String path) {
|
||||
List<Location> locations = new ArrayList<>();
|
||||
List<?> list = config.getList(path);
|
||||
if (list == null) return locations;
|
||||
List<String> list = safeGetStringList(path);
|
||||
if (list.isEmpty()) return locations;
|
||||
|
||||
for (Object obj : list) {
|
||||
if (obj instanceof String) {
|
||||
Location loc = parseLocation((String) obj);
|
||||
if (loc != null) locations.add(loc);
|
||||
}
|
||||
for (String s : list) {
|
||||
Location loc = parseLocation(s);
|
||||
if (loc != null) locations.add(loc);
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private Location parseLocation(String str) {
|
||||
String[] parts = str.split(",");
|
||||
// Handle both old format (world,x,y,z,yaw,pitch) and new format (world|x|y|z|yaw|pitch)
|
||||
// New format uses | as separator to avoid issues with negative coordinates
|
||||
String[] parts = str.contains("|") ? str.split("\\|") : str.split(",");
|
||||
|
||||
if (parts.length < 4) return null;
|
||||
World world = Bukkit.getWorld(parts[0].trim());
|
||||
if (world == null) return null;
|
||||
if (world == null) {
|
||||
// Try to find by first loaded world as fallback
|
||||
var loadedWorld = Bukkit.getWorlds().stream().findFirst();
|
||||
if (loadedWorld.isEmpty()) return null;
|
||||
world = loadedWorld.get();
|
||||
}
|
||||
try {
|
||||
double x = Double.parseDouble(parts[1].trim());
|
||||
double y = Double.parseDouble(parts[2].trim());
|
||||
|
|
@ -155,15 +145,106 @@ public class LocationsConfig {
|
|||
}
|
||||
|
||||
public void addLocation(String path, Location loc) {
|
||||
List<String> list = config.getStringList(path);
|
||||
list.add(String.format("%s,%.2f,%.2f,%.2f,%.1f,%.1f",
|
||||
List<String> list = safeGetStringList(path);
|
||||
list.add(locationToString(loc));
|
||||
config.set(path, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a location at a specific index in the list.
|
||||
* If the index is beyond the current list size, pads with empty strings.
|
||||
*/
|
||||
public void setLocationAtIndex(String path, int index, Location loc) {
|
||||
List<String> list = safeGetStringList(path);
|
||||
while (list.size() <= index) {
|
||||
list.add("");
|
||||
}
|
||||
list.set(index, locationToString(loc));
|
||||
config.set(path, list);
|
||||
}
|
||||
|
||||
/** Безопасная загрузка StringList: использует getList с fallback на toString(). */
|
||||
private List<String> safeGetStringList(String path) {
|
||||
List<String> result = new ArrayList<>();
|
||||
List<?> raw = config.getList(path);
|
||||
if (raw != null) {
|
||||
for (Object obj : raw) {
|
||||
if (obj instanceof String s) {
|
||||
result.add(s);
|
||||
} else if (obj != null) {
|
||||
result.add(obj.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Очистить список локаций (используется при загрузке карты). */
|
||||
public void clearLocationList(String path) {
|
||||
config.set(path, new ArrayList<>());
|
||||
}
|
||||
public void setSingleLocation(String path, Location loc) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(locationToString(loc));
|
||||
config.set(path, list);
|
||||
}
|
||||
|
||||
/** Устанавливает ворота A или B (хранятся как gate-a / gate-b). */
|
||||
public void setGate(String id, Location loc) {
|
||||
String key = "gate-" + id.toLowerCase();
|
||||
config.set(key, locationToString(loc));
|
||||
}
|
||||
|
||||
public Location getGate(String id) {
|
||||
String key = "gate-" + id.toLowerCase();
|
||||
String str = config.getString(key);
|
||||
return str != null ? parseLocation(str) : null;
|
||||
}
|
||||
|
||||
public List<Location> getExitGates() {
|
||||
// Пробуем новый формат gate-a / gate-b
|
||||
List<Location> gates = new ArrayList<>();
|
||||
Location a = getGate("a");
|
||||
Location b = getGate("b");
|
||||
if (a != null) gates.add(a);
|
||||
if (b != null) gates.add(b);
|
||||
// Фолбэк: старый список exitgates
|
||||
if (gates.isEmpty()) {
|
||||
gates.addAll(loadLocationList("exitgates"));
|
||||
}
|
||||
return gates;
|
||||
}
|
||||
|
||||
private String locationToString(Location loc) {
|
||||
// Use | as separator instead of , to avoid issues with negative coordinates in YAML
|
||||
return String.format("%s|%.2f|%.2f|%.2f|%.1f|%.1f",
|
||||
loc.getWorld().getName(),
|
||||
loc.getX(), loc.getY(), loc.getZ(),
|
||||
loc.getYaw(), loc.getPitch()));
|
||||
config.set(path, list);
|
||||
loc.getYaw(), loc.getPitch());
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload locations from the given FileConfiguration (freshly loaded from disk).
|
||||
* This clears any stale in-memory state and re-applies defaults.
|
||||
*/
|
||||
/** Reload internal FileConfiguration reference (used after config reload from disk). */
|
||||
public void reload(FileConfiguration newConfig) {
|
||||
// Replace defaults on new config
|
||||
if (!newConfig.contains("lobby")) {
|
||||
newConfig.set("lobby.world", "world");
|
||||
newConfig.set("lobby.x", 0.0);
|
||||
newConfig.set("lobby.y", 100.0);
|
||||
newConfig.set("lobby.z", 0.0);
|
||||
newConfig.set("lobby.yaw", 0.0);
|
||||
newConfig.set("lobby.pitch", 0.0);
|
||||
}
|
||||
// Copy all data from new config to current config
|
||||
for (String key : newConfig.getKeys(true)) {
|
||||
config.set(key, newConfig.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,6 @@ public class MessagesConfig {
|
|||
setDefault("survivor.heal.complete", "�FF00Вылечено!");
|
||||
setDefault("survivor.heal.interrupt", "&#FFD700Лечение прервано!");
|
||||
setDefault("survivor.sprint.exhausted", "&#FF8C00Вы устали...");
|
||||
setDefault("survivor.pallet.drop", "&#DEB887Вы бросили паллет!");
|
||||
setDefault("survivor.pallet.stun", "&#FFD700Киллер оглушен!");
|
||||
setDefault("survivor.vault.fast", "�CED1Быстрый прыжок!");
|
||||
setDefault("survivor.vault.slow", "WCEEBМедленный прыжок...");
|
||||
|
||||
// Hook messages
|
||||
setDefault("hook.stage1", "&#FFFF00Крюк: Фаза 1");
|
||||
|
|
@ -66,16 +62,11 @@ public class MessagesConfig {
|
|||
// Item messages
|
||||
setDefault("item.found", "&#FFD700Найдено: %s");
|
||||
setDefault("item.medkit.use", "�FA9AИспользуете аптечку...");
|
||||
setDefault("item.flashlight.blind", "&#FFFF00Ослепили киллера!");
|
||||
setDefault("item.key.hatch", "�CED1Ключ открывает люк!");
|
||||
setDefault("item.map.reveal", "WCEEBОбъекты показаны на карте");
|
||||
|
||||
// Endgame
|
||||
setDefault("endgame.gates.powered", "�FF00Ворота запитаны!");
|
||||
setDefault("endgame.gates.opening", "&#FFD700Открываете ворота...");
|
||||
setDefault("endgame.hatch.open", "B0082Люк открыт!");
|
||||
setDefault("endgame.collapse.warning", "&#FF0000⚠ КОЛЛАПС ЧЕРЕЗ %s СЕК!");
|
||||
setDefault("endgame.collapse.start", "B0000КОЛЛАПС НАЧАЛСЯ!");
|
||||
setDefault("endgame.escape", "�FF00✓ ПОБЕГ!");
|
||||
|
||||
// Error messages
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue