mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
use top-center panel for more things in all challenge modes. remove help
functions in favor of putting more info in the challenge description
This commit is contained in:
parent
67ebb76f94
commit
73680948b5
@ -83,7 +83,10 @@ impl ModalMenu {
|
||||
self.hovering_idx = None;
|
||||
if let Some(cursor) = ctx.canvas.get_cursor_in_screen_space() {
|
||||
let mut top_left = self.top_left;
|
||||
top_left.y += ctx.default_line_height() + ctx.text_dims(&self.info).height;
|
||||
top_left.y += ctx.text_dims(&self.info).height;
|
||||
if !self.title.is_empty() {
|
||||
top_left.y += ctx.default_line_height();
|
||||
}
|
||||
for idx in 0..self.choices.len() {
|
||||
let rect = ScreenRectangle {
|
||||
x1: top_left.x,
|
||||
@ -205,7 +208,11 @@ impl ModalMenu {
|
||||
}
|
||||
|
||||
fn calculate_txt(&self) -> Text {
|
||||
let mut txt = Text::prompt(&self.title);
|
||||
let mut txt = if self.title.is_empty() {
|
||||
Text::new().with_bg()
|
||||
} else {
|
||||
Text::prompt(&self.title)
|
||||
};
|
||||
txt.extend(&self.info);
|
||||
|
||||
for (idx, choice) in self.choices.iter().enumerate() {
|
||||
|
@ -16,7 +16,7 @@ use std::collections::{BTreeMap, HashSet};
|
||||
#[derive(Clone)]
|
||||
pub struct Challenge {
|
||||
title: String,
|
||||
description: Vec<String>,
|
||||
pub description: Vec<String>,
|
||||
pub map_path: String,
|
||||
pub alias: String,
|
||||
pub gameplay: GameplayMode,
|
||||
|
@ -9,7 +9,7 @@ mod warp;
|
||||
|
||||
pub use self::colors::{ColorLegend, Colorer, ColorerBuilder};
|
||||
pub use self::minimap::Minimap;
|
||||
pub use self::panels::{edit_map_panel, tool_panel};
|
||||
pub use self::panels::tool_panel;
|
||||
pub use self::warp::Warping;
|
||||
use crate::game::Transition;
|
||||
use crate::helpers::{list_names, ID};
|
||||
|
@ -1,10 +1,8 @@
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::Transition;
|
||||
use crate::managed::Composite;
|
||||
use crate::options;
|
||||
use crate::sandbox::GameplayMode;
|
||||
use ezgui::{
|
||||
hotkey, lctrl, Button, Color, EventCtx, HorizontalAlignment, Key, ManagedWidget, RewriteColor,
|
||||
hotkey, Button, Color, EventCtx, HorizontalAlignment, Key, ManagedWidget, RewriteColor,
|
||||
VerticalAlignment,
|
||||
};
|
||||
|
||||
@ -39,24 +37,3 @@ pub fn tool_panel(ctx: &mut EventCtx) -> Composite {
|
||||
Box::new(|_, _| Some(Transition::Push(options::open_panel()))),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn edit_map_panel(ctx: &mut EventCtx, gameplay: GameplayMode) -> Composite {
|
||||
Composite::new(
|
||||
ezgui::Composite::new(
|
||||
Composite::svg_button(ctx, "assets/tools/edit_map.svg", "edit map", lctrl(Key::E))
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx),
|
||||
)
|
||||
.cb(
|
||||
"edit map",
|
||||
Box::new(move |ctx, ui| {
|
||||
Some(Transition::Replace(Box::new(EditMode::new(
|
||||
ctx,
|
||||
ui,
|
||||
gameplay.clone(),
|
||||
))))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::common::edit_map_panel;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::game::Transition;
|
||||
use crate::managed::Composite;
|
||||
use crate::render::InnerAgentColorScheme;
|
||||
use crate::sandbox::gameplay::{cmp_count_fewer, manage_acs, GameplayMode, GameplayState};
|
||||
use crate::sandbox::gameplay::{
|
||||
challenge_controller, cmp_count_fewer, manage_acs, GameplayMode, GameplayState,
|
||||
};
|
||||
use crate::sandbox::overlays::Overlays;
|
||||
use crate::ui::UI;
|
||||
use abstutil::prettyprint_usize;
|
||||
@ -18,18 +19,11 @@ pub struct CreateGridlock {
|
||||
impl CreateGridlock {
|
||||
pub fn new(ctx: &mut EventCtx) -> (Composite, Box<dyn GameplayState>) {
|
||||
(
|
||||
edit_map_panel(ctx, GameplayMode::CreateGridlock),
|
||||
challenge_controller(ctx, GameplayMode::CreateGridlock, "Gridlock Challenge"),
|
||||
Box::new(CreateGridlock {
|
||||
time: Time::START_OF_DAY,
|
||||
menu: ModalMenu::new(
|
||||
"Cause gridlock",
|
||||
vec![
|
||||
(hotkey(Key::E), "show agent delay"),
|
||||
(hotkey(Key::H), "help"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
menu: ModalMenu::new("", vec![(hotkey(Key::E), "show agent delay")], ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -52,13 +46,6 @@ impl GameplayState for CreateGridlock {
|
||||
self.menu.set_info(ctx, gridlock_panel(ui));
|
||||
}
|
||||
|
||||
if self.menu.action("help") {
|
||||
return Some(Transition::Push(msg("Help", vec![
|
||||
"You might notice a few places in the map where gridlock forms already.",
|
||||
"You can make things worse!",
|
||||
"How few lanes can you close for construction before everything grinds to a halt?",
|
||||
])));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
use crate::common::edit_map_panel;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::game::Transition;
|
||||
use crate::managed::Composite;
|
||||
use crate::sandbox::gameplay::{cmp_count_more, cmp_duration_shorter, GameplayMode, GameplayState};
|
||||
use crate::sandbox::gameplay::{
|
||||
challenge_controller, cmp_count_more, cmp_duration_shorter, GameplayMode, GameplayState,
|
||||
};
|
||||
use crate::sandbox::overlays::Overlays;
|
||||
use crate::ui::UI;
|
||||
use abstutil::prettyprint_usize;
|
||||
use ezgui::{hotkey, layout, EventCtx, GfxCtx, Key, Line, ModalMenu, Text};
|
||||
use ezgui::{layout, EventCtx, GfxCtx, Line, ModalMenu, Text};
|
||||
use geom::{Statistic, Time};
|
||||
use sim::TripMode;
|
||||
|
||||
@ -18,16 +19,16 @@ pub struct FasterTrips {
|
||||
impl FasterTrips {
|
||||
pub fn new(trip_mode: TripMode, ctx: &mut EventCtx) -> (Composite, Box<dyn GameplayState>) {
|
||||
(
|
||||
edit_map_panel(ctx, GameplayMode::FasterTrips(trip_mode)),
|
||||
challenge_controller(
|
||||
ctx,
|
||||
GameplayMode::FasterTrips(trip_mode),
|
||||
&format!("Faster {} Trips Challenge", trip_mode),
|
||||
),
|
||||
Box::new(FasterTrips {
|
||||
mode: trip_mode,
|
||||
time: Time::START_OF_DAY,
|
||||
menu: ModalMenu::new(
|
||||
format!("Speed up {} trips", trip_mode),
|
||||
vec![(hotkey(Key::H), "help")],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
menu: ModalMenu::new::<&str, &str>("", Vec::new(), ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -42,12 +43,6 @@ impl GameplayState for FasterTrips {
|
||||
self.menu.set_info(ctx, faster_trips_panel(self.mode, ui));
|
||||
}
|
||||
|
||||
if self.menu.action("help") {
|
||||
return Some(Transition::Push(msg(
|
||||
"Help",
|
||||
vec!["How can you possibly speed up all trips of some mode?"],
|
||||
)));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::common::edit_map_panel;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::managed::Composite;
|
||||
use crate::sandbox::gameplay::faster_trips::small_faster_trips_panel;
|
||||
use crate::sandbox::gameplay::{manage_overlays, GameplayMode, GameplayState};
|
||||
use crate::sandbox::gameplay::{
|
||||
challenge_controller, manage_overlays, GameplayMode, GameplayState,
|
||||
};
|
||||
use crate::sandbox::overlays::Overlays;
|
||||
use crate::ui::UI;
|
||||
use ezgui::{hotkey, layout, EventCtx, GfxCtx, Key, ModalMenu};
|
||||
@ -19,16 +20,15 @@ pub struct FixTrafficSignals {
|
||||
impl FixTrafficSignals {
|
||||
pub fn new(ctx: &mut EventCtx, mode: GameplayMode) -> (Composite, Box<dyn GameplayState>) {
|
||||
(
|
||||
edit_map_panel(ctx, mode),
|
||||
challenge_controller(ctx, mode, "Traffic Signals Challenge"),
|
||||
Box::new(FixTrafficSignals {
|
||||
time: Time::START_OF_DAY,
|
||||
once: true,
|
||||
menu: ModalMenu::new(
|
||||
"Fix traffic signals",
|
||||
"",
|
||||
vec![
|
||||
(hotkey(Key::F), "find slowest traffic signals"),
|
||||
(hotkey(Key::D), "hide finished trip distribution"),
|
||||
(hotkey(Key::H), "help"),
|
||||
(hotkey(Key::S), "final score"),
|
||||
],
|
||||
ctx,
|
||||
@ -88,15 +88,6 @@ impl GameplayState for FixTrafficSignals {
|
||||
.set_info(ctx, small_faster_trips_panel(TripMode::Drive, ui));
|
||||
}
|
||||
|
||||
if self.menu.action("help") {
|
||||
return Some(Transition::Push(msg(
|
||||
"Help",
|
||||
vec![
|
||||
"All of the traffic signals follow one timing plan through the whole day.",
|
||||
"(Due to budget cuts, none of the vehicle-actuated signals are working -- don't worry if you don't know what these are.)",
|
||||
])));
|
||||
}
|
||||
|
||||
if self.menu.action("final score") {
|
||||
return Some(Transition::Push(msg("Final score", final_score(ui))));
|
||||
}
|
||||
|
@ -6,20 +6,26 @@ mod optimize_bus;
|
||||
mod play_scenario;
|
||||
pub mod spawner;
|
||||
|
||||
use crate::game::Transition;
|
||||
use crate::challenges;
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::managed::{Composite, Outcome};
|
||||
use crate::render::{AgentColorScheme, InnerAgentColorScheme};
|
||||
use crate::sandbox::overlays::Overlays;
|
||||
use crate::sandbox::SandboxMode;
|
||||
use crate::ui::UI;
|
||||
use abstutil::{prettyprint_usize, Timer};
|
||||
use ezgui::{Color, EventCtx, GfxCtx, Line, ModalMenu, TextSpan, Wizard};
|
||||
use geom::Duration;
|
||||
use ezgui::{
|
||||
lctrl, Color, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, ManagedWidget,
|
||||
ModalMenu, Text, TextSpan, VerticalAlignment, Wizard,
|
||||
};
|
||||
use geom::{Duration, Polygon};
|
||||
use map_model::{EditCmd, Map, MapEdits};
|
||||
use sim::{Analytics, Scenario, TripMode};
|
||||
|
||||
pub struct GameplayRunner {
|
||||
pub mode: GameplayMode,
|
||||
// TODO Why not make each state own this?
|
||||
controller: Composite,
|
||||
state: Box<dyn GameplayState>,
|
||||
}
|
||||
@ -321,3 +327,51 @@ pub fn cmp_count_more(now: usize, baseline: usize) -> TextSpan {
|
||||
Line("same as baseline")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn challenge_controller(ctx: &mut EventCtx, gameplay: GameplayMode, title: &str) -> Composite {
|
||||
// Scrape the description
|
||||
let mut description = Vec::new();
|
||||
'OUTER: for (_, stages) in challenges::all_challenges() {
|
||||
for challenge in stages {
|
||||
if challenge.gameplay == gameplay {
|
||||
description = challenge.description.clone();
|
||||
break 'OUTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Composite::new(
|
||||
ezgui::Composite::new(
|
||||
ManagedWidget::row(vec![
|
||||
ManagedWidget::draw_text(ctx, Text::from(Line(title).size(26))).margin(5),
|
||||
Composite::svg_button(ctx, "assets/tools/info.svg", "info", None).margin(5),
|
||||
ManagedWidget::draw_batch(
|
||||
ctx,
|
||||
GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 50.0))]),
|
||||
)
|
||||
.margin(5),
|
||||
Composite::svg_button(ctx, "assets/tools/edit_map.svg", "edit map", lctrl(Key::E))
|
||||
.margin(5),
|
||||
])
|
||||
.centered()
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx),
|
||||
)
|
||||
.cb(
|
||||
"edit map",
|
||||
Box::new(move |ctx, ui| {
|
||||
Some(Transition::Replace(Box::new(EditMode::new(
|
||||
ctx,
|
||||
ui,
|
||||
gameplay.clone(),
|
||||
))))
|
||||
}),
|
||||
)
|
||||
// TODO msg() is silly, it's hard to plumb the title. Also, show the challenge splash screen.
|
||||
.cb(
|
||||
"info",
|
||||
Box::new(move |_, _| Some(Transition::Push(msg("Challenge", description.clone())))),
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::common::edit_map_panel;
|
||||
use crate::game::{msg, Transition, WizardState};
|
||||
use crate::game::{Transition, WizardState};
|
||||
use crate::sandbox::gameplay::{
|
||||
cmp_duration_shorter, manage_overlays, GameplayMode, GameplayState,
|
||||
challenge_controller, cmp_duration_shorter, manage_overlays, GameplayMode, GameplayState,
|
||||
};
|
||||
use crate::sandbox::overlays::Overlays;
|
||||
use crate::sandbox::SandboxMode;
|
||||
@ -25,19 +24,22 @@ impl OptimizeBus {
|
||||
) -> (crate::managed::Composite, Box<dyn GameplayState>) {
|
||||
let route = ui.primary.map.get_bus_route(&route_name).unwrap();
|
||||
(
|
||||
edit_map_panel(ctx, GameplayMode::OptimizeBus(route_name.clone())),
|
||||
challenge_controller(
|
||||
ctx,
|
||||
GameplayMode::OptimizeBus(route_name.clone()),
|
||||
&format!("Optimize {} Challenge", route_name),
|
||||
),
|
||||
Box::new(OptimizeBus {
|
||||
route: route.id,
|
||||
time: Time::START_OF_DAY,
|
||||
stat: Statistic::Max,
|
||||
menu: ModalMenu::new(
|
||||
format!("Optimize {}", route_name),
|
||||
"",
|
||||
vec![
|
||||
(hotkey(Key::E), "show bus route"),
|
||||
(hotkey(Key::T), "show delays over time"),
|
||||
(hotkey(Key::P), "show bus passengers"),
|
||||
(hotkey(Key::S), "change statistic"),
|
||||
(hotkey(Key::H), "help"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
@ -129,17 +131,6 @@ impl GameplayState for OptimizeBus {
|
||||
},
|
||||
))));
|
||||
}
|
||||
if self.menu.action("help") {
|
||||
return Some(Transition::Push(msg(
|
||||
"Help",
|
||||
vec![
|
||||
"First find where the bus gets stuck.",
|
||||
"Then use edit mode to try to speed things up.",
|
||||
"Try making dedicated bus lanes",
|
||||
"and adjusting traffic signals.",
|
||||
],
|
||||
)));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user