1pub mod battle;
2pub mod constants;
3pub mod growth_type;
4pub mod input;
5pub mod load;
6pub mod message;
7pub mod monster;
8pub mod output;
9pub mod player;
10pub mod save;
11pub mod traits;
12pub mod utility;
13
14use battle::Battle;
15pub use constants::config::Cli;
16use constants::config::{DISPLAY_CATEGORY_LIST, Mode};
17use constants::item_weapon::{ARMOR_MASTER, ITEM_MASTER, SHIELD_MASTER, WEAPON_MASTER};
18use constants::monster::MONSTER_MASTER;
19use constants::spell::SPELL_INFO_LIST;
20use constants::status::STATUS_TABLE;
21use input::cli_input::CliInput;
22use monster::Monster;
23use output::cli_output::CliOutput;
24use player::Player;
25use std::collections::HashSet;
26use utility::status_utils::{get_status_by_level, get_status_list};
27
28pub fn run_from_args(args: Cli) -> Result<(), Box<dyn std::error::Error>> {
29 let views: HashSet<String> = args
30 .view
31 .clone()
32 .unwrap_or_default()
33 .iter()
34 .map(|s| s.to_lowercase())
35 .collect();
36 let mut player = Player::new_with(args.to_player_args());
37 if args.option.iter().any(|opt| opt == "max") {
38 player.maximize();
39 }
40
41 let category = views
42 .iter()
43 .find(|s| DISPLAY_CATEGORY_LIST.contains(&s.as_str()))
44 .map(|s| s.as_str());
45 let is_list_mode = views.contains("list");
46 let index = args
47 .view
48 .clone()
49 .unwrap_or_default()
50 .iter()
51 .find_map(|s| s.parse::<usize>().ok());
52
53 let mode = args.mode();
54 match mode {
55 Mode::Start => {
56 println!("player name: {}", player.name);
57 println!("summary: {:?}", player.summary());
58 println!("strength_status: {:?}", player.strength_status());
59 println!("item: {:?}", player.item_list());
60 }
61 Mode::Save => {
62 println!("password: {}", player.to_password_string()?);
63 }
64 Mode::Load => {
65 let new_player = Player::from_password_string(&args.password)?;
66 println!("new_player from Password");
67 println!("player name: {}", new_player.name);
68 println!("summary: {:?}", new_player.summary());
69 println!("strength_status: {:?}", new_player.strength_status());
70 }
71 Mode::Status => {
72 if is_list_mode {
73 println!("{:?}", get_status_list());
75 } else {
76 println!("status: {:?}", get_status_by_level(player.level()));
77 }
78 }
79 Mode::Display => match category {
80 Some("item") => print_list_or_index(&ITEM_MASTER, is_list_mode, index),
81 Some("weapon") => print_list_or_index(&WEAPON_MASTER, is_list_mode, index),
82 Some("armor") => print_list_or_index(&ARMOR_MASTER, is_list_mode, index),
83 Some("shield") => print_list_or_index(&SHIELD_MASTER, is_list_mode, index),
84 Some("status") => print_list_or_index(&STATUS_TABLE, is_list_mode, index),
85 Some("spell") => print_list_or_index(&SPELL_INFO_LIST, is_list_mode, index),
86 Some("monster") => print_list_or_index(&MONSTER_MASTER, is_list_mode, index),
87 None => println!("Category not specified"),
88 _ => {}
89 },
90 Mode::Battle => {
91 let mut output = CliOutput;
92 let mut input = CliInput;
93 let mut battle = Battle::new(
94 player,
95 Monster::new(index.unwrap_or(0)),
96 &mut input,
97 &mut output,
98 );
99 battle.start();
100 }
101 }
102 Ok(())
103}
104
105fn print_list_or_index<T: std::fmt::Debug>(list: &[T], is_list_mode: bool, index: Option<usize>) {
106 if is_list_mode {
107 println!("{:?}", list);
108 } else if let Some(i) = index {
109 let safe_index = i.min(list.len().saturating_sub(1));
110 println!("{:?}", list[safe_index]);
111 } else {
112 println!("{:?}", list);
113 }
114}