Battle unit gauges extension point; battle action schemas
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
44462624cd
commit
d2f710a6a1
12 files changed
+231
No files matched your search
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = Start a battle
|
||||||
|
battle/schema/builtin/battle_init_desc = A battle from a novel scene: enemies, the return scene, a quest
|
||||||
|
battle/schema/field/enemies = Enemies
|
||||||
|
battle/schema/field/scene = Scene
|
||||||
|
battle/schema/field/quest = Quest
|
||||||
|
battle/schema/field/tag = Tag
|
||||||
|
battle/schema/builtin/set_core = Battle core
|
||||||
|
battle/schema/builtin/set_core_desc = Which rules the next battle follows
|
||||||
|
battle/schema/field/core = Core
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = Empezar un combate
|
||||||
|
battle/schema/builtin/battle_init_desc = Un combate desde una escena de novela: enemigos, escena de regreso, misión
|
||||||
|
battle/schema/field/enemies = Enemigos
|
||||||
|
battle/schema/field/scene = Escena
|
||||||
|
battle/schema/field/quest = Misión
|
||||||
|
battle/schema/field/tag = Etiqueta
|
||||||
|
battle/schema/builtin/set_core = Núcleo de combate
|
||||||
|
battle/schema/builtin/set_core_desc = Qué reglas sigue el próximo combate
|
||||||
|
battle/schema/field/core = Núcleo
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = 戦闘を始める
|
||||||
|
battle/schema/builtin/battle_init_desc = ノベルのシーンからの戦闘:敵、戻り先のシーン、クエスト
|
||||||
|
battle/schema/field/enemies = 敵
|
||||||
|
battle/schema/field/scene = シーン
|
||||||
|
battle/schema/field/quest = クエスト
|
||||||
|
battle/schema/field/tag = タグ
|
||||||
|
battle/schema/builtin/set_core = バトルコア
|
||||||
|
battle/schema/builtin/set_core_desc = 次の戦闘がどのルールに従うか
|
||||||
|
battle/schema/field/core = コア
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = 전투 시작
|
||||||
|
battle/schema/builtin/battle_init_desc = 노벨 장면에서의 전투: 적, 돌아올 장면, 퀘스트
|
||||||
|
battle/schema/field/enemies = 적
|
||||||
|
battle/schema/field/scene = 장면
|
||||||
|
battle/schema/field/quest = 퀘스트
|
||||||
|
battle/schema/field/tag = 태그
|
||||||
|
battle/schema/builtin/set_core = 전투 코어
|
||||||
|
battle/schema/builtin/set_core_desc = 다음 전투가 따를 규칙
|
||||||
|
battle/schema/field/core = 코어
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = Начать бой
|
||||||
|
battle/schema/builtin/battle_init_desc = Бой из сцены новеллы: враги, сцена возврата, квест
|
||||||
|
battle/schema/field/enemies = Враги
|
||||||
|
battle/schema/field/scene = Сцена
|
||||||
|
battle/schema/field/quest = Квест
|
||||||
|
battle/schema/field/tag = Метка
|
||||||
|
battle/schema/builtin/set_core = Боевое ядро
|
||||||
|
battle/schema/builtin/set_core_desc = Каким правилам подчиняется следующий бой
|
||||||
|
battle/schema/field/core = Ядро
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = Bắt đầu trận đấu
|
||||||
|
battle/schema/builtin/battle_init_desc = Trận đấu từ cảnh tiểu thuyết: kẻ địch, cảnh quay về, nhiệm vụ
|
||||||
|
battle/schema/field/enemies = Kẻ địch
|
||||||
|
battle/schema/field/scene = Cảnh
|
||||||
|
battle/schema/field/quest = Nhiệm vụ
|
||||||
|
battle/schema/field/tag = Thẻ
|
||||||
|
battle/schema/builtin/set_core = Lõi chiến đấu
|
||||||
|
battle/schema/builtin/set_core_desc = Trận tới theo luật nào
|
||||||
|
battle/schema/field/core = Lõi
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
battle/schema/builtin/battle_init = 开始战斗
|
||||||
|
battle/schema/builtin/battle_init_desc = 来自小说场景的战斗:敌人、返回场景、任务
|
||||||
|
battle/schema/field/enemies = 敌人
|
||||||
|
battle/schema/field/scene = 场景
|
||||||
|
battle/schema/field/quest = 任务
|
||||||
|
battle/schema/field/tag = 标签
|
||||||
|
battle/schema/builtin/set_core = 战斗核心
|
||||||
|
battle/schema/builtin/set_core_desc = 下一场战斗遵循哪套规则
|
||||||
|
battle/schema/field/core = 核心
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"Actions": [
|
||||||
|
{
|
||||||
|
"Id": "battle.init",
|
||||||
|
"Name": "battle/schema/builtin/battle_init",
|
||||||
|
"Description": "battle/schema/builtin/battle_init_desc",
|
||||||
|
"Category": "battle",
|
||||||
|
"Params": [
|
||||||
|
{
|
||||||
|
"Key": "enemies",
|
||||||
|
"Type": "ref_list",
|
||||||
|
"Kind": "character",
|
||||||
|
"Required": true,
|
||||||
|
"Name": "battle/schema/field/enemies"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Key": "scene",
|
||||||
|
"Type": "scene",
|
||||||
|
"Name": "battle/schema/field/scene"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Key": "quest_id",
|
||||||
|
"Type": "ref",
|
||||||
|
"Kind": "quest",
|
||||||
|
"Name": "battle/schema/field/quest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Key": "new_tag",
|
||||||
|
"Type": "text",
|
||||||
|
"Name": "battle/schema/field/tag"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "battle.set_core",
|
||||||
|
"Name": "battle/schema/builtin/set_core",
|
||||||
|
"Description": "battle/schema/builtin/set_core_desc",
|
||||||
|
"Category": "battle",
|
||||||
|
"Params": [
|
||||||
|
{
|
||||||
|
"Key": "core",
|
||||||
|
"Type": "choice",
|
||||||
|
"Options": [
|
||||||
|
"ff_battle",
|
||||||
|
"card_battle"
|
||||||
|
],
|
||||||
|
"Required": true,
|
||||||
|
"Name": "battle/schema/field/core"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Cthangover.Core.Battle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// One extra bar of a battle unit next to its health (mana, rage, ammo…), as an
|
||||||
|
/// <see cref="IBattleUnitGauge"/> reads it at this moment.
|
||||||
|
/// </summary>
|
||||||
|
public class BattleGauge
|
||||||
|
{
|
||||||
|
/// <summary>Stable id (a stat id, for example) the cores key their rows by.</summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Short label, a locale key or plain text ("MP").</summary>
|
||||||
|
public string Label { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Current value.</summary>
|
||||||
|
public int Current { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Maximum; a bar with Max <= 0 is not drawn.</summary>
|
||||||
|
public int Max { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Fill colour as HTML ("#4a8cff"); null = the theme's info colour.</summary>
|
||||||
|
public string Color { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Cthangover.Core.Battle
|
||||||
|
{
|
||||||
|
using Cthangover.Core.Mods.Consumers;
|
||||||
|
|
||||||
|
/// <summary>Registers every <see cref="IBattleUnitGauge"/> of a loaded mod assembly in <see cref="BattleUnitGauges"/>.</summary>
|
||||||
|
public class BattleUnitGaugeConsumer : ModTypeConsumer<IBattleUnitGauge>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Id => "turn_battle_base.unit_gauges";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Add(IBattleUnitGauge instance, string modId) => BattleUnitGauges.Add(instance);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Remove(IBattleUnitGauge instance, string modId) => BattleUnitGauges.Remove(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
namespace Cthangover.Core.Battle
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Cthangover.Core.Characters;
|
||||||
|
using Cthangover.Core.Utils;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The registered <see cref="IBattleUnitGauge"/>s and the bars they give for a unit. A
|
||||||
|
/// provider calls <see cref="NotifyChanged"/> when a value moved (mana spent), so the
|
||||||
|
/// cores redraw that unit; cores also read the bars whenever they redraw it themselves.
|
||||||
|
/// </summary>
|
||||||
|
public static class BattleUnitGauges
|
||||||
|
{
|
||||||
|
private static readonly List<IBattleUnitGauge> Providers = new();
|
||||||
|
|
||||||
|
/// <summary>Raised with a unit id (null = every unit) when its bars changed.</summary>
|
||||||
|
public static event Action<string> Changed;
|
||||||
|
|
||||||
|
/// <summary>Registers a provider.</summary>
|
||||||
|
public static void Add(IBattleUnitGauge gauge)
|
||||||
|
{
|
||||||
|
if (gauge != null && !Providers.Contains(gauge))
|
||||||
|
Providers.Add(gauge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Removes a provider (its mod is unloaded).</summary>
|
||||||
|
public static void Remove(IBattleUnitGauge gauge) => Providers.Remove(gauge);
|
||||||
|
|
||||||
|
/// <summary>Every bar of <paramref name="unit"/> with a positive maximum, providers in order; a failing provider is logged and skipped.</summary>
|
||||||
|
public static List<BattleGauge> Read(Character unit)
|
||||||
|
{
|
||||||
|
var result = new List<BattleGauge>();
|
||||||
|
if (unit == null)
|
||||||
|
return result;
|
||||||
|
foreach (var provider in Providers.OrderBy(p => p.Order).ToList())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result.AddRange((provider.Read(unit) ?? Enumerable.Empty<BattleGauge>()).Where(g => g != null && g.Max > 0));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
GameLogger.Log("BATTLE", $"gauge provider {provider.GetType().Name} failed for '{unit.ID}': {ex.Message}", LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Tells the cores that the bars of <paramref name="unitId"/> changed.</summary>
|
||||||
|
public static void NotifyChanged(string unitId) => Changed?.Invoke(unitId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
namespace Cthangover.Core.Battle
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Cthangover.Core.Characters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Supplies extra bars of battle units (found in mod assemblies by
|
||||||
|
/// <see cref="BattleUnitGaugeConsumer"/>): a mod that adds a resource — mana of
|
||||||
|
/// <c>battle_formulas</c>, a rage meter — shows it in every battle core that draws
|
||||||
|
/// <see cref="BattleUnitGauges"/>, without knowing the cores.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBattleUnitGauge
|
||||||
|
{
|
||||||
|
/// <summary>Order among the providers (lower first).</summary>
|
||||||
|
int Order { get; }
|
||||||
|
|
||||||
|
/// <summary>The bars of <paramref name="unit"/> now; empty when it has none.</summary>
|
||||||
|
IEnumerable<BattleGauge> Read(Character unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user