fold in the intersection spawning controls a bit

This commit is contained in:
Dustin Carlino 2020-06-02 11:04:06 -07:00
parent d5e3c3740c
commit 749d0809f7
4 changed files with 116 additions and 120 deletions

View File

@ -9,13 +9,17 @@ use crate::sandbox::SandboxMode;
use abstutil::Timer;
use ezgui::{
hotkey, lctrl, Btn, Choice, Color, Composite, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment,
Key, Line, Outcome, ScreenRectangle, Spinner, TextExt, VerticalAlignment, Widget,
Key, Line, Outcome, ScreenRectangle, Spinner, Text, TextExt, VerticalAlignment, Widget,
};
use geom::{Distance, Duration, Polygon};
use map_model::{Map, PathConstraints, PathRequest, Position, NORMAL_LANE_THICKNESS};
use map_model::{
IntersectionID, Map, PathConstraints, PathRequest, Position, NORMAL_LANE_THICKNESS,
};
use rand::seq::SliceRandom;
use rand::Rng;
use sim::{
DontDrawAgents, IndividTrip, PersonID, PersonSpec, Scenario, SidewalkSpot, SpawnTrip,
TripEndpoint, TripMode,
DontDrawAgents, DrivingGoal, IndividTrip, PersonID, PersonSpec, Scenario, SidewalkSpot,
SpawnTrip, TripEndpoint, TripMode, TripSpec,
};
// TODO Maybe remember what things were spawned, offer to replay this later
@ -107,6 +111,14 @@ pub fn freeform_controller(
.build_def(ctx, None)
.centered_horiz(),
);
rows.push(
Text::from_all(vec![
Line("Select an intersection and press "),
Line(Key::Z.describe()).fg(ctx.style().hotkey_color),
Line(" to start traffic nearby"),
])
.draw(ctx),
);
}
Composite::new(Widget::col(rows).bg(app.cs.panel_bg).padding(10))
@ -172,8 +184,6 @@ pub fn make_change_traffic(btn: ScreenRectangle) -> Box<dyn State> {
}))
}
// TODO Maybe move all this to the other module
const SMALL_DT: Duration = Duration::const_seconds(0.1);
struct AgentSpawner {
@ -426,3 +436,99 @@ fn pos(endpt: TripEndpoint, mode: TripMode, from: bool, map: &Map) -> Option<Pos
},
}
}
pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
let map = &app.primary.map;
let sim = &mut app.primary.sim;
let mut rng = app.primary.current_flags.sim_flags.make_rng();
let mut spawner = sim.make_spawner();
if map.all_buildings().is_empty() {
println!("No buildings, can't pick destinations");
return;
}
let mut timer = Timer::new(format!(
"spawning agents around {} (rng seed {:?})",
i, app.primary.current_flags.sim_flags.rng_seed
));
let now = sim.time();
for l in &map.get_i(i).incoming_lanes {
let lane = map.get_l(*l);
if lane.is_driving() || lane.is_biking() {
for _ in 0..10 {
let vehicle_spec = if rng.gen_bool(0.7) && lane.is_driving() {
Scenario::rand_car(&mut rng)
} else {
Scenario::rand_bike(&mut rng)
};
if vehicle_spec.length > lane.length() {
continue;
}
let person = sim.random_person(
Scenario::rand_ped_speed(&mut rng),
vec![vehicle_spec.clone()],
);
spawner.schedule_trip(
person,
now,
TripSpec::VehicleAppearing {
start_pos: Position::new(
lane.id,
Scenario::rand_dist(&mut rng, vehicle_spec.length, lane.length()),
),
goal: DrivingGoal::ParkNear(
map.all_buildings().choose(&mut rng).unwrap().id,
),
use_vehicle: person.vehicles[0].id,
retry_if_no_room: false,
origin: None,
},
TripEndpoint::Border(lane.src_i, None),
map,
);
}
} else if lane.is_sidewalk() {
for _ in 0..5 {
spawner.schedule_trip(
sim.random_person(Scenario::rand_ped_speed(&mut rng), Vec::new()),
now,
TripSpec::JustWalking {
start: SidewalkSpot::suddenly_appear(
lane.id,
Scenario::rand_dist(&mut rng, 0.1 * lane.length(), 0.9 * lane.length()),
map,
),
goal: SidewalkSpot::building(
map.all_buildings().choose(&mut rng).unwrap().id,
map,
),
},
TripEndpoint::Border(lane.src_i, None),
map,
);
}
}
}
sim.flush_spawner(spawner, map, &mut timer);
sim.normal_step(map, SMALL_DT);
}
pub fn actions(_: &App, id: ID) -> Vec<(Key, String)> {
match id {
ID::Intersection(_) => vec![(Key::Z, "spawn agents here".to_string())],
_ => Vec::new(),
}
}
pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Transition {
match (id, action.as_ref()) {
(ID::Intersection(id), "spawn agents here") => {
spawn_agents_around(id, app);
Transition::Keep
}
_ => unreachable!(),
}
}

View File

