keep track of positions of IDed objects, for easy rel. position calc.

This commit is contained in:
yuni 2024-04-19 22:23:25 +02:00
parent 1d73cf8367
commit e3ff386011
2 changed files with 40 additions and 18 deletions

View file

@ -3,6 +3,7 @@ use bevy_xpbd_3d::prelude::*;
use bevy::scene::SceneInstance; use bevy::scene::SceneInstance;
use bevy::math::DVec3; use bevy::math::DVec3;
use crate::{actor, audio, camera, chat, commands, effects, hud, nature, var, world}; use crate::{actor, audio, camera, chat, commands, effects, hud, nature, var, world};
use std::collections::HashMap;
pub const ENGINE_SPEED_FACTOR: f32 = 30.0; pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
const MAX_TRANSMISSION_DISTANCE: f32 = 100.0; const MAX_TRANSMISSION_DISTANCE: f32 = 100.0;
@ -27,9 +28,11 @@ impl Plugin for ActorPlugin {
)); ));
app.add_systems(PostUpdate, ( app.add_systems(PostUpdate, (
handle_vehicle_enter_exit, handle_vehicle_enter_exit,
update_id2pos,
)); ));
app.add_event::<VehicleEnterExitEvent>(); app.add_event::<VehicleEnterExitEvent>();
app.add_event::<PlayerDiesEvent>(); app.add_event::<PlayerDiesEvent>();
app.insert_resource(Id2Pos(HashMap::new()));
} }
} }
@ -115,6 +118,8 @@ impl Default for ExperiencesGForce { fn default() -> Self { Self {
#[derive(Component)] pub struct ActorVehicleBeingEntered; #[derive(Component)] pub struct ActorVehicleBeingEntered;
#[derive(Component)] pub struct WantsMaxRotation(pub f64); #[derive(Component)] pub struct WantsMaxRotation(pub f64);
#[derive(Component)] pub struct WantsMaxVelocity(pub f64); #[derive(Component)] pub struct WantsMaxVelocity(pub f64);
#[derive(Component)] pub struct Identifier(pub String);
#[derive(Resource)] pub struct Id2Pos(pub HashMap<String, DVec3>);
#[derive(Component)] #[derive(Component)]
pub struct LifeForm { pub struct LifeForm {
@ -521,3 +526,13 @@ fn handle_gforce(
} }
} }
} }
fn update_id2pos(
mut id2pos: ResMut<Id2Pos>,
q_id: Query<(&Position, &Identifier)>,
) {
id2pos.0.clear();
for (pos, id) in &q_id {
id2pos.0.insert(id.0.clone(), pos.0);
}
}

View file

