План от 27.10.2026, раздел «Армии и восстановление»: - BattleCondition (флаги Famine, Fatigue); BattleRequest.AttackerConditions / DefenderConditions - голод −50%, усталость −20%, применяются последовательно: вместе 40% силы - порядок: контры и осадные → бонусы → состояния → случайность - числа в BattleConfig (famineStrengthPercent, fatigueStrengthPercent) и BattleRules, версия правил 2 - BattleOutcome.AttackerConditionPercent / DefenderConditionPercent Мир: - голод проверяется на момент боя: WorldSimulation.AttackerConditions спрашивает MarchManager, тот берёт IPopulation.IsStarving - бой в офлайне получает голод на момент входа в игру (истории голода у Населения нет) — записано в Battle.md Интерфейс карты: - окно атаки: «Голод: войско слабее, сила 50%. Накормите город до боя», прогноз учитывает голод - окно итога боя: «голод: сила 50%» Усталость пока никто не выставляет: не утверждено, как смешивать свежие и уставшие войска. Тесты: штрафы и их сложение, голод переворачивает бой у нападающего и у защитника, прогноз с голодом, голод в момент боя у похода. Все 39 тестов ModuleTests проходят вне Unity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
3.8 KiB
C#
68 lines
3.8 KiB
C#
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 = 2;
|
|
|
|
[Tooltip("Контра, %: пехота > кавалерия > лучники > пехота. Взвешивается по доле нужного типа у врага")]
|
|
public int counterPercent = 25;
|
|
[Tooltip("Стены, %: усиление защитников замка и городов")]
|
|
public int wallsPercent = 20;
|
|
[Tooltip("Осадные при штурме стен, %")]
|
|
public int siegeVsWallsPercent = 50;
|
|
[Tooltip("Осадные в поле и в обороне, % (минус)")]
|
|
public int siegeInFieldPercent = -25;
|
|
[Tooltip("Потери проигравшего, % от каждого типа. Не окончательная формула")]
|
|
public int loserLossPercent = 50;
|
|
[Tooltip("Случайность каждой стороны: от -N% до +N%. 0 -- без случайности")]
|
|
public int randomPercent = 5;
|
|
|
|
[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>("BattleConfig");
|
|
if (cached == null)
|
|
{
|
|
Debug.LogWarning("[БОЙ] Нет Assets/Resources/BattleConfig.asset -- берутся числа по умолчанию из BattleConfig.cs.");
|
|
cached = CreateInstance<BattleConfig>();
|
|
}
|
|
return cached;
|
|
}
|
|
|
|
// Правила для модуля Боя
|
|
public BattleRules ToRules(int[] unitPower)
|
|
{
|
|
return new BattleRules
|
|
{
|
|
Version = version,
|
|
UnitPower = unitPower,
|
|
CounterPercent = counterPercent,
|
|
WallsPercent = wallsPercent,
|
|
SiegeVsWallsPercent = siegeVsWallsPercent,
|
|
SiegeInFieldPercent = siegeInFieldPercent,
|
|
LoserLossPercent = loserLossPercent,
|
|
RandomPercent = Mathf.Max(0, randomPercent),
|
|
FamineStrengthPercent = Mathf.Clamp(famineStrengthPercent, 0, 100),
|
|
FatigueStrengthPercent = Mathf.Clamp(fatigueStrengthPercent, 0, 100)
|
|
};
|
|
}
|
|
}
|