mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 19:27:11 +03:00
give ownership of the top-center panel to each gameplay state
This commit is contained in:
parent
78344ee2a4
commit
92c6b8e282
@ -1,6 +1,6 @@
|
||||
use crate::game::Transition;
|
||||
use crate::helpers::cmp_count_fewer;
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::render::InnerAgentColorScheme;
|
||||
use crate::sandbox::gameplay::{challenge_controller, manage_acs, GameplayMode, GameplayState};
|
||||
use crate::ui::UI;
|
||||
@ -12,23 +12,34 @@ use sim::TripMode;
|
||||
pub struct CreateGridlock {
|
||||
time: Time,
|
||||
menu: ModalMenu,
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl CreateGridlock {
|
||||
pub fn new(ctx: &mut EventCtx) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
(
|
||||
challenge_controller(ctx, GameplayMode::CreateGridlock, "Gridlock Challenge"),
|
||||
Box::new(CreateGridlock {
|
||||
time: Time::START_OF_DAY,
|
||||
menu: ModalMenu::new("", vec![(hotkey(Key::E), "show agent delay")], ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
pub fn new(ctx: &mut EventCtx) -> Box<dyn GameplayState> {
|
||||
Box::new(CreateGridlock {
|
||||
time: Time::START_OF_DAY,
|
||||
menu: ModalMenu::new("", vec![(hotkey(Key::E), "show agent delay")], ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
top_center: challenge_controller(
|
||||
ctx,
|
||||
GameplayMode::CreateGridlock,
|
||||
"Gridlock Challenge",
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayState for CreateGridlock {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
|
||||
self.menu.event(ctx);
|
||||
manage_acs(
|
||||
&mut self.menu,
|
||||
@ -48,6 +59,7 @@ impl GameplayState for CreateGridlock {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.top_center.draw(g);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::game::Transition;
|
||||
use crate::helpers::{cmp_count_more, cmp_duration_shorter};
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::sandbox::gameplay::{challenge_controller, GameplayMode, GameplayState};
|
||||
use crate::ui::UI;
|
||||
use abstutil::prettyprint_usize;
|
||||
@ -12,31 +12,34 @@ pub struct FasterTrips {
|
||||
mode: TripMode,
|
||||
time: Time,
|
||||
menu: ModalMenu,
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl FasterTrips {
|
||||
pub fn new(
|
||||
trip_mode: TripMode,
|
||||
ctx: &mut EventCtx,
|
||||
) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
(
|
||||
challenge_controller(
|
||||
pub fn new(trip_mode: TripMode, ctx: &mut EventCtx) -> Box<dyn GameplayState> {
|
||||
Box::new(FasterTrips {
|
||||
mode: trip_mode,
|
||||
time: Time::START_OF_DAY,
|
||||
menu: ModalMenu::new::<&str, &str>("", Vec::new(), ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
top_center: 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::<&str, &str>("", Vec::new(), ctx)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayState for FasterTrips {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
self.menu.event(ctx);
|
||||
|
||||
if self.time != ui.primary.sim.time() {
|
||||
@ -48,6 +51,7 @@ impl GameplayState for FasterTrips {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.top_center.draw(g);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::common::Overlays;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::helpers::cmp_duration_shorter;
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::sandbox::gameplay::{
|
||||
challenge_controller, manage_overlays, GameplayMode, GameplayState,
|
||||
};
|
||||
@ -15,30 +15,26 @@ pub struct FixTrafficSignals {
|
||||
time: Time,
|
||||
once: bool,
|
||||
menu: ModalMenu,
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl FixTrafficSignals {
|
||||
pub fn new(
|
||||
ctx: &mut EventCtx,
|
||||
mode: GameplayMode,
|
||||
) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
(
|
||||
challenge_controller(ctx, mode, "Traffic Signals Challenge"),
|
||||
Box::new(FixTrafficSignals {
|
||||
time: Time::START_OF_DAY,
|
||||
once: true,
|
||||
menu: ModalMenu::new(
|
||||
"",
|
||||
vec![
|
||||
(hotkey(Key::F), "find slowest traffic signals"),
|
||||
(hotkey(Key::D), "hide finished trip distribution"),
|
||||
(hotkey(Key::S), "final score"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
pub fn new(ctx: &mut EventCtx, mode: GameplayMode) -> Box<dyn GameplayState> {
|
||||
Box::new(FixTrafficSignals {
|
||||
time: Time::START_OF_DAY,
|
||||
once: true,
|
||||
menu: ModalMenu::new(
|
||||
"",
|
||||
vec![
|
||||
(hotkey(Key::F), "find slowest traffic signals"),
|
||||
(hotkey(Key::D), "hide finished trip distribution"),
|
||||
(hotkey(Key::S), "final score"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
top_center: challenge_controller(ctx, mode, "Traffic Signals Challenge"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +46,13 @@ impl GameplayState for FixTrafficSignals {
|
||||
self.once = false;
|
||||
}
|
||||
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
self.menu.event(ctx);
|
||||
|
||||
// Technically this shows stop signs too, but mostly the bottlenecks are signals.
|
||||
@ -111,6 +114,7 @@ impl GameplayState for FixTrafficSignals {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.top_center.draw(g);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::{State, Transition, WizardState};
|
||||
use crate::helpers::{nice_map_name, ID};
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::sandbox::gameplay::{change_scenario, spawner, GameplayMode, GameplayState};
|
||||
use crate::sandbox::SandboxMode;
|
||||
use crate::ui::UI;
|
||||
@ -17,21 +17,28 @@ use std::collections::BTreeSet;
|
||||
pub struct Freeform {
|
||||
// TODO Clean these up later when done?
|
||||
pub spawn_pts: BTreeSet<IntersectionID>,
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl Freeform {
|
||||
pub fn new(ctx: &mut EventCtx, ui: &UI) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
(
|
||||
freeform_controller(ctx, ui, GameplayMode::Freeform, "none"),
|
||||
Box::new(Freeform {
|
||||
spawn_pts: BTreeSet::new(),
|
||||
}),
|
||||
)
|
||||
pub fn new(ctx: &mut EventCtx, ui: &UI) -> Box<dyn GameplayState> {
|
||||
Box::new(Freeform {
|
||||
spawn_pts: BTreeSet::new(),
|
||||
top_center: freeform_controller(ctx, ui, GameplayMode::Freeform, "none"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayState for Freeform {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
|
||||
if let Some(new_state) = spawner::AgentSpawner::new(ctx, ui) {
|
||||
return Some(Transition::Push(new_state));
|
||||
}
|
||||
@ -42,6 +49,7 @@ impl GameplayState for Freeform {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
||||
self.top_center.draw(g);
|
||||
// TODO Overriding draw options would be ideal, but...
|
||||
for i in &self.spawn_pts {
|
||||
g.draw_polygon(Color::GREEN.alpha(0.8), &ui.primary.map.get_i(*i).polygon);
|
||||
|
@ -10,7 +10,7 @@ use crate::challenges;
|
||||
use crate::common::Overlays;
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::{msg, Transition};
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::render::{AgentColorScheme, InnerAgentColorScheme};
|
||||
use crate::sandbox::SandboxMode;
|
||||
use crate::ui::UI;
|
||||
@ -25,8 +25,6 @@ use sim::{Analytics, Scenario, TripMode};
|
||||
|
||||
pub struct GameplayRunner {
|
||||
pub mode: GameplayMode,
|
||||
// TODO Why not make each state own this?
|
||||
controller: WrappedComposite,
|
||||
state: Box<dyn GameplayState>,
|
||||
}
|
||||
|
||||
@ -137,7 +135,7 @@ impl GameplayMode {
|
||||
|
||||
impl GameplayRunner {
|
||||
pub fn initialize(mode: GameplayMode, ui: &mut UI, ctx: &mut EventCtx) -> GameplayRunner {
|
||||
let (controller, state) = match mode.clone() {
|
||||
let state = match mode.clone() {
|
||||
GameplayMode::Freeform => freeform::Freeform::new(ctx, ui),
|
||||
GameplayMode::PlayScenario(scenario) => {
|
||||
play_scenario::PlayScenario::new(&scenario, ctx, ui)
|
||||
@ -186,26 +184,14 @@ impl GameplayRunner {
|
||||
}
|
||||
}
|
||||
});
|
||||
GameplayRunner {
|
||||
mode,
|
||||
controller,
|
||||
state,
|
||||
}
|
||||
GameplayRunner { mode, state }
|
||||
}
|
||||
|
||||
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.controller.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
self.state.event(ctx, ui)
|
||||
}
|
||||
|
||||
pub fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
||||
self.controller.draw(g);
|
||||
self.state.draw(g, ui);
|
||||
}
|
||||
}
|
||||
@ -298,7 +284,7 @@ fn manage_acs(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn challenge_controller(
|
||||
fn challenge_controller(
|
||||
ctx: &mut EventCtx,
|
||||
gameplay: GameplayMode,
|
||||
title: &str,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::common::Overlays;
|
||||
use crate::game::{Transition, WizardState};
|
||||
use crate::helpers::cmp_duration_shorter;
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::sandbox::gameplay::{
|
||||
challenge_controller, manage_overlays, GameplayMode, GameplayState,
|
||||
};
|
||||
@ -16,43 +16,45 @@ pub struct OptimizeBus {
|
||||
time: Time,
|
||||
stat: Statistic,
|
||||
menu: ModalMenu,
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl OptimizeBus {
|
||||
pub fn new(
|
||||
route_name: String,
|
||||
ctx: &mut EventCtx,
|
||||
ui: &UI,
|
||||
) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
pub fn new(route_name: String, ctx: &mut EventCtx, ui: &UI) -> Box<dyn GameplayState> {
|
||||
let route = ui.primary.map.get_bus_route(&route_name).unwrap();
|
||||
(
|
||||
challenge_controller(
|
||||
Box::new(OptimizeBus {
|
||||
route: route.id,
|
||||
time: Time::START_OF_DAY,
|
||||
stat: Statistic::Max,
|
||||
menu: ModalMenu::new(
|
||||
"",
|
||||
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"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
top_center: 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(
|
||||
"",
|
||||
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"),
|
||||
],
|
||||
ctx,
|
||||
)
|
||||
.set_standalone_layout(layout::ContainerOrientation::TopLeftButDownABit(150.0)),
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayState for OptimizeBus {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
self.menu.event(ctx);
|
||||
if manage_overlays(
|
||||
&mut self.menu,
|
||||
@ -132,6 +134,7 @@ impl GameplayState for OptimizeBus {
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.top_center.draw(g);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,41 @@
|
||||
use crate::game::Transition;
|
||||
use crate::managed::WrappedComposite;
|
||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||
use crate::sandbox::gameplay::freeform::freeform_controller;
|
||||
use crate::sandbox::gameplay::{GameplayMode, GameplayState};
|
||||
use crate::ui::UI;
|
||||
use ezgui::{EventCtx, GfxCtx};
|
||||
|
||||
pub struct PlayScenario;
|
||||
pub struct PlayScenario {
|
||||
top_center: WrappedComposite,
|
||||
}
|
||||
|
||||
impl PlayScenario {
|
||||
pub fn new(
|
||||
name: &String,
|
||||
ctx: &mut EventCtx,
|
||||
ui: &UI,
|
||||
) -> (WrappedComposite, Box<dyn GameplayState>) {
|
||||
(
|
||||
freeform_controller(ctx, ui, GameplayMode::PlayScenario(name.to_string()), name),
|
||||
Box::new(PlayScenario),
|
||||
)
|
||||
pub fn new(name: &String, ctx: &mut EventCtx, ui: &UI) -> Box<dyn GameplayState> {
|
||||
Box::new(PlayScenario {
|
||||
top_center: freeform_controller(
|
||||
ctx,
|
||||
ui,
|
||||
GameplayMode::PlayScenario(name.to_string()),
|
||||
name,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayState for PlayScenario {
|
||||
fn event(&mut self, _: &mut EventCtx, _: &mut UI) -> Option<Transition> {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
|
||||
match self.top_center.event(ctx, ui) {
|
||||
Some(WrappedOutcome::Transition(t)) => {
|
||||
return Some(t);
|
||||
}
|
||||
Some(WrappedOutcome::Clicked(_)) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn draw(&self, _: &mut GfxCtx, _: &UI) {}
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.top_center.draw(g);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user