New tool to union two scenarios. One use case is manually defining some

new trips, then seeing the impact they'll have on the normal weekday
scenario. So how much externality would be caused by a bunch of new
trips if some building is built?

Demo showing the whole flow: https://youtu.be/adpED0KGQ7Q. Why do those
few trips at the beginning impact some later trips so much? Who knows.
Likely parking spots get gobbled up.
This commit is contained in:
Dustin Carlino 2020-08-19 15:05:41 -07:00
parent 24a8d4a836
commit f31c4ec7fb
2 changed files with 52 additions and 3 deletions

View File

@ -1,7 +1,7 @@
use crate::app::App; use crate::app::App;
use crate::common::CityPicker; use crate::common::CityPicker;
use crate::edit::EditMode; use crate::edit::EditMode;
use crate::game::{PopupMsg, State, Transition}; use crate::game::{ChooseSomething, PopupMsg, State, Transition};
use crate::helpers::{checkbox_per_mode, nice_map_name}; use crate::helpers::{checkbox_per_mode, nice_map_name};
use crate::sandbox::gameplay::freeform::make_change_traffic; use crate::sandbox::gameplay::freeform::make_change_traffic;
use crate::sandbox::gameplay::{GameplayMode, GameplayState}; use crate::sandbox::gameplay::{GameplayMode, GameplayState};
@ -190,7 +190,13 @@ impl EditScenarioModifiers {
.outline(2.0, Color::WHITE), .outline(2.0, Color::WHITE),
); );
} }
rows.push(Btn::text_bg2("Change trip mode").build_def(ctx, None)); rows.push(
Widget::row(vec![
Btn::text_bg2("Change trip mode").build_def(ctx, None),
Btn::text_bg2("Add extra new trips").build_def(ctx, None),
])
.centered(),
);
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Spinner::new(ctx, (2, 14), 2).named("repeat_days"), Spinner::new(ctx, (2, 14), 2).named("repeat_days"),
Btn::text_bg2("Repeat schedule multiple days").build_def(ctx, None), Btn::text_bg2("Repeat schedule multiple days").build_def(ctx, None),
@ -246,6 +252,31 @@ impl State for EditScenarioModifiers {
self.modifiers.clone(), self.modifiers.clone(),
)); ));
} }
"Add extra new trips" => {
return Transition::Push(ChooseSomething::new(
ctx,
"Which trips do you want to add in?",
// TODO Exclude weekday?
Choice::strings(abstutil::list_all_objects(abstutil::path_all_scenarios(
app.primary.map.get_name(),
))),
Box::new(|name, _, _| {
Transition::Multi(vec![
Transition::Pop,
Transition::ReplaceWithData(Box::new(|state, ctx, _| {
let mut state =
state.downcast::<EditScenarioModifiers>().ok().unwrap();
state.modifiers.push(ScenarioModifier::AddExtraTrips(name));
vec![EditScenarioModifiers::new(
ctx,
state.scenario_name,
state.modifiers,
)]
})),
])
}),
));
}
"Repeat schedule multiple days" => { "Repeat schedule multiple days" => {
self.modifiers.push(ScenarioModifier::RepeatDays( self.modifiers.push(ScenarioModifier::RepeatDays(
self.composite.spinner("repeat_days") as usize, self.composite.spinner("repeat_days") as usize,

View File

@ -1,4 +1,5 @@
use crate::{IndividTrip, Scenario, SpawnTrip, TripMode}; use crate::{IndividTrip, PersonID, Scenario, SpawnTrip, TripMode};
use abstutil::Timer;
use geom::{Duration, Time}; use geom::{Duration, Time};
use map_model::Map; use map_model::Map;
use rand::Rng; use rand::Rng;
@ -15,6 +16,8 @@ pub enum ScenarioModifier {
departure_filter: (Time, Time), departure_filter: (Time, Time),
from_modes: BTreeSet<TripMode>, from_modes: BTreeSet<TripMode>,
}, },
// Scenario name
AddExtraTrips(String),
} }
impl ScenarioModifier { impl ScenarioModifier {
@ -52,6 +55,20 @@ impl ScenarioModifier {
} }
s s
} }
ScenarioModifier::AddExtraTrips(name) => {
let other: Scenario = abstutil::read_binary(
abstutil::path_scenario(map.get_name(), name),
&mut Timer::throwaway(),
);
for mut p in other.people {
p.id = PersonID(s.people.len());
for trip in &mut p.trips {
trip.modified = true;
}
s.people.push(p);
}
s
}
} }
} }
@ -74,6 +91,7 @@ impl ScenarioModifier {
departure_filter.1.ampm_tostring(), departure_filter.1.ampm_tostring(),
to_mode.verb() to_mode.verb()
), ),
ScenarioModifier::AddExtraTrips(name) => format!("Add extra trips from {}", name),
} }
} }
} }