use crate::border_panel::{INNER_BORDER, OUTER_BORDER, draw_border_panel}; use crate::row::Row; use crate::{ Currency, unlocks::{Unlock, UnlockSystem}, }; use servicepoint::{Bitmap, CharGrid, CharGridMutExt, GridMut, TILE_SIZE, WindowMut}; use std::time::Duration; #[derive(Debug)] pub struct Game { total_currency: Currency, unlocks: UnlockSystem, state: State, } #[derive(Debug)] pub struct State { pub currency: Currency, pub speed: f64, pub productivity: f64, pub rows: Vec, } impl Game { const BAR_NAMES: [&'static str; 10] = [ "Powering infrastructure", "Dusting ServicePoint", "Activating colorful lights", "Dimming darkroom", "Refilling Matemat", "Pre-heating convectiomat", "Resetting chair heights", "Untangling 'block chain'", "Refilling sticker box", "Setting room to public", // "Welcoming creatures", ]; pub fn new() -> Self { let bars = Self::BAR_NAMES .iter() .enumerate() .map(|(index, name)| { Row::new( 2usize.pow(index as u32) as f64, 1.0 * (0.5f64.powi(index as i32)), *name, ) }) .collect(); let state = State { rows: bars, currency: 1f64, speed: 1f64, productivity: 1f64, }; Self { total_currency: 0f64, unlocks: UnlockSystem::new(&state), state, } } pub fn progress(&mut self, delta: Duration) { let adjusted_delta = delta.mul_f64(self.state.speed); let extra_currency = self.state.productivity * self .state .rows .iter_mut() .map(|bar| bar.progress(adjusted_delta)) .sum::(); self.state.currency += extra_currency; self.total_currency += extra_currency; self.unlocks.progress(&mut self.state); } pub fn draw( &self, text_layer: WindowMut, pixel_layer: WindowMut, ) { let (text_layer, pixel_layer) = draw_border_panel( text_layer, pixel_layer, " Discordia Boot Procedure ", OUTER_BORDER, ); let unlocks_height = 3 + 2; let (unlocks_text, text_layer) = text_layer.split_vertical_mut(unlocks_height).unwrap(); let (unlocks_pixel, pixel_layer) = pixel_layer .split_vertical_mut(unlocks_height * TILE_SIZE) .unwrap(); self.unlocks.draw(unlocks_text, unlocks_pixel); let bars_height = self.state.rows.len() + 2; let (bars_text, text_layer) = text_layer.split_vertical_mut(bars_height).unwrap(); let (bars_pixel, _) = pixel_layer .split_vertical_mut(bars_height * TILE_SIZE) .unwrap(); self.draw_bars(bars_text, bars_pixel); let free_row_bottom = text_layer.height() - 1; self.draw_stats(text_layer, free_row_bottom); } fn draw_stats>(&self, text_layer: WindowMut, row: usize) { let middle = text_layer.width() / 2; let (mut left, mut right) = text_layer.split_horizontal_mut(middle).unwrap(); left.set_row_str(0, &format!("Hack Score: {:.2}", self.total_currency)) .unwrap(); if self.unlocks.bought() > 0 { right .set_row_str(0, &format!(" Unlocks: {}", self.unlocks.bought())) .unwrap(); } } fn draw_bars, P: GridMut>( &self, text_layer: WindowMut, pixel_layer: WindowMut, ) { let (mut text_layer, mut pixel_layer) = draw_border_panel(text_layer, pixel_layer, " Processes ", INNER_BORDER); for (index, row) in self.state.rows.iter().enumerate() { let mut bar_window = pixel_layer .window_mut(0, index * TILE_SIZE, pixel_layer.width(), TILE_SIZE) .unwrap(); let mut label_window = text_layer .window_mut(0, index, text_layer.width(), 1) .unwrap(); row.draw(&mut label_window, &mut bar_window); } } }