mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 12:43:38 +03:00
try again or back out of challenge after final score
This commit is contained in:
parent
a0ec59b6c3
commit
c62ca1a125
@ -5,7 +5,7 @@
|
|||||||
You will first need:
|
You will first need:
|
||||||
|
|
||||||
- Standard dependencies: `bash`, `curl`, `unzip`, `gunzip`
|
- Standard dependencies: `bash`, `curl`, `unzip`, `gunzip`
|
||||||
- Rust, at least 1.40. https://www.rust-lang.org/tools/install
|
- Rust, at least 1.41. https://www.rust-lang.org/tools/install
|
||||||
|
|
||||||
One-time setup:
|
One-time setup:
|
||||||
|
|
||||||
|
@ -81,11 +81,11 @@ impl GUI for Game {
|
|||||||
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
|
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
|
||||||
self.states.push(state);
|
self.states.push(state);
|
||||||
}
|
}
|
||||||
Transition::Clear(state) => {
|
Transition::Clear(states) => {
|
||||||
while !self.states.is_empty() {
|
while !self.states.is_empty() {
|
||||||
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
|
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
|
||||||
}
|
}
|
||||||
self.states.push(state);
|
self.states.extend(states);
|
||||||
}
|
}
|
||||||
Transition::ApplyObjectAction(action) => {
|
Transition::ApplyObjectAction(action) => {
|
||||||
self.ui.per_obj.action_chosen(action);
|
self.ui.per_obj.action_chosen(action);
|
||||||
@ -187,7 +187,7 @@ pub enum Transition {
|
|||||||
Push(Box<dyn State>),
|
Push(Box<dyn State>),
|
||||||
Replace(Box<dyn State>),
|
Replace(Box<dyn State>),
|
||||||
PopThenReplace(Box<dyn State>),
|
PopThenReplace(Box<dyn State>),
|
||||||
Clear(Box<dyn State>),
|
Clear(Vec<Box<dyn State>>),
|
||||||
ApplyObjectAction(String),
|
ApplyObjectAction(String),
|
||||||
PushTwice(Box<dyn State>, Box<dyn State>),
|
PushTwice(Box<dyn State>, Box<dyn State>),
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::common::Overlays;
|
use crate::common::Overlays;
|
||||||
use crate::game::{msg, Transition};
|
use crate::game::Transition;
|
||||||
use crate::helpers::cmp_duration_shorter;
|
use crate::helpers::cmp_duration_shorter;
|
||||||
use crate::managed::{WrappedComposite, WrappedOutcome};
|
use crate::managed::{WrappedComposite, WrappedOutcome};
|
||||||
use crate::sandbox::gameplay::{challenge_controller, GameplayMode, GameplayState};
|
use crate::sandbox::gameplay::{challenge_controller, FinalScore, GameplayMode, GameplayState};
|
||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use ezgui::{EventCtx, GfxCtx, Line, ManagedWidget, Text};
|
use ezgui::{EventCtx, GfxCtx, Line, ManagedWidget, Text};
|
||||||
use geom::{Duration, Statistic, Time};
|
use geom::{Duration, Statistic, Time};
|
||||||
@ -51,8 +51,11 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ui.primary.sim.is_done() {
|
if ui.primary.sim.is_done() {
|
||||||
// TODO Stop the challenge somehow
|
return Some(Transition::Push(FinalScore::new(
|
||||||
return Some(Transition::Push(msg("Final score", vec![final_score(ui)])));
|
ctx,
|
||||||
|
final_score(ui),
|
||||||
|
self.mode.clone(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@ -91,7 +94,7 @@ fn make_top_center(ctx: &mut EventCtx, ui: &UI, mode: GameplayMode) -> WrappedCo
|
|||||||
WrappedComposite::text_button(ctx, "details", None).margin(5),
|
WrappedComposite::text_button(ctx, "details", None).margin(5),
|
||||||
])
|
])
|
||||||
.centered(),
|
.centered(),
|
||||||
ManagedWidget::draw_text(ctx, Text::from(Line(format!("Goal: {}", GOAL)))),
|
ManagedWidget::draw_text(ctx, Text::from(Line(format!("Goal: {} faster", GOAL)))),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.cb(
|
.cb(
|
||||||
|
@ -7,17 +7,19 @@ mod play_scenario;
|
|||||||
pub mod spawner;
|
pub mod spawner;
|
||||||
|
|
||||||
use crate::challenges;
|
use crate::challenges;
|
||||||
use crate::common::Overlays;
|
use crate::challenges::challenges_picker;
|
||||||
|
use crate::common::{CommonState, Overlays};
|
||||||
use crate::edit::EditMode;
|
use crate::edit::EditMode;
|
||||||
use crate::game::{msg, Transition};
|
use crate::game::{msg, State, Transition};
|
||||||
use crate::managed::WrappedComposite;
|
use crate::managed::WrappedComposite;
|
||||||
|
use crate::pregame::main_menu;
|
||||||
use crate::render::{AgentColorScheme, InnerAgentColorScheme};
|
use crate::render::{AgentColorScheme, InnerAgentColorScheme};
|
||||||
use crate::sandbox::SandboxMode;
|
use crate::sandbox::SandboxMode;
|
||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use ezgui::{
|
use ezgui::{
|
||||||
lctrl, Choice, Color, Composite, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line,
|
lctrl, Choice, Color, Composite, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line,
|
||||||
ManagedWidget, ModalMenu, Text, VerticalAlignment, Wizard,
|
ManagedWidget, ModalMenu, Outcome, Text, VerticalAlignment, Wizard,
|
||||||
};
|
};
|
||||||
use geom::{Duration, Polygon};
|
use geom::{Duration, Polygon};
|
||||||
use map_model::{EditCmd, Map, MapEdits};
|
use map_model::{EditCmd, Map, MapEdits};
|
||||||
@ -320,3 +322,71 @@ fn challenge_controller(
|
|||||||
Box::new(move |_, _| Some(Transition::Push(msg("Challenge", description.clone())))),
|
Box::new(move |_, _| Some(Transition::Push(msg("Challenge", description.clone())))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FinalScore {
|
||||||
|
composite: Composite,
|
||||||
|
mode: GameplayMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FinalScore {
|
||||||
|
fn new(ctx: &mut EventCtx, verdict: String, mode: GameplayMode) -> Box<dyn State> {
|
||||||
|
let mut txt = Text::prompt("Final score");
|
||||||
|
txt.add(Line(verdict));
|
||||||
|
Box::new(FinalScore {
|
||||||
|
composite: Composite::new(
|
||||||
|
ManagedWidget::col(vec![
|
||||||
|
ManagedWidget::draw_text(ctx, txt),
|
||||||
|
ManagedWidget::row(vec![
|
||||||
|
WrappedComposite::text_button(ctx, "try again", None),
|
||||||
|
WrappedComposite::text_button(ctx, "back to challenges", None),
|
||||||
|
])
|
||||||
|
.centered(),
|
||||||
|
])
|
||||||
|
.bg(Color::grey(0.4))
|
||||||
|
.outline(10.0, Color::WHITE)
|
||||||
|
.padding(10),
|
||||||
|
)
|
||||||
|
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||||
|
.build(ctx),
|
||||||
|
mode,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State for FinalScore {
|
||||||
|
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
||||||
|
match self.composite.event(ctx) {
|
||||||
|
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||||
|
"try again" => {
|
||||||
|
ui.primary.clear_sim();
|
||||||
|
Transition::PopThenReplace(Box::new(SandboxMode::new(
|
||||||
|
ctx,
|
||||||
|
ui,
|
||||||
|
self.mode.clone(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
"back to challenges" => {
|
||||||
|
ui.primary.clear_sim();
|
||||||
|
Transition::Clear(vec![main_menu(ctx, ui), challenges_picker(ctx)])
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
None => Transition::Keep,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
||||||
|
// Make it clear the map can't be interacted with right now.
|
||||||
|
g.fork_screenspace();
|
||||||
|
// TODO - OSD height
|
||||||
|
g.draw_polygon(
|
||||||
|
Color::BLACK.alpha(0.5),
|
||||||
|
&Polygon::rectangle(g.canvas.window_width, g.canvas.window_height),
|
||||||
|
);
|
||||||
|
g.unfork();
|
||||||
|
|
||||||
|
self.composite.draw(g);
|
||||||
|
// Still want to show hotkeys
|
||||||
|
CommonState::draw_osd(g, ui, &None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -153,7 +153,7 @@ impl State for SandboxMode {
|
|||||||
ui.primary.clear_sim();
|
ui.primary.clear_sim();
|
||||||
ui.set_prebaked(None);
|
ui.set_prebaked(None);
|
||||||
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
||||||
Some(Transition::Clear(main_menu(ctx, ui)))
|
Some(Transition::Clear(vec![main_menu(ctx, ui)]))
|
||||||
}
|
}
|
||||||
"quit challenge" => {
|
"quit challenge" => {
|
||||||
if !ui.primary.map.get_edits().is_empty() {
|
if !ui.primary.map.get_edits().is_empty() {
|
||||||
@ -166,7 +166,7 @@ impl State for SandboxMode {
|
|||||||
ui.primary.clear_sim();
|
ui.primary.clear_sim();
|
||||||
ui.set_prebaked(None);
|
ui.set_prebaked(None);
|
||||||
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
||||||
Some(Transition::Clear(main_menu(ctx, ui)))
|
Some(Transition::Clear(vec![main_menu(ctx, ui)]))
|
||||||
}
|
}
|
||||||
"keep playing" => Some(Transition::Pop),
|
"keep playing" => Some(Transition::Pop),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
Loading…
Reference in New Issue
Block a user