M4 runtime story Rust migration wrap-up
This commit is contained in:
@@ -9,17 +9,47 @@ use module_npc::{
|
||||
build_relation_state as build_module_npc_relation_state,
|
||||
};
|
||||
use module_runtime::RuntimeSnapshotRecord;
|
||||
use module_runtime_story_compat::{
|
||||
CONTINUE_ADVENTURE_FUNCTION_ID, CurrentEncounterNpcQuestContext, GeneratedStoryPayload,
|
||||
PendingQuestOfferContext, RuntimeStoryActionResponseParts,
|
||||
StoryResolution, add_player_currency, add_player_inventory_items,
|
||||
append_story_history, apply_equipment_loadout_to_state,
|
||||
battle_mode_text, build_battle_runtime_story_options, build_current_build_toast,
|
||||
build_status_patch,
|
||||
build_npc_gift_result_text,
|
||||
build_runtime_story_view_model,
|
||||
clear_encounter_only, clear_encounter_state, clone_inventory_item_with_quantity,
|
||||
current_encounter_id, current_encounter_name, current_world_type,
|
||||
ensure_inventory_action_available, ensure_json_object, equipment_slot_label,
|
||||
find_player_inventory_entry,
|
||||
format_now_rfc3339, grant_player_progression_experience, has_giftable_player_inventory,
|
||||
format_currency_text,
|
||||
increment_runtime_stat, normalize_equipped_item,
|
||||
normalize_equipment_slot_id, normalize_required_string, npc_buyback_price,
|
||||
npc_purchase_price, read_array_field, read_bool_field, read_field, read_i32_field,
|
||||
read_inventory_item_name, read_object_field, read_optional_string_field,
|
||||
read_player_equipment_item, read_required_string_field, read_runtime_session_id,
|
||||
read_u32_field, recruit_companion_to_party, remove_player_inventory_item,
|
||||
restore_player_resource,
|
||||
resolve_action_text, resolve_battle_action, resolve_equipment_slot_for_item,
|
||||
resolve_forge_craft_action,
|
||||
resolve_forge_dismantle_action, resolve_forge_reforge_action,
|
||||
resolve_npc_gift_affinity_gain, simple_story_resolution, trade_quantity_suffix,
|
||||
resolve_current_encounter_npc_state,
|
||||
build_disabled_runtime_story_option, build_runtime_story_option_from_story_option,
|
||||
build_static_runtime_story_option, build_story_option_from_runtime_option,
|
||||
write_bool_field, write_i32_field, write_null_field, write_player_equipment_item,
|
||||
write_string_field, write_u32_field,
|
||||
};
|
||||
use platform_llm::{LlmClient, LlmMessage, LlmTextRequest};
|
||||
use serde_json::{Map, Value, json};
|
||||
use shared_contracts::runtime_story::{
|
||||
RuntimeBattlePresentation, RuntimeStoryActionRequest, RuntimeStoryActionResponse,
|
||||
RuntimeStoryAiRequest, RuntimeStoryAiResponse, RuntimeStoryCompanionViewModel,
|
||||
RuntimeStoryEncounterViewModel, RuntimeStoryOptionInteraction, RuntimeStoryOptionView,
|
||||
RuntimeStoryPatch, RuntimeStoryPlayerViewModel, RuntimeStoryPresentation,
|
||||
RuntimeStorySnapshotPayload, RuntimeStoryStateResolveRequest, RuntimeStoryStatusViewModel,
|
||||
RuntimeStoryViewModel,
|
||||
RuntimeStoryAiRequest, RuntimeStoryAiResponse, RuntimeStoryOptionInteraction,
|
||||
RuntimeStoryOptionView, RuntimeStoryPatch, RuntimeStoryPresentation,
|
||||
RuntimeStorySnapshotPayload, RuntimeStoryStateResolveRequest,
|
||||
};
|
||||
use shared_kernel::{format_rfc3339, offset_datetime_to_unix_micros, parse_rfc3339};
|
||||
use shared_kernel::{offset_datetime_to_unix_micros, parse_rfc3339};
|
||||
use spacetime_client::SpacetimeClientError;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
@@ -30,22 +60,10 @@ use crate::{
|
||||
|
||||
#[path = "compat/ai.rs"]
|
||||
mod ai;
|
||||
#[path = "compat/battle.rs"]
|
||||
mod battle;
|
||||
#[path = "compat/battle_actions.rs"]
|
||||
mod battle_actions;
|
||||
#[path = "compat/core.rs"]
|
||||
mod core;
|
||||
#[path = "compat/equipment_actions.rs"]
|
||||
mod equipment_actions;
|
||||
#[path = "compat/forge.rs"]
|
||||
mod forge;
|
||||
#[path = "compat/forge_actions.rs"]
|
||||
mod forge_actions;
|
||||
#[path = "compat/game_state.rs"]
|
||||
mod game_state;
|
||||
#[path = "compat/npc_support.rs"]
|
||||
mod npc_support;
|
||||
#[path = "compat/npc_actions.rs"]
|
||||
mod npc_actions;
|
||||
#[path = "compat/presentation.rs"]
|
||||
@@ -54,50 +72,13 @@ mod presentation;
|
||||
mod quest_actions;
|
||||
|
||||
use self::{
|
||||
ai::*, battle::*, battle_actions::*, core::*, equipment_actions::*, forge::*,
|
||||
forge_actions::*, game_state::*, npc_actions::*, npc_support::*, presentation::*,
|
||||
quest_actions::*,
|
||||
ai::*, equipment_actions::*, game_state::*, npc_actions::*, presentation::*, quest_actions::*,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "compat/tests.rs"]
|
||||
mod tests;
|
||||
|
||||
const CONTINUE_ADVENTURE_FUNCTION_ID: &str = "story_continue_adventure";
|
||||
const MAX_TASK5_COMPANIONS: usize = 2;
|
||||
|
||||
struct StoryResolution {
|
||||
action_text: String,
|
||||
result_text: String,
|
||||
story_text: Option<String>,
|
||||
presentation_options: Option<Vec<RuntimeStoryOptionView>>,
|
||||
saved_current_story: Option<Value>,
|
||||
patches: Vec<RuntimeStoryPatch>,
|
||||
battle: Option<RuntimeBattlePresentation>,
|
||||
toast: Option<String>,
|
||||
}
|
||||
|
||||
struct GeneratedStoryPayload {
|
||||
story_text: String,
|
||||
history_result_text: String,
|
||||
presentation_options: Vec<RuntimeStoryOptionView>,
|
||||
saved_current_story: Value,
|
||||
}
|
||||
|
||||
struct CurrentEncounterNpcQuestContext {
|
||||
npc_id: String,
|
||||
npc_name: String,
|
||||
}
|
||||
|
||||
struct PendingQuestOfferContext {
|
||||
dialogue: Vec<Value>,
|
||||
turn_count: i32,
|
||||
custom_input_placeholder: String,
|
||||
quest: Value,
|
||||
quest_id: String,
|
||||
intro_text: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn resolve_runtime_story_state(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
@@ -482,19 +463,6 @@ fn validate_client_version(
|
||||
))
|
||||
}
|
||||
|
||||
struct RuntimeStoryActionResponseParts {
|
||||
requested_session_id: String,
|
||||
server_version: u32,
|
||||
snapshot: RuntimeStorySnapshotPayload,
|
||||
action_text: String,
|
||||
result_text: String,
|
||||
story_text: String,
|
||||
options: Vec<RuntimeStoryOptionView>,
|
||||
patches: Vec<RuntimeStoryPatch>,
|
||||
toast: Option<String>,
|
||||
battle: Option<RuntimeBattlePresentation>,
|
||||
}
|
||||
|
||||
fn resolve_runtime_story_choice_action(
|
||||
game_state: &mut Value,
|
||||
current_story: Option<&Value>,
|
||||
@@ -650,49 +618,6 @@ fn resolve_continue_adventure_action(
|
||||
})
|
||||
}
|
||||
|
||||
fn simple_story_resolution(
|
||||
game_state: &Value,
|
||||
action_text: String,
|
||||
result_text: &str,
|
||||
) -> StoryResolution {
|
||||
StoryResolution {
|
||||
action_text,
|
||||
result_text: result_text.to_string(),
|
||||
story_text: None,
|
||||
presentation_options: None,
|
||||
saved_current_story: None,
|
||||
patches: vec![build_status_patch(game_state)],
|
||||
battle: None,
|
||||
toast: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_action_text(default_text: &str, request: &RuntimeStoryActionRequest) -> String {
|
||||
request
|
||||
.action
|
||||
.payload
|
||||
.as_ref()
|
||||
.and_then(|payload| read_optional_string_field(payload, "optionText"))
|
||||
.unwrap_or_else(|| default_text.to_string())
|
||||
}
|
||||
|
||||
fn build_status_patch(game_state: &Value) -> RuntimeStoryPatch {
|
||||
RuntimeStoryPatch::StatusChanged {
|
||||
in_battle: read_bool_field(game_state, "inBattle").unwrap_or(false),
|
||||
npc_interaction_active: read_bool_field(game_state, "npcInteractionActive")
|
||||
.unwrap_or(false),
|
||||
current_npc_battle_mode: read_optional_string_field(game_state, "currentNpcBattleMode"),
|
||||
current_npc_battle_outcome: read_optional_string_field(
|
||||
game_state,
|
||||
"currentNpcBattleOutcome",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn current_world_type(game_state: &Value) -> Option<String> {
|
||||
read_optional_string_field(game_state, "worldType")
|
||||
}
|
||||
|
||||
fn map_runtime_story_client_error(error: SpacetimeClientError) -> AppError {
|
||||
let (status, provider) = match error {
|
||||
SpacetimeClientError::Runtime(_) => (StatusCode::BAD_REQUEST, "runtime-story"),
|
||||
|
||||
Reference in New Issue
Block a user