use std::collections::HashMap;
use linenoise;
use command::GameCommand;
use scenario::Scenario;
use state::State;
pub struct GameMaster {
state: Box<State>,
commands: HashMap<String, Box<GameCommand>>,
scenarios: HashMap<String, Box<Scenario>>
}
impl GameMaster {
pub fn new(state: Box<State>) -> GameMaster {
GameMaster {
state: state,
commands: HashMap::new(),
scenarios: HashMap::new()
}
}
pub fn add_command(&mut self, name: String, command: Box<GameCommand>) {
self.commands.insert(name, command);
}
pub fn add_scenario(&mut self, name: String, scenario: Box<Scenario>) {
self.scenarios.insert(name, scenario);
}
pub fn start_game(&mut self) {
self.main_loop();
}
fn change_scenario(&mut self) {
let scenario_name = self.state.get_next_scenario();
let scenario = match self.scenarios.get(&scenario_name) {
Some(s) => { s },
_ => {
println!("[ERROR] scenario {} not found", scenario_name);
return
}
};
scenario.load(&mut self.state);
self.state.load_scenario();
}
fn exec_game_command(&mut self, command: &str) -> bool {
let game_command = match self.commands.get(command) {
Some(f) => { f },
None => return false
};
game_command.execute(&mut self.state);
return true;
}
fn main_loop(&mut self) {
linenoise::set_multiline(0);
self.state.set_scenario("start".to_string());
self.change_scenario();
let mut input = String::new();
let mut command;
let mut current_scenario;
loop {
input = match linenoise::input("\n> ") {
Some(i) => { i },
None => { continue }
};
command = input.clone();
println!(" ");
if !self.exec_game_command(&command.trim()) {
current_scenario = self.state.get_current_scenario();
match self.scenarios.get(¤t_scenario) {
Some(s) => s.do_action(&command.trim(), &mut self.state),
_ => {
println!("[ERROR] scenario {} not found", current_scenario);
return
}
};
}
if self.state.has_next_scenario() {
self.change_scenario();
}
}
}
}