Start actdev mode with the baseline scenario, if it exists. Improve the follow shortcut. cyipt/actdev#66

This commit is contained in:
Dustin Carlino 2021-02-16 17:58:20 -08:00
parent 12d73e10bc
commit 4de7cb68c0
3 changed files with 50 additions and 23 deletions

View File

@ -96,7 +96,13 @@ pub fn main() {
let name = MapName::new("gb", &city, "center");
flags.sim_flags.load = name.path();
flags.study_area = Some(site);
mode = Some(sandbox::GameplayMode::Blog(name));
// Start with the baseline scenario if it exists.
let scenario = if abstio::file_exists(abstio::path_scenario(&name, "base")) {
Some("base".to_string())
} else {
None
};
mode = Some(sandbox::GameplayMode::Blog(name, scenario));
}
args.done();
@ -277,7 +283,7 @@ fn finish_app_setup(
let states: Vec<Box<dyn State<App>>> = if title {
vec![Box::new(TitleScreen::new(ctx, app))]
} else if let Some(mode) = maybe_mode {
if let GameplayMode::Blog(_) = mode {
if let GameplayMode::Blog(_, _) = mode {
vec![SandboxMode::async_new(app, mode, start_daytime)]
} else {
vec![SandboxMode::simple_new(app, mode)]

View File

@ -1,6 +1,5 @@
use std::collections::BTreeMap;
use map_gui::tools::{grey_out_map, nice_map_name, open_browser, PopupMsg};
use sim::{PersonID, TripID};
use widgetry::{
lctrl, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, SimpleState,
StyledButtons, Text, TextExt, VerticalAlignment, Widget,
@ -8,19 +7,21 @@ use widgetry::{
use crate::app::{App, Transition};
use crate::edit::EditMode;
use crate::info::Tab;
use crate::info::{OpenTrip, Tab};
use crate::sandbox::gameplay::freeform::ChangeScenario;
use crate::sandbox::gameplay::{GameplayMode, GameplayState};
use crate::sandbox::{Actions, SandboxControls};
pub struct Blog {
top_center: Panel,
scenario_name: Option<String>,
}
impl Blog {
pub fn new(ctx: &mut EventCtx) -> Box<dyn GameplayState> {
pub fn new(ctx: &mut EventCtx, scenario_name: Option<String>) -> Box<dyn GameplayState> {
Box::new(Blog {
top_center: Panel::empty(ctx),
scenario_name,
})
}
}
@ -68,19 +69,12 @@ impl GameplayState for Blog {
Some(Transition::Push(SimpleState::new(panel, Box::new(About))))
}
"follow someone" => {
// Just find the first active non-bus person
if let Some(person) = app
.primary
.sim
.active_agents()
.into_iter()
.filter_map(|a| app.primary.sim.agent_to_person(a))
.next()
{
if let Some((person, trip)) = find_active_trip(app) {
ctx.canvas.cam_zoom = 40.0;
controls.common.as_mut().unwrap().launch_info_panel(
ctx,
app,
Tab::PersonTrips(person, BTreeMap::new()),
Tab::PersonTrips(person, OpenTrip::single(trip)),
actions,
);
None
@ -121,7 +115,10 @@ impl GameplayState for Blog {
.draw(ctx),
Widget::vert_separator(ctx, 50.0),
ctx.style()
.btn_light_popup_icon_text("system/assets/tools/calendar.svg", "none")
.btn_light_popup_icon_text(
"system/assets/tools/calendar.svg",
self.scenario_name.as_ref().unwrap_or(&"none".to_string()),
)
.hotkey(Key::S)
.build_widget(ctx, "change scenario"),
ctx.style()
@ -167,3 +164,14 @@ impl SimpleState<App> for About {
grey_out_map(g, app);
}
}
fn find_active_trip(app: &App) -> Option<(PersonID, TripID)> {
for agent in app.primary.sim.active_agents() {
if let Some(trip) = app.primary.sim.agent_to_trip(agent) {
if let Some(person) = app.primary.sim.trip_to_person(trip) {
return Some((person, trip));
}
}
}
None
}

View File

@ -39,7 +39,8 @@ pub enum GameplayMode {
PlayScenario(MapName, String, Vec<ScenarioModifier>),
FixTrafficSignals,
OptimizeCommute(OrigPersonID, Duration),
Blog(MapName),
// Map name, scenario name
Blog(MapName, Option<String>),
// current
Tutorial(TutorialPointer),
@ -104,15 +105,14 @@ impl GameplayMode {
GameplayMode::FixTrafficSignals => MapName::seattle("downtown"),
GameplayMode::OptimizeCommute(_, _) => MapName::seattle("montlake"),
GameplayMode::Tutorial(_) => MapName::seattle("montlake"),
GameplayMode::Blog(ref name) => name.clone(),
GameplayMode::Blog(ref name, _) => name.clone(),
}
}
pub fn scenario(&self, app: &App, mut rng: XorShiftRng, timer: &mut Timer) -> LoadScenario {
let map = &app.primary.map;
let name = match self {
// TODO Start with a scenario in blog mode, once all the actdev scenarios are imported.
GameplayMode::Freeform(_) | GameplayMode::Blog(_) => {
GameplayMode::Freeform(_) => {
let mut s = Scenario::empty(map, "empty");
s.only_seed_buses = None;
return LoadScenario::Scenario(s);
@ -126,7 +126,18 @@ impl GameplayMode {
None => LoadScenario::Nothing,
};
}
_ => "weekday".to_string(),
GameplayMode::Blog(_, ref maybe_scenario) => {
if let Some(s) = maybe_scenario {
s.to_string()
} else {
let mut s = Scenario::empty(map, "empty");
s.only_seed_buses = None;
return LoadScenario::Scenario(s);
}
}
GameplayMode::FixTrafficSignals | GameplayMode::OptimizeCommute(_, _) => {
"weekday".to_string()
}
};
if name == "random" {
LoadScenario::Scenario(ScenarioGenerator::small_run(map).generate(map, &mut rng, timer))
@ -218,7 +229,9 @@ impl GameplayMode {
commute::OptimizeCommute::new(ctx, app, *p, *goal)
}
GameplayMode::Tutorial(current) => Tutorial::make_gameplay(ctx, app, *current),
GameplayMode::Blog(_) => blog::Blog::new(ctx),
GameplayMode::Blog(_, ref maybe_scenario) => {
blog::Blog::new(ctx, maybe_scenario.clone())
}
}
}
}