163 lines
6.2 KiB
Rust
163 lines
6.2 KiB
Rust
use serde_json::Value;
|
|
use shared_contracts::runtime_story::{
|
|
RuntimeBattlePresentation, RuntimeStoryActionRequest, RuntimeStoryOptionView,
|
|
RuntimeStoryPatch, RuntimeStorySnapshotPayload,
|
|
};
|
|
|
|
pub mod battle;
|
|
#[cfg(test)]
|
|
mod battle_tests;
|
|
pub mod core;
|
|
pub mod forge;
|
|
pub mod forge_actions;
|
|
pub mod game_state;
|
|
pub mod npc_support;
|
|
pub mod options;
|
|
pub mod post_battle;
|
|
pub mod prompt_context;
|
|
pub mod story_engine;
|
|
pub mod view_model;
|
|
|
|
pub use battle::{
|
|
build_battle_runtime_story_options, inventory_item_has_usable_effect, resolve_battle_action,
|
|
restore_player_resource,
|
|
};
|
|
pub use core::{
|
|
MAX_PLAYER_LEVEL, add_player_currency, add_player_inventory_items, append_active_build_buffs,
|
|
append_story_history, clear_encounter_only, clear_encounter_state, cumulative_xp_required,
|
|
ensure_json_object, first_hostile_npc_string_field, format_now_rfc3339,
|
|
grant_player_progression_experience, increment_runtime_stat, normalize_optional_string,
|
|
normalize_required_string, read_array_field, read_bool_field, read_field, read_i32_field,
|
|
read_object_field, read_optional_string_field, read_required_string_field,
|
|
read_runtime_session_id, read_u32_field, remove_player_inventory_item,
|
|
resolve_progression_level, write_bool_field, write_current_encounter_i32_field,
|
|
write_first_hostile_npc_i32_field, write_i32_field, write_null_field, write_string_field,
|
|
write_u32_field, xp_to_next_level_for,
|
|
};
|
|
pub use forge::{build_runtime_equipment_item, build_runtime_material_item, format_currency_text};
|
|
pub use forge_actions::{
|
|
resolve_forge_craft_action, resolve_forge_dismantle_action, resolve_forge_reforge_action,
|
|
};
|
|
pub use game_state::{
|
|
add_inventory_items_to_list, apply_equipment_loadout_to_state, battle_mode_text,
|
|
build_current_build_toast, clone_inventory_item_with_quantity, current_encounter_id,
|
|
current_encounter_name, current_encounter_name_from_battle, ensure_inventory_action_available,
|
|
equipment_bonus_fallbacks, equipment_item_bonuses, equipment_slot_label,
|
|
find_player_inventory_entry, has_giftable_player_inventory, item_rarity_key,
|
|
normalize_equipment_slot_id, normalize_equipped_item, read_equipment_total_bonuses,
|
|
read_inventory_item_name, read_player_equipment_item, read_player_inventory_values,
|
|
read_runtime_equipment_bonus_cache, remove_inventory_item_from_list,
|
|
resolve_equipment_slot_for_item, write_player_equipment_item, write_player_inventory_values,
|
|
write_runtime_equipment_bonus_cache,
|
|
};
|
|
pub use npc_support::{
|
|
build_npc_gift_result_text, build_runtime_npc_interaction_view, npc_buyback_price,
|
|
npc_purchase_price, recruit_companion_to_party, resolve_npc_gift_affinity_gain,
|
|
trade_quantity_suffix, write_runtime_npc_interaction_view,
|
|
};
|
|
pub use options::{
|
|
build_disabled_runtime_story_option, build_runtime_story_option_from_story_option,
|
|
build_runtime_story_option_interaction, build_runtime_story_option_with_payload,
|
|
build_static_runtime_story_option, build_story_option_from_runtime_option, infer_option_scope,
|
|
};
|
|
pub use post_battle::{
|
|
finalize_post_battle_resolution, is_terminal_battle_outcome, resolve_post_battle_story_options,
|
|
};
|
|
pub use prompt_context::{RuntimeStoryPromptContextExtras, build_runtime_story_prompt_context};
|
|
pub use story_engine::project_story_engine_after_action;
|
|
pub use view_model::{
|
|
build_runtime_story_companions, build_runtime_story_encounter, build_runtime_story_view_model,
|
|
resolve_current_encounter_npc_state,
|
|
};
|
|
|
|
pub const CONTINUE_ADVENTURE_FUNCTION_ID: &str = "story_continue_adventure";
|
|
pub const MAX_TASK5_COMPANIONS: usize = 2;
|
|
|
|
pub struct StoryResolution {
|
|
pub action_text: String,
|
|
pub result_text: String,
|
|
pub story_text: Option<String>,
|
|
pub presentation_options: Option<Vec<RuntimeStoryOptionView>>,
|
|
pub saved_current_story: Option<Value>,
|
|
pub patches: Vec<RuntimeStoryPatch>,
|
|
pub battle: Option<RuntimeBattlePresentation>,
|
|
pub toast: Option<String>,
|
|
}
|
|
|
|
pub struct GeneratedStoryPayload {
|
|
pub story_text: String,
|
|
pub history_result_text: String,
|
|
pub presentation_options: Vec<RuntimeStoryOptionView>,
|
|
pub saved_current_story: Value,
|
|
}
|
|
|
|
pub struct CurrentEncounterNpcQuestContext {
|
|
pub npc_id: String,
|
|
pub npc_name: String,
|
|
}
|
|
|
|
pub struct PendingQuestOfferContext {
|
|
pub dialogue: Vec<Value>,
|
|
pub turn_count: i32,
|
|
pub custom_input_placeholder: String,
|
|
pub quest: Value,
|
|
pub quest_id: String,
|
|
pub intro_text: Option<String>,
|
|
}
|
|
|
|
pub struct RuntimeStoryActionResponseParts {
|
|
pub requested_session_id: String,
|
|
pub server_version: u32,
|
|
pub snapshot: RuntimeStorySnapshotPayload,
|
|
pub action_text: String,
|
|
pub result_text: String,
|
|
pub story_text: String,
|
|
pub options: Vec<RuntimeStoryOptionView>,
|
|
pub patches: Vec<RuntimeStoryPatch>,
|
|
pub toast: Option<String>,
|
|
pub battle: Option<RuntimeBattlePresentation>,
|
|
}
|
|
|
|
pub 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,
|
|
}
|
|
}
|
|
|
|
pub 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())
|
|
}
|
|
|
|
pub 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",
|
|
),
|
|
}
|
|
}
|
|
|
|
pub fn current_world_type(game_state: &Value) -> Option<String> {
|
|
read_optional_string_field(game_state, "worldType")
|
|
}
|