From 3548b464daf3e5687cb4fa04b83934286076908a Mon Sep 17 00:00:00 2001 From: Isse Date: Fri, 14 Apr 2023 11:15:50 +0200 Subject: [PATCH] orient airships correctly on load --- common/src/event.rs | 1 + rtsim/src/data/npc.rs | 2 ++ rtsim/src/rule/npc_ai.rs | 28 +++++++++------------- rtsim/src/rule/simulate_npcs.rs | 12 ++++++---- server/src/cmd.rs | 35 +++++++++++----------------- server/src/events/entity_creation.rs | 3 ++- server/src/events/mod.rs | 3 ++- server/src/rtsim/tick.rs | 2 ++ server/src/state_ext.rs | 4 +++- 9 files changed, 45 insertions(+), 45 deletions(-) diff --git a/common/src/event.rs b/common/src/event.rs index 89c708b5e0..6f5b2f15be 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -227,6 +227,7 @@ pub enum ServerEvent { }, CreateShip { pos: Pos, + ori: Ori, ship: comp::ship::Body, rtsim_entity: Option, driver: Option, diff --git a/rtsim/src/data/npc.rs b/rtsim/src/data/npc.rs index 0709085a60..61f0cc7167 100644 --- a/rtsim/src/data/npc.rs +++ b/rtsim/src/data/npc.rs @@ -262,6 +262,7 @@ pub enum VehicleKind { #[derive(Clone, Serialize, Deserialize)] pub struct Vehicle { pub wpos: Vec3, + pub dir: Vec2, pub body: comp::ship::Body, @@ -283,6 +284,7 @@ impl Vehicle { pub fn new(wpos: Vec3, body: comp::ship::Body) -> Self { Self { wpos, + dir: Vec2::unit_y(), body, chunk_pos: None, driver: None, diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index ca1f2ce68b..b5ff2ee199 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -301,7 +301,6 @@ fn goto(wpos: Vec3, speed_factor: f32, goal_dist: f32) -> impl Action { ctx.world .sim() .get_surface_alt_approx(wpos.xy().as_()) - .map(|alt| alt) .unwrap_or(wpos.z), ) }); @@ -314,7 +313,6 @@ fn goto(wpos: Vec3, speed_factor: f32, goal_dist: f32) -> impl Action { .map(|_| {}) } - fn goto_flying( wpos: Vec3, speed_factor: f32, @@ -902,21 +900,17 @@ fn pilot(ship: common::comp::ship::Body) -> impl Action { }) .choose(&mut ctx.rng); if let Some((_id, site)) = site { - Either::Right(goto_2d_flying( - site.wpos.as_(), - 1.0, - 50.0, - 150.0, - 110.0, - ship.flying_height(), - ).then(goto_2d_flying( - site.wpos.as_(), - 1.0, - 10.0, - 32.0, - 16.0, - 10.0, - ))) + Either::Right( + goto_2d_flying( + site.wpos.as_(), + 1.0, + 50.0, + 150.0, + 110.0, + ship.flying_height(), + ) + .then(goto_2d_flying(site.wpos.as_(), 1.0, 10.0, 32.0, 16.0, 10.0)), + ) } else { Either::Left(finish()) } diff --git a/rtsim/src/rule/simulate_npcs.rs b/rtsim/src/rule/simulate_npcs.rs index a2a9a6489c..08b60004c7 100644 --- a/rtsim/src/rule/simulate_npcs.rs +++ b/rtsim/src/rule/simulate_npcs.rs @@ -11,6 +11,7 @@ use common::{ use rand::prelude::*; use rand_chacha::ChaChaRng; use tracing::{error, warn}; +use vek::Vec2; use world::site::SiteKind; pub struct SimulateNpcs; @@ -167,10 +168,10 @@ fn on_tick(ctx: EventCtx) { if dist2 > 0.5f32.powi(2) { let wpos = vehicle.wpos - + (diff - * (vehicle.get_speed() * speed_factor * ctx.event.dt - / dist2.sqrt()) - .min(1.0)); + + (diff + * (vehicle.get_speed() * speed_factor * ctx.event.dt + / dist2.sqrt()) + .min(1.0)); let is_valid = match vehicle.body { common::comp::ship::Body::DefaultAirship @@ -189,6 +190,9 @@ fn on_tick(ctx: EventCtx) { if is_valid { vehicle.wpos = wpos; } + vehicle.dir = (target.xy() - vehicle.wpos.xy()) + .try_normalized() + .unwrap_or(Vec2::unit_y()); } }, // When riding, other actions are disabled diff --git a/server/src/cmd.rs b/server/src/cmd.rs index cb64723a05..91c4807dd8 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1572,19 +1572,14 @@ fn handle_spawn_airship( pos.0.z += 50.0; const DESTINATION_RADIUS: f32 = 2000.0; let angle = angle.map(|a| a * std::f32::consts::PI / 180.0); - let destination = angle.map(|a| { - pos.0 - + Vec3::new( - DESTINATION_RADIUS * a.cos(), - DESTINATION_RADIUS * a.sin(), - 200.0, - ) - }); + let dir = angle.map(|a| Vec3::new(a.cos(), a.sin(), 0.0)); + let destination = dir.map(|dir| pos.0 + dir * DESTINATION_RADIUS + Vec3::new(0.0, 0.0, 200.0)); let mut rng = thread_rng(); let ship = comp::ship::Body::random_airship_with(&mut rng); + let ori = comp::Ori::from(common::util::Dir::new(dir.unwrap_or(Vec3::unit_y()))); let mut builder = server .state - .create_ship(pos, ship, |ship| ship.make_collider()) + .create_ship(pos, ori, ship, |ship| ship.make_collider()) .with(LightEmitter { col: Rgb::new(1.0, 0.65, 0.2), strength: 2.0, @@ -1621,19 +1616,14 @@ fn handle_spawn_ship( pos.0.z += 50.0; const DESTINATION_RADIUS: f32 = 2000.0; let angle = angle.map(|a| a * std::f32::consts::PI / 180.0); - let destination = angle.map(|a| { - pos.0 - + Vec3::new( - DESTINATION_RADIUS * a.cos(), - DESTINATION_RADIUS * a.sin(), - 200.0, - ) - }); + let dir = angle.map(|a| Vec3::new(a.cos(), a.sin(), 0.0)); + let destination = dir.map(|dir| pos.0 + dir * DESTINATION_RADIUS + Vec3::new(0.0, 0.0, 200.0)); let mut rng = thread_rng(); let ship = comp::ship::Body::random_ship_with(&mut rng); + let ori = comp::Ori::from(common::util::Dir::new(dir.unwrap_or(Vec3::unit_y()))); let mut builder = server .state - .create_ship(pos, ship, |ship| ship.make_collider()) + .create_ship(pos, ori, ship, |ship| ship.make_collider()) .with(LightEmitter { col: Rgb::new(1.0, 0.65, 0.2), strength: 2.0, @@ -1683,9 +1673,12 @@ fn handle_make_volume( }; server .state - .create_ship(comp::Pos(pos.0 + Vec3::unit_z() * 50.0), ship, move |_| { - collider - }) + .create_ship( + comp::Pos(pos.0 + Vec3::unit_z() * 50.0), + comp::Ori::default(), + ship, + move |_| collider, + ) .build(); server.notify_client( diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index 61901ca597..76067e4a78 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -194,6 +194,7 @@ pub fn handle_create_npc(server: &mut Server, pos: Pos, mut npc: NpcBuilder) -> pub fn handle_create_ship( server: &mut Server, pos: Pos, + ori: Ori, ship: comp::ship::Body, rtsim_vehicle: Option, driver: Option, @@ -201,7 +202,7 @@ pub fn handle_create_ship( ) { let mut entity = server .state - .create_ship(pos, ship, |ship| ship.make_collider()); + .create_ship(pos, ori, ship, |ship| ship.make_collider()); /* if let Some(mut agent) = agent { let (kp, ki, kd) = pid_coefficients(&Body::Ship(ship)); diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index a6c4882257..6e2a28e3d7 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -193,10 +193,11 @@ impl Server { }, ServerEvent::CreateShip { pos, + ori, ship, rtsim_entity, driver, - } => handle_create_ship(self, pos, ship, rtsim_entity, driver, Vec::new()), + } => handle_create_ship(self, pos, ori, ship, rtsim_entity, driver, Vec::new()), ServerEvent::CreateWaypoint(pos) => handle_create_waypoint(self, pos), ServerEvent::ClientDisconnect(entity, reason) => { frontend_events.push(handle_client_disconnect(self, entity, reason, false)) diff --git a/server/src/rtsim/tick.rs b/server/src/rtsim/tick.rs index 31956ca1c6..f898cf1cb3 100644 --- a/server/src/rtsim/tick.rs +++ b/server/src/rtsim/tick.rs @@ -11,6 +11,7 @@ use common::{ slowjob::SlowJobPool, terrain::CoordinateConversions, trade::{Good, SiteInformation}, + util::Dir, LoadoutBuilder, }; use common_ecs::{Job, Origin, Phase, System}; @@ -315,6 +316,7 @@ impl<'a> System<'a> for Sys { emitter.emit(ServerEvent::CreateShip { pos: comp::Pos(vehicle.wpos), + ori: comp::Ori::from(Dir::new(vehicle.dir.with_z(0.0))), ship: vehicle.body, rtsim_entity: Some(RtSimVehicle(vehicle_id)), driver: vehicle.driver.and_then(&mut actor_info), diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 850a2b19e7..bbf5a7d280 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -64,6 +64,7 @@ pub trait StateExt { fn create_ship comp::Collider>( &mut self, pos: comp::Pos, + ori: comp::Ori, ship: comp::ship::Body, make_collider: F, ) -> EcsEntityBuilder; @@ -338,6 +339,7 @@ impl StateExt for State { fn create_ship comp::Collider>( &mut self, pos: comp::Pos, + ori: comp::Ori, ship: comp::ship::Body, make_collider: F, ) -> EcsEntityBuilder { @@ -347,7 +349,7 @@ impl StateExt for State { .create_entity_synced() .with(pos) .with(comp::Vel(Vec3::zero())) - .with(comp::Ori::default()) + .with(ori) .with(body.mass()) .with(body.density()) .with(make_collider(ship))