using UnityEngine; // ТАБЛИЦА БАЛАНСА БОЯ. Все числа боевой системы -- здесь, а не в коде модуля (ревью от 27.10.2026, п. 2.5). // // Ассет: Assets/Resources/BattleConfig.asset (выдели его в окне Project и меняй числа в Inspector, // перекомпиляция не нужна; изменения действуют со следующего запуска игры). Создать заново: // правый клик в Project -> Create -> Bogatyri -> Battle Config, имя файла -- BattleConfig, папка -- Resources. // // Модуль Боя таблицу не видит: App/GameModules переводит её в BattleRules. // Сила воинов -- в GameData.Troops (рядом с ценой и временем обучения), здесь её нет. // Числа -- стартовые для тестирования (план от 27.10.2026), утверждает команда. [CreateAssetMenu(fileName = "BattleConfig", menuName = "Bogatyri/Battle Config")] public class BattleConfig : ScriptableObject { [Tooltip("Версия баланса боя. Поменял числа -- подними версию: итог боя запоминает, по какой версии посчитан")] public int version = 4; [Tooltip("Контра, %: пехота > кавалерия > лучники > пехота. Взвешивается по доле нужного типа у врага")] public int counterPercent = 25; [Tooltip("Стены, %: усиление защитников замка и городов")] public int wallsPercent = 20; [Tooltip("Осадные при штурме стен, %")] public int siegeVsWallsPercent = 50; [Tooltip("Осадные в поле и в обороне, % (минус)")] public int siegeInFieldPercent = -25; [Tooltip("Случайность каждой стороны: от -N% до +N%. 0 -- без случайности")] public int randomPercent = 5; [Header("Кривая потерь (решение №14, регламент 31.10, ТЕСТ)")] [Tooltip("Опорные точки соотношения сил (сильная / слабая) в десятых долях процента: 1000 = 1:1, 3000 = 3:1. Первая -- обязательно 1000, дальше по возрастанию")] public int[] lossRatioPermille = { 1000, 3000, 5000, 7000, 10000 }; [Tooltip("Доля выбывших у сильной стороны в каждой точке, десятые доли процента: 450 = 45%")] public int[] strongLossPermille = { 450, 160, 110, 74, 20 }; [Tooltip("Доля выбывших у слабой стороны в каждой точке, десятые доли процента: 740 = 74%")] public int[] weakLossPermille = { 450, 740, 880, 920, 950 }; [Tooltip("Разгром дальше последней точки: слабая сторона плавно стремится к этому пределу, десятые доли процента. Решения 31.10, п. 5: 990 = 99%")] public int weakLossMaxPermille = 990; [Header("Погибшие и раненые (регламент 31.10, решения 31.10, п. 7, ТЕСТ)")] [Tooltip("Соотношение сил стороны (своя / чужая) в десятых долях процента: 200 = 1:5, 1000 = 1:1, 3000 = 3:1. По возрастанию")] public int[] deadRatioPermille = { 200, 500, 1000, 3000 }; [Tooltip("Доля погибших среди выбывших в каждой точке, десятые доли процента: 700 = 70%. Остальные выбывшие -- раненые")] public int[] deadSharePermille = { 700, 450, 300, 200 }; [Tooltip("Пропавшие без вести (решения 01.11, п. 5): доля выбывших, десятые доли процента. НЕ УТВЕРЖДЕНА -- 0, механика выключена. Для проверки -- например 150 (15%)")] public int missingSharePermille = 0; [Tooltip("Голод: сколько силы остаётся, %. Утверждено 27.10.2026: -50% (остаётся 50). Проверяется на момент боя")] public int famineStrengthPercent = 50; [Tooltip("Усталость: сколько силы остаётся, %. Утверждено 27.10.2026: -20% (остаётся 80). Вместе с голодом -- 40%")] public int fatigueStrengthPercent = 80; static BattleConfig cached; public static BattleConfig Load() { if (cached != null) return cached; cached = Resources.Load("BattleConfig"); if (cached == null) { Debug.LogWarning("[БОЙ] Нет Assets/Resources/BattleConfig.asset -- берутся числа по умолчанию из BattleConfig.cs."); cached = CreateInstance(); } return cached; } // Правила для модуля Боя public BattleRules ToRules(int[] unitPower) { return new BattleRules { Version = version, UnitPower = unitPower, CounterPercent = counterPercent, WallsPercent = wallsPercent, SiegeVsWallsPercent = siegeVsWallsPercent, SiegeInFieldPercent = siegeInFieldPercent, LossRatioPermille = lossRatioPermille, StrongLossPermille = strongLossPermille, WeakLossPermille = weakLossPermille, WeakLossMaxPermille = weakLossMaxPermille, DeadRatioPermille = deadRatioPermille, DeadSharePermille = deadSharePermille, MissingSharePermille = Mathf.Clamp(missingSharePermille, 0, 1000), RandomPercent = Mathf.Max(0, randomPercent), FamineStrengthPercent = Mathf.Clamp(famineStrengthPercent, 0, 100), FatigueStrengthPercent = Mathf.Clamp(fatigueStrengthPercent, 0, 100) }; } }