add borders around panels
This commit is contained in:
parent
74d146242b
commit
12f48497ae
6 changed files with 368 additions and 197 deletions
214
src/unlocks.rs
214
src/unlocks.rs
|
|
@ -1,20 +1,26 @@
|
|||
use crate::Currency;
|
||||
use crate::game::{Game, State};
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::{Debug, Formatter, format};
|
||||
use std::ops::Mul;
|
||||
use crate::border_panel::{INNER_BORDER, draw_border_panel};
|
||||
use crate::{Currency, bar::Bar, game::State, row::Row};
|
||||
use servicepoint::{CharGridMutExt, GridMut, TILE_SIZE, WindowMut};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fmt::{Debug, Formatter},
|
||||
iter::Map,
|
||||
ops::{Mul, Range},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct UnlockSystem {
|
||||
pub struct UnlockSystem {
|
||||
bought: usize,
|
||||
last_unlock: Option<String>,
|
||||
unlock_queue: VecDeque<Unlock>,
|
||||
all_unlocks_bar: Bar,
|
||||
next_unlock_bar: Bar,
|
||||
}
|
||||
|
||||
pub(crate) struct Unlock {
|
||||
pub(crate) name: String,
|
||||
pub(crate) cost: Currency,
|
||||
pub(crate) apply: Box<dyn Fn(&mut State)>,
|
||||
pub struct Unlock {
|
||||
pub name: String,
|
||||
pub cost: Currency,
|
||||
pub apply: Box<dyn Fn(&mut State)>,
|
||||
}
|
||||
|
||||
impl Debug for Unlock {
|
||||
|
|
@ -27,93 +33,147 @@ impl Debug for Unlock {
|
|||
}
|
||||
|
||||
impl UnlockSystem {
|
||||
pub(crate) fn new(start_state: &State) -> Self {
|
||||
let mut upgrades = start_state
|
||||
.bars
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(index, bar)| {
|
||||
let initial_cost = 10usize.pow(index as u32);
|
||||
[
|
||||
Unlock {
|
||||
name: format!("Start {}", bar.name()),
|
||||
cost: initial_cost as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.bars[index].enabled = true;
|
||||
}),
|
||||
},
|
||||
Unlock {
|
||||
name: format!("{} productivity", bar.name()),
|
||||
cost: initial_cost.mul(2) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.bars[index].productivity *= 2.0;
|
||||
}),
|
||||
},
|
||||
Unlock {
|
||||
name: format!("{} speed", bar.name()),
|
||||
cost: initial_cost.mul(20) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.bars[index].speed *= 1.5;
|
||||
}),
|
||||
},
|
||||
]
|
||||
})
|
||||
.chain(
|
||||
(1..10).map(|level|
|
||||
Unlock {
|
||||
name: format!("The answer {}", level),
|
||||
cost: (42usize * 10usize.pow(level)) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.speed *= 1.1;
|
||||
}),
|
||||
}
|
||||
)
|
||||
)
|
||||
.chain(
|
||||
(1..10).map(|level|
|
||||
Unlock {
|
||||
name: format!("??? {}", level),
|
||||
cost: (23usize * 10usize.pow(level)) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.productivity *= 1.1;
|
||||
}),
|
||||
},
|
||||
)
|
||||
)
|
||||
pub fn new(start_state: &State) -> Self {
|
||||
let mut upgrades = Self::gen_bar_upgrades(&start_state.rows)
|
||||
.chain(Self::gen_speed_upgrades())
|
||||
.chain(Self::gen_productivity_upgrades())
|
||||
.collect::<Vec<_>>();
|
||||
upgrades.sort_by(|l, r| l.cost.total_cmp(&r.cost));
|
||||
|
||||
let unlock_queue = upgrades.into();
|
||||
|
||||
Self {
|
||||
unlock_queue,
|
||||
unlock_queue: upgrades.into(),
|
||||
bought: 0,
|
||||
last_unlock: None
|
||||
last_unlock: None,
|
||||
all_unlocks_bar: Bar::new(),
|
||||
next_unlock_bar: Bar::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn peek_next(&self) -> Option<&Unlock> {
|
||||
pub fn peek_next(&self) -> Option<&Unlock> {
|
||||
self.unlock_queue.front()
|
||||
}
|
||||
|
||||
pub(crate) fn check_next(&mut self, state: &mut State) {
|
||||
pub fn progress(&mut self, state: &mut State) {
|
||||
if let Some(next_upgrade) = self.peek_next() {
|
||||
if next_upgrade.cost <= state.currency {
|
||||
log::info!("Applying upgrade {:?}", next_upgrade);
|
||||
let next_upgrade = self.unlock_queue.pop_front().unwrap();
|
||||
state.currency -= next_upgrade.cost;
|
||||
(next_upgrade.apply)(state);
|
||||
self.last_unlock = Some(next_upgrade.name);
|
||||
self.bought += 1;
|
||||
self.buy_next(state);
|
||||
self.next_unlock_bar.progress = 0.0;
|
||||
} else {
|
||||
self.next_unlock_bar.progress = state.currency / next_upgrade.cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn bought(&self) -> usize {
|
||||
pub fn bought(&self) -> usize {
|
||||
self.bought
|
||||
}
|
||||
|
||||
pub(crate) fn previous(&self) -> Option<&String> {
|
||||
pub fn previous(&self) -> Option<&String> {
|
||||
self.last_unlock.as_ref()
|
||||
}
|
||||
|
||||
pub fn draw<C: GridMut<char>, P: GridMut<bool>>(
|
||||
&self,
|
||||
chars: WindowMut<char, C>,
|
||||
bitmap: WindowMut<bool, P>,
|
||||
) {
|
||||
let (mut chars, mut bitmap) = draw_border_panel(chars, bitmap, " Unlocks ", INNER_BORDER);
|
||||
let mut free_row_bottom = chars.height() - 1;
|
||||
|
||||
let pixel_width = bitmap.width();
|
||||
self.all_unlocks_bar.draw(
|
||||
&mut WindowMut::new(
|
||||
&mut bitmap,
|
||||
0,
|
||||
free_row_bottom * TILE_SIZE,
|
||||
pixel_width,
|
||||
TILE_SIZE,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
free_row_bottom -= 1;
|
||||
|
||||
self.next_unlock_bar.draw(
|
||||
&mut WindowMut::new(
|
||||
&mut bitmap,
|
||||
0,
|
||||
free_row_bottom * TILE_SIZE,
|
||||
pixel_width,
|
||||
TILE_SIZE,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
free_row_bottom -= 1;
|
||||
|
||||
if let Some(prev_unlock) = self.previous() {
|
||||
let char_width = chars.width();
|
||||
WindowMut::new(&mut chars, 0, free_row_bottom, char_width, 1)
|
||||
.unwrap()
|
||||
.set_row_str(0, &format!("Unlocked: {}", prev_unlock))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn buy_next(&mut self, state: &mut State) {
|
||||
let next_upgrade = self.unlock_queue.pop_front().unwrap();
|
||||
log::info!("Applying upgrade {:?}", &next_upgrade);
|
||||
|
||||
state.currency -= next_upgrade.cost;
|
||||
(next_upgrade.apply)(state);
|
||||
|
||||
self.last_unlock = Some(next_upgrade.name);
|
||||
self.bought += 1;
|
||||
|
||||
let total = self.bought + self.unlock_queue.len();
|
||||
self.all_unlocks_bar.progress = self.bought as f64 / total as f64;
|
||||
}
|
||||
|
||||
fn gen_bar_upgrades(bars: &Vec<Row>) -> impl Iterator<Item = Unlock> {
|
||||
bars.iter().enumerate().flat_map(|(index, bar)| {
|
||||
let initial_cost = 10usize.pow(index as u32);
|
||||
[
|
||||
Unlock {
|
||||
name: format!("Start {}", bar.name()),
|
||||
cost: initial_cost as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.rows[index].enabled = true;
|
||||
}),
|
||||
},
|
||||
Unlock {
|
||||
name: format!("{} productivity", bar.name()),
|
||||
cost: initial_cost.mul(2) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.rows[index].productivity *= 2.0;
|
||||
}),
|
||||
},
|
||||
Unlock {
|
||||
name: format!("{} speed", bar.name()),
|
||||
cost: initial_cost.mul(20) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.rows[index].speed *= 1.5;
|
||||
}),
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_speed_upgrades() -> impl Iterator<Item = Unlock> {
|
||||
(1..10).map(|level| Unlock {
|
||||
name: format!("The answer {}", level),
|
||||
cost: (42usize * 10usize.pow(level)) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.speed *= 1.1;
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
fn gen_productivity_upgrades() -> Map<Range<u32>, fn(u32) -> Unlock> {
|
||||
(1..10).map(|level| Unlock {
|
||||
name: format!("??? {}", level),
|
||||
cost: (23usize * 10usize.pow(level)) as f64,
|
||||
apply: Box::new(move |game| {
|
||||
game.productivity *= 1.1;
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue