mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +03:00
Remember the upzoned buildings, and add a button to clear the choices. #431
This commit is contained in:
parent
af5811c33c
commit
f8ac0fc96b
@ -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> {
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user