283 lines
8.6 KiB
Rust
283 lines
8.6 KiB
Rust
//! 任务领域模型。
|
|
//!
|
|
//! 本文件承载任务状态、步骤、奖励、叙事绑定和进度信号等稳定值对象。
|
|
|
|
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<String>,
|
|
pub quantity: u32,
|
|
pub rarity: QuestRewardItemRarity,
|
|
pub tags: Vec<String>,
|
|
pub stackable: bool,
|
|
pub stack_key: String,
|
|
pub equipment_slot_id: Option<QuestRewardEquipmentSlot>,
|
|
}
|
|
|
|
#[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<String>,
|
|
}
|
|
|
|
#[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<u32>,
|
|
pub items: Vec<QuestRewardItem>,
|
|
pub intel: Option<QuestRewardIntel>,
|
|
pub story_hint: Option<String>,
|
|
}
|
|
|
|
#[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<String>,
|
|
}
|
|
|
|
#[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<String>,
|
|
pub target_npc_id: Option<String>,
|
|
pub target_scene_id: Option<String>,
|
|
pub target_item_id: Option<String>,
|
|
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<String>,
|
|
pub target_npc_id: Option<String>,
|
|
pub target_scene_id: Option<String>,
|
|
pub target_item_id: Option<String>,
|
|
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<String>,
|
|
pub actor_user_id: String,
|
|
pub issuer_npc_id: String,
|
|
pub issuer_npc_name: String,
|
|
pub scene_id: Option<String>,
|
|
pub chapter_id: Option<String>,
|
|
pub act_id: Option<String>,
|
|
pub thread_id: Option<String>,
|
|
pub contract_id: Option<String>,
|
|
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<QuestStepSnapshot>,
|
|
pub active_step_id: Option<String>,
|
|
pub visible_stage: u32,
|
|
pub hidden_flags: Vec<String>,
|
|
pub discovered_fact_ids: Vec<String>,
|
|
pub related_carrier_ids: Vec<String>,
|
|
pub consequence_ids: Vec<String>,
|
|
pub created_at_micros: i64,
|
|
pub updated_at_micros: i64,
|
|
pub completed_at_micros: Option<i64>,
|
|
pub turned_in_at_micros: Option<i64>,
|
|
}
|
|
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct QuestHostileNpcDefeatedSignal {
|
|
pub scene_id: Option<String>,
|
|
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<String>,
|
|
}
|
|
|
|
#[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,
|
|
}
|
|
}
|
|
}
|