diff --git a/data/system/override_colors.json b/data/system/override_colors.json index c7d0c4016f..82741b5077 100644 --- a/data/system/override_colors.json +++ b/data/system/override_colors.json @@ -15,14 +15,14 @@ "#0F7D4B", 1.0 ], - "blinker on": [ - "#FF0000", - 1.0 - ], "border intersection": [ "#32CD32", 1.0 ], + "brake light": [ + "#FF1300", + 1.0 + ], "building": [ "#C4C1BC", 1.0 @@ -47,10 +47,6 @@ "#00FFFF", 1.0 ], - "car window": [ - "#000000", - 1.0 - ], "change lanes left turn": [ "#00FFFF", 1.0 @@ -115,14 +111,6 @@ "#DDDDDD", 1.0 ], - "moving bike": [ - "#00FF00", - 1.0 - ], - "moving car": [ - "#00FFFF", - 1.0 - ], "neighborhood last placed point": [ "#00FF00", 1.0 @@ -159,7 +147,7 @@ "#333333", 1.0 ], - "pedestrian": [ + "pedestrian crowd": [ "#33B2B2", 1.0 ], @@ -251,6 +239,10 @@ "#000000", 1.0 ], + "turn arrow": [ + "#DF8C3D", + 1.0 + ], "turn block background": [ "#999999", 1.0 diff --git a/docs/dev.md b/docs/dev.md index 71eb8652fa..e08080e2e7 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -14,7 +14,8 @@ One-time setup: 2. Build all input data. This is very slow, so you should seed from a pre-built copy: `./data/grab_seed_data.sh`. This will download about 1GB and expand to - about 5GB. + about 5GB. If you see version controlled files change after doing this, it + means I need to upload a new package; please let me know. 3. Run the game: `cd game; cargo run --release` diff --git a/game/src/helpers.rs b/game/src/helpers.rs index 5d81ff1b66..882465df45 100644 --- a/game/src/helpers.rs +++ b/game/src/helpers.rs @@ -117,7 +117,11 @@ impl ColorScheme { } pub fn get(&self, name: &str) -> Color { - self.0[name] + if let Some(c) = self.0.get(name) { + *c + } else { + panic!("Color {} undefined", name); + } } } diff --git a/game/src/render/bike.rs b/game/src/render/bike.rs index cf96c144a0..99b7f42073 100644 --- a/game/src/render/bike.rs +++ b/game/src/render/bike.rs @@ -1,5 +1,5 @@ -use crate::helpers::{ColorScheme, ID}; -use crate::render::{AgentColorScheme, DrawCtx, DrawOptions, Renderable}; +use crate::helpers::{rotating_color_agents, ColorScheme, ID}; +use crate::render::{DrawCtx, DrawOptions, Renderable}; use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender}; use geom::{Circle, Distance, Line, PolyLine, Polygon}; use map_model::{Map, LANE_THICKNESS}; @@ -20,13 +20,12 @@ impl DrawBike { map: &Map, prerender: &Prerender, cs: &ColorScheme, - acs: AgentColorScheme, ) -> DrawBike { let mut draw_default = GeomBatch::new(); // TODO Share constants with DrawPedestrian let body_radius = LANE_THICKNESS / 4.0; - let body_color = acs.zoomed_color_bike(&input, cs); + let body_color = zoomed_color_bike(&input); draw_default.push( cs.get_def("bike frame", Color::rgb(0, 128, 128)), input.body.make_polygons(Distance::meters(0.4)), @@ -115,3 +114,7 @@ impl Renderable for DrawBike { self.zorder } } + +fn zoomed_color_bike(input: &DrawCarInput) -> Color { + rotating_color_agents(input.id.0) +} diff --git a/game/src/render/car.rs b/game/src/render/car.rs index 3f14c21a44..828826ed14 100644 --- a/game/src/render/car.rs +++ b/game/src/render/car.rs @@ -1,9 +1,9 @@ -use crate::helpers::{ColorScheme, ID}; -use crate::render::{AgentColorScheme, DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS}; +use crate::helpers::{rotating_color_agents, ColorScheme, ID}; +use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS}; use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text}; use geom::{Angle, Distance, PolyLine, Polygon, Pt2D}; use map_model::{Map, TurnType}; -use sim::{CarID, DrawCarInput}; +use sim::{CarID, CarStatus, DrawCarInput, VehicleType}; const CAR_WIDTH: Distance = Distance::const_meters(1.75); @@ -18,13 +18,7 @@ pub struct DrawCar { } impl DrawCar { - pub fn new( - input: DrawCarInput, - map: &Map, - prerender: &Prerender, - cs: &ColorScheme, - acs: AgentColorScheme, - ) -> DrawCar { + pub fn new(input: DrawCarInput, map: &Map, prerender: &Prerender, cs: &ColorScheme) -> DrawCar { let mut draw_default = GeomBatch::new(); let body_polygon = { let len = input.body.length(); @@ -45,7 +39,7 @@ impl DrawCar { front.union(thick_line) }; - draw_default.push(acs.zoomed_color_car(&input, cs), body_polygon.clone()); + draw_default.push(zoomed_color_car(&input, cs), body_polygon.clone()); { let arrow_len = 0.8 * CAR_WIDTH; @@ -163,3 +157,14 @@ fn thick_line_from_angle( // Shouldn't ever fail for a single line PolyLine::new(vec![pt, pt2]).make_polygons(thickness) } + +fn zoomed_color_car(input: &DrawCarInput, cs: &ColorScheme) -> Color { + if input.id.1 == VehicleType::Bus { + cs.get_def("bus", Color::rgb(50, 133, 117)) + } else { + match input.status { + CarStatus::Moving => rotating_color_agents(input.id.0), + CarStatus::Parked => cs.get_def("parked car", Color::rgb(180, 233, 76)), + } + } +} diff --git a/game/src/render/map.rs b/game/src/render/map.rs index 8521753d15..fc1f4dcfed 100644 --- a/game/src/render/map.rs +++ b/game/src/render/map.rs @@ -1,4 +1,4 @@ -use crate::helpers::{rotating_color, rotating_color_agents, ColorScheme, ID}; +use crate::helpers::{rotating_color, ColorScheme, ID}; use crate::render::area::DrawArea; use crate::render::building::DrawBuilding; use crate::render::bus_stop::DrawBusStop; @@ -16,10 +16,7 @@ use map_model::{ AreaID, BuildingID, BusStopID, DirectedRoadID, Intersection, IntersectionID, LaneID, Map, Road, RoadID, Traversable, LANE_THICKNESS, }; -use sim::{ - AgentMetadata, CarStatus, DrawCarInput, DrawPedestrianInput, GetDrawAgents, UnzoomedAgent, - VehicleType, -}; +use sim::{GetDrawAgents, UnzoomedAgent, VehicleType}; use std::borrow::Borrow; use std::cell::RefCell; use std::collections::HashMap; @@ -393,7 +390,6 @@ fn osm_rank_to_color(cs: &ColorScheme, rank: usize) -> Color { // TODO ETA till goal... #[derive(Clone, Copy, PartialEq)] pub enum AgentColorScheme { - ByID, VehicleTypes, Delay, DistanceCrossedSoFar, @@ -405,73 +401,23 @@ impl Cloneable for AgentColorScheme {} impl AgentColorScheme { pub fn unzoomed_color(self, agent: &UnzoomedAgent, cs: &ColorScheme) -> Color { match self { - // ByID should just act like VehicleTypes unzoomed - AgentColorScheme::VehicleTypes | AgentColorScheme::ByID => match agent.vehicle_type { + AgentColorScheme::VehicleTypes => match agent.vehicle_type { Some(VehicleType::Car) => cs.get_def("unzoomed car", Color::RED.alpha(0.5)), Some(VehicleType::Bike) => cs.get_def("unzoomed bike", Color::GREEN.alpha(0.5)), Some(VehicleType::Bus) => cs.get_def("unzoomed bus", Color::BLUE.alpha(0.5)), None => cs.get_def("unzoomed pedestrian", Color::ORANGE.alpha(0.5)), }, - _ => self.by_metadata(&agent.metadata), - } - } - - pub fn zoomed_color_car(self, input: &DrawCarInput, cs: &ColorScheme) -> Color { - match self { - AgentColorScheme::ByID => rotating_color_agents(input.id.0), - AgentColorScheme::VehicleTypes => { - if input.id.1 == VehicleType::Bus { - cs.get_def("bus", Color::rgb(50, 133, 117)) - } else { - match input.status { - CarStatus::Moving => cs.get_def("moving car", Color::CYAN), - CarStatus::Parked => cs.get_def("parked car", Color::rgb(180, 233, 76)), - } - } + AgentColorScheme::Delay => delay_color(agent.metadata.time_spent_blocked), + AgentColorScheme::DistanceCrossedSoFar => { + percent_color(agent.metadata.percent_dist_crossed) } - _ => self.by_metadata(&input.metadata), - } - } - - pub fn zoomed_color_bike(self, input: &DrawCarInput, cs: &ColorScheme) -> Color { - match self { - AgentColorScheme::ByID => rotating_color_agents(input.id.0), - AgentColorScheme::VehicleTypes => match input.status { - // TODO Hard to see on the greenish bike lanes? :P - CarStatus::Moving => cs.get_def("moving bike", Color::GREEN), - CarStatus::Parked => unreachable!(), - }, - _ => self.by_metadata(&input.metadata), - } - } - - pub fn zoomed_color_ped(self, input: &DrawPedestrianInput, cs: &ColorScheme) -> Color { - match self { - AgentColorScheme::ByID => rotating_color_agents(input.id.0), - AgentColorScheme::VehicleTypes => { - if input.preparing_bike { - cs.get_def("pedestrian preparing bike", Color::rgb(255, 0, 144)) - } else { - cs.get_def("pedestrian", Color::rgb_f(0.2, 0.7, 0.7)) - } - } - _ => self.by_metadata(&input.metadata), - } - } - - fn by_metadata(self, md: &AgentMetadata) -> Color { - match self { - AgentColorScheme::VehicleTypes | AgentColorScheme::ByID => unreachable!(), - AgentColorScheme::Delay => delay_color(md.time_spent_blocked), - AgentColorScheme::DistanceCrossedSoFar => percent_color(md.percent_dist_crossed), - AgentColorScheme::TripTimeSoFar => delay_color(md.trip_time_so_far), + AgentColorScheme::TripTimeSoFar => delay_color(agent.metadata.trip_time_so_far), } } // TODO Lots of duplicated values here. :\ pub fn color_legend_entries(self, cs: &ColorScheme) -> (&str, Vec<(&str, Color)>) { match self { - AgentColorScheme::ByID => ("arbitrary colors", Vec::new()), AgentColorScheme::VehicleTypes => ( "vehicle types", vec![ @@ -518,7 +464,6 @@ impl AgentColorScheme { pub fn all() -> Vec<(AgentColorScheme, String)> { vec![ - (AgentColorScheme::ByID, "arbitrary colors".to_string()), ( AgentColorScheme::VehicleTypes, "by vehicle type".to_string(), diff --git a/game/src/render/mod.rs b/game/src/render/mod.rs index 8f1d9b19b4..62c6b2b2fd 100644 --- a/game/src/render/mod.rs +++ b/game/src/render/mod.rs @@ -66,12 +66,11 @@ pub fn draw_vehicle( map: &Map, prerender: &Prerender, cs: &ColorScheme, - acs: AgentColorScheme, ) -> Box { if input.id.1 == VehicleType::Bike { - Box::new(DrawBike::new(input, map, prerender, cs, acs)) + Box::new(DrawBike::new(input, map, prerender, cs)) } else { - Box::new(DrawCar::new(input, map, prerender, cs, acs)) + Box::new(DrawCar::new(input, map, prerender, cs)) } } diff --git a/game/src/render/pedestrian.rs b/game/src/render/pedestrian.rs index e2332c71f0..f165e6be0e 100644 --- a/game/src/render/pedestrian.rs +++ b/game/src/render/pedestrian.rs @@ -1,5 +1,5 @@ -use crate::helpers::{ColorScheme, ID}; -use crate::render::{AgentColorScheme, DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS}; +use crate::helpers::{rotating_color_agents, ColorScheme, ID}; +use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS}; use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text}; use geom::{Circle, Distance, PolyLine, Polygon}; use map_model::{Map, LANE_THICKNESS}; @@ -20,7 +20,6 @@ impl DrawPedestrian { map: &Map, prerender: &Prerender, cs: &ColorScheme, - acs: AgentColorScheme, ) -> DrawPedestrian { // TODO Slight issues with rendering small pedestrians: // - route visualization is thick @@ -123,7 +122,7 @@ impl DrawPedestrian { }; let head_circle = Circle::new(input.pos, 0.5 * radius); - draw_default.push(acs.zoomed_color_ped(&input, cs), body_circle.to_polygon()); + draw_default.push(zoomed_color_ped(&input, cs), body_circle.to_polygon()); draw_default.push( cs.get_def("pedestrian head", Color::rgb(139, 69, 19)), head_circle.to_polygon(), @@ -209,7 +208,10 @@ impl DrawPedCrowd { .exact_slice(input.low, input.high), }; let blob = pl_shifted.make_polygons(LANE_THICKNESS / 2.0); - let draw_default = prerender.upload_borrowed(vec![(cs.get("pedestrian"), &blob)]); + let draw_default = prerender.upload_borrowed(vec![( + cs.get_def("pedestrian crowd", Color::rgb_f(0.2, 0.7, 0.7)), + &blob, + )]); // Ideally "pedestrian head" color, but it looks really faded... let label = Text::from( @@ -257,3 +259,10 @@ impl Renderable for DrawPedCrowd { self.zorder } } +fn zoomed_color_ped(input: &DrawPedestrianInput, cs: &ColorScheme) -> Color { + if input.preparing_bike { + cs.get_def("pedestrian preparing bike", Color::rgb(255, 0, 144)) + } else { + rotating_color_agents(input.id.0) + } +} diff --git a/game/src/sandbox/gameplay/mod.rs b/game/src/sandbox/gameplay/mod.rs index f68299c984..c74727366e 100644 --- a/game/src/sandbox/gameplay/mod.rs +++ b/game/src/sandbox/gameplay/mod.rs @@ -299,7 +299,7 @@ fn manage_acs( if !active_originally && menu.swap_action(show, hide, ctx) { ui.agent_cs = acs; } else if active_originally && menu.swap_action(hide, show, ctx) { - ui.agent_cs = AgentColorScheme::ByID; + ui.agent_cs = AgentColorScheme::VehicleTypes; } } diff --git a/game/src/ui.rs b/game/src/ui.rs index 787524489a..88ee72a103 100644 --- a/game/src/ui.rs +++ b/game/src/ui.rs @@ -17,6 +17,8 @@ pub struct UI { // Invariant: This is Some(...) iff we're in A/B test mode or a sub-state. pub secondary: Option, pub cs: ColorScheme, + // TODO This is a bit weird to keep here; it's controlled almost entirely by the minimap panel. + // It has no meaning in edit mode. pub agent_cs: AgentColorScheme, pub opts: Options, @@ -67,7 +69,7 @@ impl UI { UI { primary, secondary: None, - agent_cs: AgentColorScheme::ByID, + agent_cs: AgentColorScheme::VehicleTypes, cs, opts, per_obj: PerObjectActions::new(), @@ -337,17 +339,12 @@ impl UI { if !agents.has(time, *on) { let mut list: Vec> = Vec::new(); for c in source.get_draw_cars(*on, map).into_iter() { - list.push(draw_vehicle(c, map, prerender, &self.cs, self.agent_cs)); + list.push(draw_vehicle(c, map, prerender, &self.cs)); } let (loners, crowds) = source.get_draw_peds(*on, map); for p in loners { list.push(Box::new(DrawPedestrian::new( - p, - step_count, - map, - prerender, - &self.cs, - self.agent_cs, + p, step_count, map, prerender, &self.cs, ))); } for c in crowds {