use crate::sink::AutosaveSink;
use std::convert::TryInto;
use std::fs::File;
use std::{env, io::BufRead, io::BufReader, io::Read};
use weasel::event::EventSinkId;
use weasel::team::TeamId;
use weasel::{
battle_rules, rules::empty::*, Battle, BattleController, BattleRules, CreateCreature,
CreateTeam, EventReceiver, EventTrigger, FlatVersionedEvent, Server,
};
mod sink;
battle_rules! {}
static TEAM_ID: TeamId<CustomRules> = 0;
const AUTOSAVE_NAME: &str = "autosave";
const SINK_ID: EventSinkId = 0;
fn main() {
print_intro();
game_loop();
println!();
println!("Goodbye!");
}
fn print_intro() {
println!("Autosave");
println!();
println!("Example to demonstrate how to use an event sink to create autosaves with weasel.");
println!("Create soldiers and exit whenever you want.");
println!("Next time you launch the game it will resume from the latest progress!");
println!();
println!(" Controls:");
println!(" c - Create a new soldier");
println!(" q - Quit");
}
fn game_loop() {
let mut server = create_server();
println!();
print_soldiers_count(&server);
loop {
let input: Option<char> = std::io::stdin()
.bytes()
.next()
.and_then(|result| result.ok())
.map(|byte| byte as char);
if let Some(key) = input {
match key {
'c' => {
create_soldier(&mut server);
print_soldiers_count(&server);
}
'q' => break,
_ => {}
}
}
}
}
fn get_soldiers_count(server: &Server<CustomRules>) -> usize {
server.battle().entities().creatures().count()
}
fn print_soldiers_count(server: &Server<CustomRules>) {
println!("Current number of soldiers: {}", get_soldiers_count(server));
}
fn create_soldier(server: &mut Server<CustomRules>) {
let next_id = get_soldiers_count(server).try_into().unwrap();
CreateCreature::trigger(server, next_id, TEAM_ID, ())
.fire()
.unwrap();
}
fn create_server() -> Server<CustomRules> {
let battle = Battle::builder(CustomRules::new()).build();
let mut server = Server::builder(battle).build();
let mut path = env::temp_dir();
path.push(AUTOSAVE_NAME);
let file = File::open(path);
match file {
Ok(file) => {
let mut reader = BufReader::new(file);
loop {
let mut buffer = Vec::new();
let result = reader.read_until(b'#', &mut buffer).unwrap();
if result > 0 {
buffer.truncate(buffer.len() - 1);
let event: FlatVersionedEvent<_> = serde_json::from_slice(&buffer).unwrap();
server.receive(event.into()).unwrap()
} else {
break;
}
}
attach_sink(&mut server);
server
}
Err(_) => {
attach_sink(&mut server);
CreateTeam::trigger(&mut server, TEAM_ID).fire().unwrap();
server
}
}
}
fn attach_sink(server: &mut Server<CustomRules>) {
let sink = AutosaveSink::new(SINK_ID, AUTOSAVE_NAME);
server.client_sinks_mut().add_sink(Box::new(sink)).unwrap();
}