//! 任务领域模型。 //! //! 本文件承载任务状态、步骤、奖励、叙事绑定和进度信号等稳定值对象。 use serde::{Deserialize, Serialize}; #[cfg(feature = "spacetime-types")] use spacetimedb::SpacetimeType; pub const QUEST_LOG_ID_PREFIX: &str = "questlog_"; #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestStatus { Active, ReadyToTurnIn, Completed, TurnedIn, Failed, Expired, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestNarrativeType { Bounty, Escort, Investigation, Retrieval, Relationship, Trial, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestObjectiveKind { DefeatHostileNpc, InspectTreasure, SparWithNpc, TalkToNpc, ReachScene, DeliverItem, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestRewardItemRarity { Common, Uncommon, Rare, Epic, Legendary, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestNarrativeOrigin { AiCompiled, FallbackBuilder, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestLogEventKind { Accepted, Progressed, Completed, CompletionAcknowledged, TurnedIn, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestSignalKind { HostileNpcDefeated, TreasureInspected, NpcSparCompleted, NpcTalkCompleted, SceneReached, ItemDelivered, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestRewardItem { pub item_id: String, pub category: String, pub name: String, pub description: Option, pub quantity: u32, pub rarity: QuestRewardItemRarity, pub tags: Vec, pub stackable: bool, pub stack_key: String, pub equipment_slot_id: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestRewardEquipmentSlot { Weapon, Armor, Relic, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestRewardIntel { pub rumor_text: String, pub unlocked_scene_id: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestRewardSnapshot { pub affinity_bonus: i32, pub currency: i64, pub experience: Option, pub items: Vec, pub intel: Option, pub story_hint: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestNarrativeBindingSnapshot { pub origin: QuestNarrativeOrigin, pub narrative_type: QuestNarrativeType, pub dramatic_need: String, pub issuer_goal: String, pub player_hook: String, pub world_reason: String, pub followup_hooks: Vec, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestObjectiveSnapshot { pub kind: QuestObjectiveKind, pub target_hostile_npc_id: Option, pub target_npc_id: Option, pub target_scene_id: Option, pub target_item_id: Option, pub required_count: u32, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestStepSnapshot { pub step_id: String, pub kind: QuestObjectiveKind, pub target_hostile_npc_id: Option, pub target_npc_id: Option, pub target_scene_id: Option, pub target_item_id: Option, pub required_count: u32, pub progress: u32, pub title: String, pub reveal_text: String, pub complete_text: String, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestRecordSnapshot { pub quest_id: String, pub runtime_session_id: String, pub story_session_id: Option, pub actor_user_id: String, pub issuer_npc_id: String, pub issuer_npc_name: String, pub scene_id: Option, pub chapter_id: Option, pub act_id: Option, pub thread_id: Option, pub contract_id: Option, pub title: String, pub description: String, pub summary: String, pub objective: QuestObjectiveSnapshot, pub progress: u32, pub status: QuestStatus, pub completion_notified: bool, pub reward: QuestRewardSnapshot, pub reward_text: String, pub narrative_binding: QuestNarrativeBindingSnapshot, pub steps: Vec, pub active_step_id: Option, pub visible_stage: u32, pub hidden_flags: Vec, pub discovered_fact_ids: Vec, pub related_carrier_ids: Vec, pub consequence_ids: Vec, pub created_at_micros: i64, pub updated_at_micros: i64, pub completed_at_micros: Option, pub turned_in_at_micros: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestHostileNpcDefeatedSignal { pub scene_id: Option, pub hostile_npc_id: String, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestTreasureInspectedSignal { pub scene_id: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestNpcSparCompletedSignal { pub npc_id: String, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestNpcTalkCompletedSignal { pub npc_id: String, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestSceneReachedSignal { pub scene_id: String, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct QuestItemDeliveredSignal { pub npc_id: String, pub item_id: String, pub quantity: u32, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum QuestProgressSignal { HostileNpcDefeated(QuestHostileNpcDefeatedSignal), TreasureInspected(QuestTreasureInspectedSignal), NpcSparCompleted(QuestNpcSparCompletedSignal), NpcTalkCompleted(QuestNpcTalkCompletedSignal), SceneReached(QuestSceneReachedSignal), ItemDelivered(QuestItemDeliveredSignal), } impl QuestStatus { pub fn is_terminal(self) -> bool { matches!(self, Self::TurnedIn | Self::Failed | Self::Expired) } pub fn is_reward_ready(self) -> bool { matches!(self, Self::ReadyToTurnIn | Self::Completed) } } impl QuestLogEventKind { pub fn as_str(self) -> &'static str { match self { Self::Accepted => "accepted", Self::Progressed => "progressed", Self::Completed => "completed", Self::CompletionAcknowledged => "completion_ack", Self::TurnedIn => "turned_in", } } } impl From<&QuestProgressSignal> for QuestSignalKind { fn from(value: &QuestProgressSignal) -> Self { match value { QuestProgressSignal::HostileNpcDefeated(_) => Self::HostileNpcDefeated, QuestProgressSignal::TreasureInspected(_) => Self::TreasureInspected, QuestProgressSignal::NpcSparCompleted(_) => Self::NpcSparCompleted, QuestProgressSignal::NpcTalkCompleted(_) => Self::NpcTalkCompleted, QuestProgressSignal::SceneReached(_) => Self::SceneReached, QuestProgressSignal::ItemDelivered(_) => Self::ItemDelivered, } } }