Remember the upzoned buildings, and add a button to clear the choices. #431

This commit is contained in:
Dustin Carlino 2020-12-26 20:10:17 -08:00
parent af5811c33c
commit f8ac0fc96b
4 changed files with 59 additions and 12 deletions

View File

@ -50,6 +50,10 @@ where
self.map.get(&key).unwrap_or(&self.empty)
}
pub fn set(&mut self, key: K, values: BTreeSet<V>) {
self.map.insert(key, values);
}
pub fn len(&self) -> usize {
self.map.len()
}
@ -62,6 +66,15 @@ where
self.map
}
}
impl<K, V> std::default::Default for MultiMap<K, V>
where
K: Ord + PartialEq + Clone,
V: Ord + PartialEq + Clone,
{
fn default() -> MultiMap<K, V> {
MultiMap::new()
}
}
#[derive(Clone)]
pub struct Counter<T: Ord + PartialEq + Clone> {

View File

@ -7,7 +7,7 @@ use abstutil::Timer;
use geom::{Duration, Pt2D, Time};
use map_model::{AreaID, BuildingID, BusStopID, IntersectionID, LaneID, Map, ParkingLotID, RoadID};
use sim::{AgentID, CarID, PedestrianID, Sim};
use widgetry::{Cached, EventCtx, GfxCtx, State};
use widgetry::{EventCtx, GfxCtx, State};
pub use self::simple_app::SimpleApp;
use crate::render::DrawOptions;

View File

@ -1,4 +1,4 @@
use std::collections::HashSet;
use std::collections::{BTreeSet, HashSet};
use rand::seq::SliceRandom;
use rand::SeedableRng;
@ -30,7 +30,7 @@ pub struct Picker {
upzone_panel: Panel,
level: Level,
bldgs: Buildings,
current_picks: HashSet<BuildingID>,
current_picks: BTreeSet<BuildingID>,
draw_start: Drawable,
}
@ -103,13 +103,20 @@ impl Picker {
.color(RewriteColor::ChangeAll(Color::RED))
.centered_on(start);
let current_picks = app
.session
.upzones_per_level
.get(level.title.clone())
.clone();
let upzone_panel = make_upzone_panel(ctx, app, current_picks.len());
Transition::Replace(Box::new(Picker {
vehicle_panel: make_vehicle_panel(ctx, app),
upzone_panel: make_upzone_panel(ctx, app, 0),
upzone_panel,
instructions_panel,
level,
bldgs,
current_picks: HashSet::new(),
current_picks,
draw_start: ctx.upload(draw_start),
}))
}),
@ -166,18 +173,27 @@ impl State<App> for Picker {
Outcome::Clicked(x) => match x.as_ref() {
"Start game" => {
app.current_selection = None;
app.session
.upzones_per_level
.set(self.level.title.clone(), self.current_picks.clone());
app.session.save();
return Transition::Replace(Game::new(
ctx,
app,
self.level.clone(),
Vehicle::get(&app.session.current_vehicle),
self.current_picks.clone(),
self.current_picks.clone().into_iter().collect(),
));
}
"Randomly choose upzones" => {
self.randomly_pick_upzones(app);
self.upzone_panel = make_upzone_panel(ctx, app, self.current_picks.len());
}
"Clear upzones" => {
self.current_picks.clear();
self.upzone_panel = make_upzone_panel(ctx, app, self.current_picks.len());
}
"help" => {
return explain_upzoning(ctx);
}
@ -306,11 +322,19 @@ fn make_upzone_panel(ctx: &mut EventCtx, app: &App, num_picked: usize) -> Panel
"Upzones chosen:".draw_text(ctx),
make_bar(ctx, Color::PINK, num_picked, app.session.upzones_unlocked),
]),
if num_picked == app.session.upzones_unlocked {
Btn::text_fg("Randomly choose upzones").inactive(ctx)
} else {
Btn::text_fg("Randomly choose upzones").build_def(ctx, None)
},
Widget::row(vec![
if num_picked == app.session.upzones_unlocked {
Btn::text_fg("Randomly choose upzones").inactive(ctx)
} else {
Btn::text_fg("Randomly choose upzones").build_def(ctx, None)
},
if num_picked == 0 {
Btn::text_fg("Clear upzones").inactive(ctx)
} else {
Btn::text_fg("Clear upzones").build_def(ctx, None)
}
.align_right(),
]),
if num_picked == app.session.upzones_unlocked {
Btn::text_bg2("Start game").build_def(ctx, Key::Enter)
} else {

View File

@ -2,7 +2,8 @@ use std::collections::{BTreeSet, HashMap};
use serde::{Deserialize, Serialize};
use abstutil::Timer;
use abstutil::{deserialize_multimap, serialize_multimap, MultiMap, Timer};
use map_model::BuildingID;
use widgetry::{Color, EventCtx};
use crate::levels::Level;
@ -23,6 +24,14 @@ pub struct Session {
pub vehicles_unlocked: BTreeSet<String>,
pub upzones_unlocked: usize,
pub upzones_explained: bool,
// This was added after the main release, so keep old save files working by allowing it to be
// missing.
#[serde(
serialize_with = "serialize_multimap",
deserialize_with = "deserialize_multimap",
default
)]
pub upzones_per_level: MultiMap<String, BuildingID>,
#[serde(skip_serializing, skip_deserializing)]
pub music: Music,
@ -84,6 +93,7 @@ impl Session {
vehicles_unlocked: vec!["bike".to_string()].into_iter().collect(),
upzones_unlocked: 0,
upzones_explained: false,
upzones_per_level: MultiMap::new(),
music: Music::empty(),
play_music: true,