M0 回合制战斗壳层:接口与单局状态、调试入口、暂停联动
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using SepCore.Definition;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个效果对单个目标产生的数值或状态变化。
|
||||
/// </summary>
|
||||
public sealed class BattleActionEffectRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标单位。
|
||||
/// </summary>
|
||||
public readonly int TargetUnitId;
|
||||
|
||||
/// <summary>
|
||||
/// 效果结算前的 HP。
|
||||
/// </summary>
|
||||
public readonly int BeforeHp;
|
||||
|
||||
/// <summary>
|
||||
/// 效果结算后的 HP。
|
||||
/// </summary>
|
||||
public readonly int AfterHp;
|
||||
|
||||
/// <summary>
|
||||
/// 效果结算前的 MP。
|
||||
/// </summary>
|
||||
public readonly int BeforeMp;
|
||||
|
||||
/// <summary>
|
||||
/// 效果结算后的 MP。
|
||||
/// </summary>
|
||||
public readonly int AfterMp;
|
||||
|
||||
/// <summary>
|
||||
/// 状态变化列表;无状态变化时为空。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattleStatusChangeRecord> StatusChanges;
|
||||
|
||||
public BattleActionEffectRecord(int targetUnitId, int beforeHp, int afterHp, int beforeMp, int afterMp,
|
||||
IReadOnlyList<BattleStatusChangeRecord> statusChanges)
|
||||
{
|
||||
TargetUnitId = targetUnitId;
|
||||
BeforeHp = beforeHp;
|
||||
AfterHp = afterHp;
|
||||
BeforeMp = beforeMp;
|
||||
AfterMp = afterMp;
|
||||
StatusChanges = statusChanges != null ? Copy(statusChanges) : new BattleStatusChangeRecord[0];
|
||||
}
|
||||
|
||||
private static BattleStatusChangeRecord[] Copy(IReadOnlyList<BattleStatusChangeRecord> source)
|
||||
{
|
||||
BattleStatusChangeRecord[] copy = new BattleStatusChangeRecord[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态变化记录。
|
||||
/// </summary>
|
||||
public sealed class BattleStatusChangeRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态类型。
|
||||
/// </summary>
|
||||
public readonly BattleStatusType StatusType;
|
||||
|
||||
/// <summary>
|
||||
/// 变化后的剩余持续次数;状态被移除时为 0。
|
||||
/// </summary>
|
||||
public readonly int RemainingRounds;
|
||||
|
||||
public BattleStatusChangeRecord(BattleStatusType statusType, int remainingRounds)
|
||||
{
|
||||
StatusType = statusType;
|
||||
RemainingRounds = remainingRounds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一次行动产生的有序行动记录。
|
||||
/// 首版 UI 立即消费并显示;未来动画系统可以逐条等待播放,不需要修改战斗规则内核。
|
||||
/// </summary>
|
||||
public sealed class BattleActionRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 行动者。
|
||||
/// </summary>
|
||||
public readonly int ActorUnitId;
|
||||
|
||||
/// <summary>
|
||||
/// 指令类型,对应配表 BattleActionType。
|
||||
/// </summary>
|
||||
public readonly BattleActionType CommandType;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击或技能配置 ID;逃跑为 0。
|
||||
/// </summary>
|
||||
public readonly int ActionConfigId;
|
||||
|
||||
/// <summary>
|
||||
/// 按结算顺序排列的效果记录。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattleActionEffectRecord> Effects;
|
||||
|
||||
public BattleActionRecord(int actorUnitId, BattleActionType commandType, int actionConfigId,
|
||||
IReadOnlyList<BattleActionEffectRecord> effects)
|
||||
{
|
||||
ActorUnitId = actorUnitId;
|
||||
CommandType = commandType;
|
||||
ActionConfigId = actionConfigId;
|
||||
Effects = effects != null ? Copy(effects) : new BattleActionEffectRecord[0];
|
||||
}
|
||||
|
||||
private static BattleActionEffectRecord[] Copy(IReadOnlyList<BattleActionEffectRecord> source)
|
||||
{
|
||||
BattleActionEffectRecord[] copy = new BattleActionEffectRecord[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 战斗推进返回值。
|
||||
/// </summary>
|
||||
public sealed class BattleAdvance
|
||||
{
|
||||
/// <summary>
|
||||
/// 本次推进产生的有序行动记录列表。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattleActionRecord> Records;
|
||||
|
||||
/// <summary>
|
||||
/// 推进结束后的只读战斗快照。
|
||||
/// </summary>
|
||||
public readonly BattleSnapshot Snapshot;
|
||||
|
||||
/// <summary>
|
||||
/// 流程状态。
|
||||
/// </summary>
|
||||
public readonly BattleFlowState FlowState;
|
||||
|
||||
/// <summary>
|
||||
/// 仅在 Completed 时存在,否则为 null。
|
||||
/// </summary>
|
||||
public readonly BattleResult Result;
|
||||
|
||||
public BattleAdvance(IReadOnlyList<BattleActionRecord> records, BattleSnapshot snapshot,
|
||||
BattleFlowState flowState, BattleResult result)
|
||||
{
|
||||
Records = records != null ? Copy(records) : new BattleActionRecord[0];
|
||||
Snapshot = snapshot;
|
||||
FlowState = flowState;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
private static BattleActionRecord[] Copy(IReadOnlyList<BattleActionRecord> source)
|
||||
{
|
||||
BattleActionRecord[] copy = new BattleActionRecord[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84f740882a72430ca27c4d77004257d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using SepCore.Definition;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家指令。
|
||||
/// 非法指令(错误行动者、错误阵营、错误目标数量、阵亡或逃跑目标)不得消耗 MP、行动机会或随机数。
|
||||
/// </summary>
|
||||
public sealed class BattleCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前获得行动机会的玩家单位。
|
||||
/// </summary>
|
||||
public readonly int ActorUnitId;
|
||||
|
||||
/// <summary>
|
||||
/// 指令类型,对应配表 BattleActionType。
|
||||
/// </summary>
|
||||
public readonly BattleActionType CommandType;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击或技能对应的配置 ID;逃跑为 0。
|
||||
/// </summary>
|
||||
public readonly int ActionConfigId;
|
||||
|
||||
/// <summary>
|
||||
/// 按目标类型解析后的唯一运行时目标列表。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<int> TargetUnitIds;
|
||||
|
||||
public BattleCommand(int actorUnitId, BattleActionType commandType, int actionConfigId,
|
||||
IReadOnlyList<int> targetUnitIds)
|
||||
{
|
||||
ActorUnitId = actorUnitId;
|
||||
CommandType = commandType;
|
||||
ActionConfigId = actionConfigId;
|
||||
TargetUnitIds = targetUnitIds != null ? Copy(targetUnitIds) : new int[0];
|
||||
}
|
||||
|
||||
private static int[] Copy(IReadOnlyList<int> source)
|
||||
{
|
||||
int[] copy = new int[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce89addfe88643eda73478128e385d5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 遭遇输入,由探索层在碰撞发生时创建。
|
||||
/// 地图坐标、碰撞器、GameObject 和警惕组件不进入战斗请求,由探索层继续持有。
|
||||
/// </summary>
|
||||
public sealed class BattleEncounter
|
||||
{
|
||||
/// <summary>
|
||||
/// 触发碰撞的地图敌人实例的单局唯一标识;不能使用敌人配置 ID 代替。
|
||||
/// </summary>
|
||||
public readonly int EncounterId;
|
||||
|
||||
/// <summary>
|
||||
/// 该地图敌人代表的敌人队伍预设 ID。
|
||||
/// </summary>
|
||||
public readonly int EnemyPartyConfigId;
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞时敌人警惕值未满为 true,否则为 false。
|
||||
/// </summary>
|
||||
public readonly bool IsPreemptive;
|
||||
|
||||
public BattleEncounter(int encounterId, int enemyPartyConfigId, bool isPreemptive)
|
||||
{
|
||||
EncounterId = encounterId;
|
||||
EnemyPartyConfigId = enemyPartyConfigId;
|
||||
IsPreemptive = isPreemptive;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42d8ce9387864e68a141ace8c990f06f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 战斗单位阵营。
|
||||
/// </summary>
|
||||
public enum BattleFaction
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家阵营。
|
||||
/// </summary>
|
||||
Player,
|
||||
|
||||
/// <summary>
|
||||
/// 敌人阵营。
|
||||
/// </summary>
|
||||
Enemy,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d809efd802bf499c8237b00546a35c15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 战斗流程状态。
|
||||
/// </summary>
|
||||
public enum BattleFlowState
|
||||
{
|
||||
/// <summary>
|
||||
/// 等待当前玩家行动者提交指令。
|
||||
/// </summary>
|
||||
AwaitingPlayerCommand,
|
||||
|
||||
/// <summary>
|
||||
/// 战斗完成,结果已产出。
|
||||
/// </summary>
|
||||
Completed,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bef66af163534a79b4b14ba27ed80665
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 战斗结束结果,四种结果互斥。
|
||||
/// </summary>
|
||||
public enum BattleOutcome
|
||||
{
|
||||
/// <summary>
|
||||
/// 所有敌人阵亡。
|
||||
/// </summary>
|
||||
Victory,
|
||||
|
||||
/// <summary>
|
||||
/// 所有玩家成功逃跑,且没有玩家阵亡。
|
||||
/// </summary>
|
||||
AllEscaped,
|
||||
|
||||
/// <summary>
|
||||
/// 至少一名玩家逃跑,其余仍在战斗中的玩家全部阵亡。
|
||||
/// </summary>
|
||||
PartialEscapeDefeat,
|
||||
|
||||
/// <summary>
|
||||
/// 所有玩家阵亡,没有任何玩家成功逃跑。
|
||||
/// </summary>
|
||||
TotalDefeat,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56279ec78df04139b731da9dd07e7f14
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家输入快照,是进入本场战斗时的值快照。
|
||||
/// 装备计算由单局角色快照构建器完成;战斗内核不读取角色存档、装备栏或背包。
|
||||
/// </summary>
|
||||
public sealed class BattlePlayerInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色配置标识;同时用于把结果回写到单局角色状态。
|
||||
/// </summary>
|
||||
public readonly int CharacterId;
|
||||
|
||||
/// <summary>
|
||||
/// 当前战备中的顺序。
|
||||
/// </summary>
|
||||
public readonly int PartyOrder;
|
||||
|
||||
/// <summary>
|
||||
/// 单局临时状态中的当前 HP。
|
||||
/// </summary>
|
||||
public readonly int CurrentHp;
|
||||
|
||||
/// <summary>
|
||||
/// 单局临时状态中的当前 MP。
|
||||
/// </summary>
|
||||
public readonly int CurrentMp;
|
||||
|
||||
/// <summary>
|
||||
/// 已结算装备加成的最终 HP 上限。
|
||||
/// </summary>
|
||||
public readonly int MaxHp;
|
||||
|
||||
/// <summary>
|
||||
/// 已结算装备加成的最终 MP 上限。
|
||||
/// </summary>
|
||||
public readonly int MaxMp;
|
||||
|
||||
/// <summary>
|
||||
/// 已结算装备加成的最终攻击。
|
||||
/// </summary>
|
||||
public readonly int Atk;
|
||||
|
||||
/// <summary>
|
||||
/// 已结算装备加成的最终魔力。
|
||||
/// </summary>
|
||||
public readonly int Mat;
|
||||
|
||||
/// <summary>
|
||||
/// 已结算装备加成的最终速度。
|
||||
/// </summary>
|
||||
public readonly int Speed;
|
||||
|
||||
/// <summary>
|
||||
/// 普通攻击行动配置 ID。
|
||||
/// </summary>
|
||||
public readonly int AttackActionId;
|
||||
|
||||
/// <summary>
|
||||
/// 该角色首版唯一技能行动配置 ID。
|
||||
/// </summary>
|
||||
public readonly int SkillActionId;
|
||||
|
||||
public BattlePlayerInput(int characterId, int partyOrder, int currentHp, int currentMp,
|
||||
int maxHp, int maxMp, int atk, int mat, int speed, int attackActionId, int skillActionId)
|
||||
{
|
||||
CharacterId = characterId;
|
||||
PartyOrder = partyOrder;
|
||||
CurrentHp = currentHp;
|
||||
CurrentMp = currentMp;
|
||||
MaxHp = maxHp;
|
||||
MaxMp = maxMp;
|
||||
Atk = atk;
|
||||
Mat = mat;
|
||||
Speed = speed;
|
||||
AttackActionId = attackActionId;
|
||||
SkillActionId = skillActionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c518c47a9854ba19045abd1f211eb7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 每名参战玩家的战后结果。
|
||||
/// 保留原始战斗值:阵亡者 HP 为 0;恢复 1/1 的规则由 RunBattleCoordinator 统一应用。
|
||||
/// </summary>
|
||||
public sealed class BattlePlayerResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色配置标识。
|
||||
/// </summary>
|
||||
public readonly int CharacterId;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗结束时的当前 HP。
|
||||
/// </summary>
|
||||
public readonly int CurrentHp;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗结束时的当前 MP。
|
||||
/// </summary>
|
||||
public readonly int CurrentMp;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在本场战斗中阵亡。
|
||||
/// </summary>
|
||||
public readonly bool WasDefeated;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在本场战斗中成功逃跑。
|
||||
/// </summary>
|
||||
public readonly bool Escaped;
|
||||
|
||||
public BattlePlayerResult(int characterId, int currentHp, int currentMp, bool wasDefeated, bool escaped)
|
||||
{
|
||||
CharacterId = characterId;
|
||||
CurrentHp = currentHp;
|
||||
CurrentMp = currentMp;
|
||||
WasDefeated = wasDefeated;
|
||||
Escaped = escaped;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 战斗结果。
|
||||
/// </summary>
|
||||
public sealed class BattleResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 关联原地图敌人实例。
|
||||
/// </summary>
|
||||
public readonly int EncounterId;
|
||||
|
||||
/// <summary>
|
||||
/// 四种战斗结果之一。
|
||||
/// </summary>
|
||||
public readonly BattleOutcome Outcome;
|
||||
|
||||
/// <summary>
|
||||
/// 每名参战玩家的原始战后结果。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattlePlayerResult> Players;
|
||||
|
||||
public BattleResult(int encounterId, BattleOutcome outcome, IReadOnlyList<BattlePlayerResult> players)
|
||||
{
|
||||
EncounterId = encounterId;
|
||||
Outcome = outcome;
|
||||
Players = players != null ? Copy(players) : new BattlePlayerResult[0];
|
||||
}
|
||||
|
||||
private static BattlePlayerResult[] Copy(IReadOnlyList<BattlePlayerResult> source)
|
||||
{
|
||||
BattlePlayerResult[] copy = new BattlePlayerResult[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da5169df3c26408ba2b665960f5632fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 探索恢复计划,由 RunBattleCoordinator 根据战斗结果统一生成,探索层只执行计划。
|
||||
/// 探索层不得再次根据玩家 HP 或逃跑数量重判战斗结果。
|
||||
/// </summary>
|
||||
public sealed class BattleReturnPlan
|
||||
{
|
||||
/// <summary>
|
||||
/// 关联原地图敌人实例。
|
||||
/// </summary>
|
||||
public readonly int EncounterId;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗结果。
|
||||
/// </summary>
|
||||
public readonly BattleOutcome Outcome;
|
||||
|
||||
/// <summary>
|
||||
/// 回写后的玩家临时状态(含 1/1 恢复规则应用后的结果)。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattlePlayerResult> Players;
|
||||
|
||||
/// <summary>
|
||||
/// 是否移除触发敌人(胜利)。
|
||||
/// </summary>
|
||||
public readonly bool RemoveEncounterEnemy;
|
||||
|
||||
/// <summary>
|
||||
/// 是否保留并恢复触发敌人,下次按完整预设重建(逃跑类结果)。
|
||||
/// </summary>
|
||||
public readonly bool ResetEncounterEnemy;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用本局随机源结算掉落(胜利)。
|
||||
/// </summary>
|
||||
public readonly bool ShouldRollDrops;
|
||||
|
||||
/// <summary>
|
||||
/// 逃跑类结果的保护时间(毫秒);其他结果为 0。
|
||||
/// </summary>
|
||||
public readonly int ProtectionMs;
|
||||
|
||||
/// <summary>
|
||||
/// 是否恢复探索更新。
|
||||
/// </summary>
|
||||
public readonly bool ShouldResumeExploration;
|
||||
|
||||
/// <summary>
|
||||
/// 是否以单局失败结束,不返回探索。
|
||||
/// </summary>
|
||||
public readonly bool EndsRunAsDefeated;
|
||||
|
||||
public BattleReturnPlan(int encounterId, BattleOutcome outcome,
|
||||
IReadOnlyList<BattlePlayerResult> players, bool removeEncounterEnemy, bool resetEncounterEnemy,
|
||||
bool shouldRollDrops, int protectionMs, bool shouldResumeExploration, bool endsRunAsDefeated)
|
||||
{
|
||||
EncounterId = encounterId;
|
||||
Outcome = outcome;
|
||||
Players = players != null ? Copy(players) : new BattlePlayerResult[0];
|
||||
RemoveEncounterEnemy = removeEncounterEnemy;
|
||||
ResetEncounterEnemy = resetEncounterEnemy;
|
||||
ShouldRollDrops = shouldRollDrops;
|
||||
ProtectionMs = protectionMs;
|
||||
ShouldResumeExploration = shouldResumeExploration;
|
||||
EndsRunAsDefeated = endsRunAsDefeated;
|
||||
}
|
||||
|
||||
private static BattlePlayerResult[] Copy(IReadOnlyList<BattlePlayerResult> source)
|
||||
{
|
||||
BattlePlayerResult[] copy = new BattlePlayerResult[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec4ca0d279034f4a939fd35aedab383e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,223 @@
|
||||
using System.Collections.Generic;
|
||||
using SepCore.Definition;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 单位剩余状态快照。
|
||||
/// </summary>
|
||||
public sealed class BattleStatusSnapshot
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态类型。
|
||||
/// </summary>
|
||||
public readonly BattleStatusType StatusType;
|
||||
|
||||
/// <summary>
|
||||
/// 剩余持续次数(行动机会);重复施加取较大值,移除后为 0。
|
||||
/// </summary>
|
||||
public readonly int RemainingRounds;
|
||||
|
||||
public BattleStatusSnapshot(BattleStatusType statusType, int remainingRounds)
|
||||
{
|
||||
StatusType = statusType;
|
||||
RemainingRounds = remainingRounds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单个战斗单位的只读视图。
|
||||
/// </summary>
|
||||
public sealed class BattleUnitSnapshot
|
||||
{
|
||||
/// <summary>
|
||||
/// 本场战斗单位的唯一运行时标识;重复配置的敌人拥有不同 ID。
|
||||
/// </summary>
|
||||
public readonly int BattleUnitId;
|
||||
|
||||
/// <summary>
|
||||
/// 阵营。
|
||||
/// </summary>
|
||||
public readonly BattleFaction Faction;
|
||||
|
||||
/// <summary>
|
||||
/// 配置标识:玩家为 CharacterId,敌人为 EnemyConfigId。
|
||||
/// </summary>
|
||||
public readonly int ConfigId;
|
||||
|
||||
/// <summary>
|
||||
/// 同阵营同速度的最终并列规则顺序。
|
||||
/// </summary>
|
||||
public readonly int PartyOrder;
|
||||
|
||||
/// <summary>
|
||||
/// 当前 HP。
|
||||
/// </summary>
|
||||
public readonly int CurrentHp;
|
||||
|
||||
/// <summary>
|
||||
/// HP 上限。
|
||||
/// </summary>
|
||||
public readonly int MaxHp;
|
||||
|
||||
/// <summary>
|
||||
/// 当前 MP。
|
||||
/// </summary>
|
||||
public readonly int CurrentMp;
|
||||
|
||||
/// <summary>
|
||||
/// MP 上限。
|
||||
/// </summary>
|
||||
public readonly int MaxMp;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击。
|
||||
/// </summary>
|
||||
public readonly int Atk;
|
||||
|
||||
/// <summary>
|
||||
/// 魔力。
|
||||
/// </summary>
|
||||
public readonly int Mat;
|
||||
|
||||
/// <summary>
|
||||
/// 当前速度。
|
||||
/// </summary>
|
||||
public readonly int Speed;
|
||||
|
||||
/// <summary>
|
||||
/// 是否阵亡。
|
||||
/// </summary>
|
||||
public readonly bool IsDefeated;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已逃跑。
|
||||
/// </summary>
|
||||
public readonly bool IsEscaped;
|
||||
|
||||
/// <summary>
|
||||
/// 剩余状态列表。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattleStatusSnapshot> Statuses;
|
||||
|
||||
/// <summary>
|
||||
/// 可用行动配置 ID 列表。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<int> AvailableActionIds;
|
||||
|
||||
public BattleUnitSnapshot(int battleUnitId, BattleFaction faction, int configId, int partyOrder,
|
||||
int currentHp, int maxHp, int currentMp, int maxMp, int atk, int mat, int speed,
|
||||
bool isDefeated, bool isEscaped, IReadOnlyList<BattleStatusSnapshot> statuses,
|
||||
IReadOnlyList<int> availableActionIds)
|
||||
{
|
||||
BattleUnitId = battleUnitId;
|
||||
Faction = faction;
|
||||
ConfigId = configId;
|
||||
PartyOrder = partyOrder;
|
||||
CurrentHp = currentHp;
|
||||
MaxHp = maxHp;
|
||||
CurrentMp = currentMp;
|
||||
MaxMp = maxMp;
|
||||
Atk = atk;
|
||||
Mat = mat;
|
||||
Speed = speed;
|
||||
IsDefeated = isDefeated;
|
||||
IsEscaped = isEscaped;
|
||||
Statuses = statuses != null ? Copy(statuses) : new BattleStatusSnapshot[0];
|
||||
AvailableActionIds = availableActionIds != null ? Copy(availableActionIds) : new int[0];
|
||||
}
|
||||
|
||||
private static BattleStatusSnapshot[] Copy(IReadOnlyList<BattleStatusSnapshot> source)
|
||||
{
|
||||
BattleStatusSnapshot[] copy = new BattleStatusSnapshot[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
private static int[] Copy(IReadOnlyList<int> source)
|
||||
{
|
||||
int[] copy = new int[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只读战斗快照,是 UI 和敌人策略唯一允许读取的战斗状态。
|
||||
/// 每次推进都创建逻辑上的只读快照,不把可修改的内部列表或战斗单位引用暴露给调用方。
|
||||
/// </summary>
|
||||
public sealed class BattleSnapshot
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前轮次,从 1 开始。
|
||||
/// </summary>
|
||||
public readonly int RoundNumber;
|
||||
|
||||
/// <summary>
|
||||
/// 当前是否为先制战斗第一轮。
|
||||
/// </summary>
|
||||
public readonly bool IsPreemptiveRound;
|
||||
|
||||
/// <summary>
|
||||
/// 当前行动者;战斗完成时为 0。
|
||||
/// </summary>
|
||||
public readonly int CurrentActorUnitId;
|
||||
|
||||
/// <summary>
|
||||
/// 全部单位的只读视图,保持稳定显示顺序。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattleUnitSnapshot> Units;
|
||||
|
||||
/// <summary>
|
||||
/// 本轮从当前行动者开始的剩余运行时单位 ID;速度变化后重建。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<int> RemainingTurnOrder;
|
||||
|
||||
/// <summary>
|
||||
/// 流程状态。
|
||||
/// </summary>
|
||||
public readonly BattleFlowState FlowState;
|
||||
|
||||
public BattleSnapshot(int roundNumber, bool isPreemptiveRound, int currentActorUnitId,
|
||||
IReadOnlyList<BattleUnitSnapshot> units, IReadOnlyList<int> remainingTurnOrder,
|
||||
BattleFlowState flowState)
|
||||
{
|
||||
RoundNumber = roundNumber;
|
||||
IsPreemptiveRound = isPreemptiveRound;
|
||||
CurrentActorUnitId = currentActorUnitId;
|
||||
Units = units != null ? Copy(units) : new BattleUnitSnapshot[0];
|
||||
RemainingTurnOrder = remainingTurnOrder != null ? Copy(remainingTurnOrder) : new int[0];
|
||||
FlowState = flowState;
|
||||
}
|
||||
|
||||
private static BattleUnitSnapshot[] Copy(IReadOnlyList<BattleUnitSnapshot> source)
|
||||
{
|
||||
BattleUnitSnapshot[] copy = new BattleUnitSnapshot[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
private static int[] Copy(IReadOnlyList<int> source)
|
||||
{
|
||||
int[] copy = new int[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5bfa0a211d34ba6874d7d0b276192a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using SepCore.CustomComponent;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 战斗启动请求,创建后视为只读。
|
||||
/// 战斗开始失败时不得消耗随机数、修改单局状态或暂停状态计数。
|
||||
/// </summary>
|
||||
public sealed class BattleStartRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于将结果关联回地图敌人实例。
|
||||
/// </summary>
|
||||
public readonly int EncounterId;
|
||||
|
||||
/// <summary>
|
||||
/// 1 到 4 个玩家输入,保持战备顺序。
|
||||
/// </summary>
|
||||
public readonly IReadOnlyList<BattlePlayerInput> Players;
|
||||
|
||||
/// <summary>
|
||||
/// 用于按队伍预设创建 1 到 4 个敌人运行时单位。
|
||||
/// </summary>
|
||||
public readonly int EnemyPartyConfigId;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用第一轮玩家先制。
|
||||
/// </summary>
|
||||
public readonly bool IsPreemptive;
|
||||
|
||||
/// <summary>
|
||||
/// 当前单局唯一的随机源实例,来自 RandomComponent,不创建战斗私有随机源。
|
||||
/// </summary>
|
||||
public readonly IRunRandomSource Random;
|
||||
|
||||
public BattleStartRequest(int encounterId, IReadOnlyList<BattlePlayerInput> players,
|
||||
int enemyPartyConfigId, bool isPreemptive, IRunRandomSource random)
|
||||
{
|
||||
EncounterId = encounterId;
|
||||
Players = players != null ? Copy(players) : new BattlePlayerInput[0];
|
||||
EnemyPartyConfigId = enemyPartyConfigId;
|
||||
IsPreemptive = isPreemptive;
|
||||
Random = random;
|
||||
}
|
||||
|
||||
private static BattlePlayerInput[] Copy(IReadOnlyList<BattlePlayerInput> source)
|
||||
{
|
||||
BattlePlayerInput[] copy = new BattlePlayerInput[source.Count];
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 040ffec92b064e3fbd9d9a8db9b39291
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using SepCore.Definition;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 战斗配置访问接口,隔离 BattleSession 与 GameEntry.Luban。
|
||||
/// 运行时适配器读取现有 Luban 表,测试使用内存配置。
|
||||
/// 配置缺失属于战斗启动失败,不允许用零值单位继续战斗。
|
||||
/// </summary>
|
||||
public interface IBattleConfigProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 按 ID 获取敌人队伍预设。
|
||||
/// </summary>
|
||||
EnemyPartyConfig GetEnemyParty(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 按 ID 获取敌人配置。
|
||||
/// </summary>
|
||||
EnemyConfig GetEnemy(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 按 ID 获取行动配置。
|
||||
/// </summary>
|
||||
BattleActionConfig GetAction(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 获取全局配置。
|
||||
/// </summary>
|
||||
GlobalConfig GetGlobal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf1d3721d95a45a0a88d81baae7ec0f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using SepCore.CustomComponent;
|
||||
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 敌人策略接口。
|
||||
/// 策略只读取快照并返回指令,不直接修改 BattleSession。
|
||||
/// 当前没有可执行行动时,本次行动机会记为跳过,不能形成无限循环。
|
||||
/// </summary>
|
||||
public interface IEnemyBattlePolicy
|
||||
{
|
||||
/// <summary>
|
||||
/// 为当前敌人行动者决定指令。
|
||||
/// </summary>
|
||||
/// <param name="snapshot">只读战斗快照。</param>
|
||||
/// <param name="actorUnitId">当前获得行动机会的敌人单位。</param>
|
||||
/// <param name="random">本局共享随机源。</param>
|
||||
BattleCommand Decide(BattleSnapshot snapshot, int actorUnitId, IRunRandomSource random);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e803cf69950a4fb9b0b8d63603f99a4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace SepCore.Battle
|
||||
{
|
||||
/// <summary>
|
||||
/// 探索层恢复接口。
|
||||
/// 碰撞方主动把 BattleEncounter 交给 RunBattleCoordinator;协调器不扫描场景寻找敌人。
|
||||
/// ApplyBattleReturn 必须按 EncounterId 精确操作触发敌人,不能按 EnemyConfigId 批量处理同类敌人。
|
||||
/// </summary>
|
||||
public interface IExplorationBattleBridge
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行探索恢复计划。
|
||||
/// </summary>
|
||||
/// <param name="plan">由 RunBattleCoordinator 生成的恢复计划。</param>
|
||||
void ApplyBattleReturn(BattleReturnPlan plan);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf022ae8498b418784037549ce415e3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user