@ -3,9 +3,9 @@ pub mod commute;
pub mod fix_traffic_signals;
mod freeform;
mod play_scenario;
pub mod spawner;
mod tutorial;
pub use self::freeform::spawn_agents_around;
pub use self::tutorial::{Tutorial, TutorialPointer, TutorialState};
use crate::app::App;
use crate::challenges::{challenges_picker, Challenge};
@ -240,7 +240,7 @@ impl GameplayMode {
impl ContextualActions for GameplayMode {
fn actions(&self, app: &App, id: ID) -> Vec<(Key, String)> {
match self {
GameplayMode::Freeform(_) => spawner::actions(app, id),
GameplayMode::Freeform(_) => freeform::actions(app, id),
GameplayMode::Tutorial(_) => tutorial::actions(app, id),
_ => Vec::new(),
}
@ -255,7 +255,7 @@ impl ContextualActions for GameplayMode {
_: &mut bool,
) -> Transition {
match self {
GameplayMode::Freeform(_) => spawner::execute(ctx, app, id, action),
GameplayMode::Freeform(_) => freeform::execute(ctx, app, id, action),
GameplayMode::Tutorial(_) => tutorial::execute(ctx, app, id, action),
_ => unreachable!(),
}

View File

@ -1,108 +0,0 @@
use crate::app::App;
use crate::game::Transition;
use crate::helpers::ID;
use abstutil::Timer;
use ezgui::{EventCtx, Key};
use geom::Duration;
use map_model::{IntersectionID, Position};
use rand::seq::SliceRandom;
use rand::Rng;
use sim::{DrivingGoal, Scenario, SidewalkSpot, TripEndpoint, TripSpec};
const SMALL_DT: Duration = Duration::const_seconds(0.1);
pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
let map = &app.primary.map;
let sim = &mut app.primary.sim;
let mut rng = app.primary.current_flags.sim_flags.make_rng();
let mut spawner = sim.make_spawner();
if map.all_buildings().is_empty() {
println!("No buildings, can't pick destinations");
return;
}
let mut timer = Timer::new(format!(
"spawning agents around {} (rng seed {:?})",
i, app.primary.current_flags.sim_flags.rng_seed
));
let now = sim.time();
for l in &map.get_i(i).incoming_lanes {
let lane = map.get_l(*l);
if lane.is_driving() || lane.is_biking() {
for _ in 0..10 {
let vehicle_spec = if rng.gen_bool(0.7) && lane.is_driving() {
Scenario::rand_car(&mut rng)
} else {
Scenario::rand_bike(&mut rng)
};
if vehicle_spec.length > lane.length() {
continue;
}
let person = sim.random_person(
Scenario::rand_ped_speed(&mut rng),
vec![vehicle_spec.clone()],
);
spawner.schedule_trip(
person,
now,
TripSpec::VehicleAppearing {
start_pos: Position::new(
lane.id,
Scenario::rand_dist(&mut rng, vehicle_spec.length, lane.length()),
),
goal: DrivingGoal::ParkNear(
map.all_buildings().choose(&mut rng).unwrap().id,
),
use_vehicle: person.vehicles[0].id,
retry_if_no_room: false,
origin: None,
},
TripEndpoint::Border(lane.src_i, None),
map,
);
}
} else if lane.is_sidewalk() {
for _ in 0..5 {
spawner.schedule_trip(
sim.random_person(Scenario::rand_ped_speed(&mut rng), Vec::new()),
now,
TripSpec::JustWalking {
start: SidewalkSpot::suddenly_appear(
lane.id,
Scenario::rand_dist(&mut rng, 0.1 * lane.length(), 0.9 * lane.length()),
map,
),
goal: SidewalkSpot::building(
map.all_buildings().choose(&mut rng).unwrap().id,
map,
),
},
TripEndpoint::Border(lane.src_i, None),
map,
);
}
}
}
sim.flush_spawner(spawner, map, &mut timer);
sim.normal_step(map, SMALL_DT);
}
pub fn actions(_: &App, id: ID) -> Vec<(Key, String)> {
match id {
ID::Intersection(_) => vec![(Key::Z, "spawn agents here".to_string())],
_ => Vec::new(),
}
}
pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Transition {
match (id, action.as_ref()) {
(ID::Intersection(id), "spawn agents here") => {
spawn_agents_around(id, app);
Transition::Keep
}
_ => unreachable!(),
}
}

View File

@ -18,13 +18,11 @@ use crate::layer::PickLayer;
use crate::managed::{WrappedComposite, WrappedOutcome};
use crate::pregame::MainMenu;
use crate::render::AgentColorScheme;
pub use crate::sandbox::gameplay::{TutorialPointer, TutorialState};
use ezgui::{
hotkey, lctrl, Btn, Choice, Color, Composite, EventCtx, EventLoopMode, GeomBatch, GfxCtx,
HorizontalAlignment, Key, Line, Outcome, Text, TextExt, VerticalAlignment, Widget, Wizard,
};
pub use gameplay::spawner::spawn_agents_around;
pub use gameplay::GameplayMode;
pub use gameplay::{spawn_agents_around, GameplayMode, TutorialPointer, TutorialState};
use geom::{Polygon, Time};
use map_model::MapEdits;
use sim::{TripMode, VehicleType};