@ -7,7 +7,6 @@ use crate::{actor, chat, hud, nature, shading, world};
use regex::Regex; use regex::Regex;
use std::f32::consts::PI; use std::f32::consts::PI;
use std::f64::consts::PI as PI64; use std::f64::consts::PI as PI64;
use std::collections::HashMap;
pub struct CommandsPlugin; pub struct CommandsPlugin;
impl Plugin for CommandsPlugin { impl Plugin for CommandsPlugin {
@ -39,6 +38,7 @@ struct ParserState {
// Actor fields // Actor fields
id: String, id: String,
pos: DVec3, pos: DVec3,
relative_to: Option<String>,
model: Option<String>, model: Option<String>,
model_scale: f32, model_scale: f32,
rotation: Quat, rotation: Quat,
@ -86,6 +86,7 @@ impl Default for ParserState {
id: "".to_string(), id: "".to_string(),
pos: DVec3::new(0.0, 0.0, 0.0), pos: DVec3::new(0.0, 0.0, 0.0),
relative_to: None,
model: None, model: None,
model_scale: 1.0, model_scale: 1.0,
rotation: Quat::IDENTITY, rotation: Quat::IDENTITY,
@ -135,7 +136,6 @@ pub fn load_defs(
let mut state = ParserState::default(); let mut state = ParserState::default();
let mut command; let mut command;
let mut parameters; let mut parameters;
let mut id2pos: HashMap<String, DVec3> = HashMap::new();
let mut line_nr = -1; let mut line_nr = -1;
while let Some(line) = lines.next() { while let Some(line) = lines.next() {
@ -207,18 +207,7 @@ pub fn load_defs(
} }
} }
["relativeto", id] => { ["relativeto", id] => {
// NOTE: call this command before "id", otherwise actors that state.relative_to = Some(id.to_string());
// set their position relative to this actor will get the wrong offset
// TODO: fix the above
match id2pos.get(&id.to_string()) {
Some(pos) => {
state.pos += *pos;
}
None => {
error!("Specified `relativeto` command but could not find id `{id}`");
continue;
}
}
} }
["orbit", radius_str, phase_str] => { ["orbit", radius_str, phase_str] => {
if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) { if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) {
@ -239,7 +228,6 @@ pub fn load_defs(
} }
["id", id] => { ["id", id] => {
state.id = id.to_string(); state.id = id.to_string();
id2pos.insert(state.id.clone(), state.pos.clone());
} }
["alive", "yes"] => { ["alive", "yes"] => {
state.is_alive = true; state.is_alive = true;
@ -468,10 +456,25 @@ fn spawn_entities(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut materials_jupiter: ResMut<Assets<shading::JupitersRing>>, mut materials_jupiter: ResMut<Assets<shading::JupitersRing>>,
mut id2pos: ResMut<actor::Id2Pos>,
) { ) {
for state_wrapper in er_spawn.read() { for state_wrapper in er_spawn.read() {
let state = &state_wrapper.0; let state = &state_wrapper.0;
if state.class == DefClass::Actor { if state.class == DefClass::Actor {
let relative_pos = if let Some(id) = &state.relative_to {
match id2pos.0.get(&id.to_string()) {
Some(pos) => {
state.pos + *pos
}
None => {
error!("Specified `relativeto` command but could not find id `{id}`");
continue;
}
}
} else {
state.pos
};
let actor_entity; let actor_entity;
{ {
let mut actor = commands.spawn_empty(); let mut actor = commands.spawn_empty();
@ -484,7 +487,7 @@ fn spawn_entities(
actor.insert(SleepingDisabled); actor.insert(SleepingDisabled);
actor.insert(world::DespawnOnPlayerDeath); actor.insert(world::DespawnOnPlayerDeath);
actor.insert(actor::HitPoints::default()); actor.insert(actor::HitPoints::default());
actor.insert(Position::from(state.pos)); actor.insert(Position::from(relative_pos));
actor.insert(Rotation::from(state.rotation)); actor.insert(Rotation::from(state.rotation));
if state.is_sphere { if state.is_sphere {
let sphere_texture_handle = if let Some(model) = &state.model { let sphere_texture_handle = if let Some(model) = &state.model {
@ -603,6 +606,10 @@ fn spawn_entities(
..default() ..default()
}); });
} }
if !state.id.is_empty() {
actor.insert(actor::Identifier(state.id.clone()));
id2pos.0.insert(state.id.clone(), relative_pos);
}
if !state.chat.is_empty() { if !state.chat.is_empty() {
actor.insert(chat::Talker { actor.insert(chat::Talker {
actor_id: state.id.clone(), actor_id: state.id.clone(),
@ -661,10 +668,10 @@ fn spawn_entities(
ring_radius: nature::JUPITER_RING_RADIUS as f32, ring_radius: nature::JUPITER_RING_RADIUS as f32,
jupiter_radius: nature::JUPITER_RADIUS as f32, jupiter_radius: nature::JUPITER_RADIUS as f32,
}), }),
transform: Transform::from_translation(state.pos.as_vec3()), transform: Transform::from_translation(relative_pos.as_vec3()),
..default() ..default()
}, },
Position::new(state.pos), Position::new(relative_pos),
Rotation::from(Quat::IDENTITY), Rotation::from(Quat::IDENTITY),
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())), //Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
)); ));