119 lines
3.7 KiB
Rust
119 lines
3.7 KiB
Rust
//! 战斗领域模型。
|
|
//!
|
|
//! 本文件只承载战斗聚合内部状态和值对象;背包奖励、成长记账和任务联动由
|
|
//! SpacetimeDB 事务 adapter 编排,不在战斗领域内直连其他上下文。
|
|
|
|
use module_runtime_item::RuntimeItemRewardItemSnapshot;
|
|
use serde::{Deserialize, Serialize};
|
|
#[cfg(feature = "spacetime-types")]
|
|
use spacetimedb::SpacetimeType;
|
|
|
|
/// 战斗状态 ID 的稳定前缀,由领域层统一持有,避免应用层重复拼接规则。
|
|
pub const BATTLE_STATE_ID_PREFIX: &str = "battle_";
|
|
/// 新建战斗状态的初始版本号,用于乐观更新和快照投影。
|
|
pub const INITIAL_BATTLE_VERSION: u32 = 1;
|
|
/// 普通战斗中敌方反击伤害占玩家输出的比例。
|
|
pub const BASIC_FIGHT_COUNTER_RATIO: f32 = 0.14;
|
|
/// 普通战斗中敌方反击的最低伤害,保证战斗有稳定消耗。
|
|
pub const MIN_FIGHT_COUNTER_DAMAGE: i32 = 4;
|
|
/// 切磋模式保底生命值,避免非生死战把玩家扣到 0。
|
|
pub const SPAR_MIN_HP: i32 = 1;
|
|
|
|
/// 旧版战斗动作 function id 白名单,仍由结算规则用于识别攻击类动作。
|
|
pub(crate) const LEGACY_ATTACK_FUNCTION_IDS: [&str; 5] = [
|
|
"battle_all_in_crush",
|
|
"battle_guard_break",
|
|
"battle_probe_pressure",
|
|
"battle_feint_step",
|
|
"battle_finisher_window",
|
|
];
|
|
|
|
/// 战斗模式,决定结算时是否允许击败玩家。
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum BattleMode {
|
|
Fight,
|
|
Spar,
|
|
}
|
|
|
|
impl BattleMode {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::Fight => "fight",
|
|
Self::Spar => "spar",
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 战斗状态,用于标记战斗是否仍可继续接收行动。
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum BattleStatus {
|
|
Ongoing,
|
|
Resolved,
|
|
Aborted,
|
|
}
|
|
|
|
impl BattleStatus {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::Ongoing => "ongoing",
|
|
Self::Resolved => "resolved",
|
|
Self::Aborted => "aborted",
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 单次战斗行动结算后的领域结果。
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum CombatOutcome {
|
|
Ongoing,
|
|
Victory,
|
|
SparComplete,
|
|
Escaped,
|
|
}
|
|
|
|
impl CombatOutcome {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::Ongoing => "ongoing",
|
|
Self::Victory => "victory",
|
|
Self::SparComplete => "spar_complete",
|
|
Self::Escaped => "escaped",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct BattleStateSnapshot {
|
|
pub battle_state_id: String,
|
|
pub story_session_id: String,
|
|
pub runtime_session_id: String,
|
|
pub actor_user_id: String,
|
|
pub chapter_id: Option<String>,
|
|
pub target_npc_id: String,
|
|
pub target_name: String,
|
|
pub battle_mode: BattleMode,
|
|
pub status: BattleStatus,
|
|
pub player_hp: i32,
|
|
pub player_max_hp: i32,
|
|
pub player_mana: i32,
|
|
pub player_max_mana: i32,
|
|
pub target_hp: i32,
|
|
pub target_max_hp: i32,
|
|
pub experience_reward: u32,
|
|
pub reward_items: Vec<RuntimeItemRewardItemSnapshot>,
|
|
pub turn_index: u32,
|
|
pub last_action_function_id: Option<String>,
|
|
pub last_action_text: Option<String>,
|
|
pub last_result_text: Option<String>,
|
|
pub last_damage_dealt: i32,
|
|
pub last_damage_taken: i32,
|
|
pub last_outcome: CombatOutcome,
|
|
pub version: u32,
|
|
pub created_at_micros: i64,
|
|
pub updated_at_micros: i64,
|
|
}
|