112 lines
3.1 KiB
Rust
112 lines
3.1 KiB
Rust
use anyhow::Result;
|
|
use crate::{GameState, Notes};
|
|
use crate::notes::{Area, Step};
|
|
|
|
pub struct NotesState<'a> {
|
|
notes: &'a Notes,
|
|
last_printed_location: u16,
|
|
last_stage: u16,
|
|
last_location: u16,
|
|
|
|
step_idx: usize,
|
|
area_idx: usize,
|
|
|
|
current_step: &'a Step,
|
|
first_step: bool,
|
|
force_print: bool,
|
|
}
|
|
|
|
impl<'a> NotesState<'a> {
|
|
pub fn new(notes: &'a Notes, game: &mut GameState) -> Result<Self> {
|
|
game.refresh()?;
|
|
// find first step with a matching story stage
|
|
let steps = notes.steps
|
|
.iter()
|
|
.take_while(|step| step.stage <= game.story)
|
|
.count();
|
|
let (step, step_idx, force) = if steps <= 1 {
|
|
// nothing previous OR first step
|
|
(¬es.steps[0], 0, false)
|
|
} else {
|
|
// in progress
|
|
(¬es.steps[steps - 1], steps - 1, true)
|
|
};
|
|
// find first area that matches
|
|
let area_idx = step.areas
|
|
.iter()
|
|
.position(|area| area.area == 0 || area.area == game.location)
|
|
.unwrap_or(0);
|
|
|
|
Ok(Self {
|
|
notes,
|
|
last_printed_location: 0,
|
|
last_stage: 0,
|
|
last_location: 0,
|
|
step_idx,
|
|
area_idx,
|
|
current_step: step,
|
|
first_step: true,
|
|
force_print: force,
|
|
})
|
|
}
|
|
|
|
pub fn tick(&mut self, game: &mut GameState) -> Result<()> {
|
|
self.last_stage = game.story;
|
|
self.last_location = game.location;
|
|
game.refresh()?;
|
|
|
|
let stage_changed = self.last_stage != game.story;
|
|
let location_changed = self.last_location != game.location;
|
|
|
|
let step_advanced = stage_changed && self.change_step(game);
|
|
let area = match self.area() {
|
|
Some(area) => area.clone(),
|
|
None => return Ok(()),
|
|
};
|
|
|
|
if self.force_print || ((step_advanced || location_changed) && (game.location == area.area || area.area == 0)) {
|
|
if self.last_printed_location != game.location {
|
|
self.last_printed_location = game.location;
|
|
println!("{}", game.location_name().unwrap_or("Unknown Location"))
|
|
}
|
|
|
|
println!("{}", area.steps);
|
|
self.area_idx += 1;
|
|
|
|
if self.first_step {
|
|
self.first_step = false;
|
|
self.step_idx += 1;
|
|
if !self.force_print {
|
|
self.area_idx = 0;
|
|
}
|
|
}
|
|
|
|
if self.force_print {
|
|
self.force_print = false;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn area(&self) -> Option<&Area> {
|
|
self.current_step.areas.get(self.area_idx)
|
|
}
|
|
|
|
fn change_step(&mut self, game: &mut GameState) -> bool {
|
|
let next = match self.notes.steps.get(self.step_idx) {
|
|
Some(step) => step,
|
|
None => return false,
|
|
};
|
|
|
|
if next.stage == game.story {
|
|
self.current_step = next;
|
|
self.step_idx += 1;
|
|
self.area_idx = 0;
|
|
return true;
|
|
}
|
|
|
|
false
|
|
}
|
|
}
|