keep track of positions of IDed objects, for easy rel. position calc.
This commit is contained in:
parent
1d73cf8367
commit
e3ff386011
2 changed files with 40 additions and 18 deletions
15
src/actor.rs
15
src/actor.rs
|
@ -3,6 +3,7 @@ use bevy_xpbd_3d::prelude::*;
|
|||
use bevy::scene::SceneInstance;
|
||||
use bevy::math::DVec3;
|
||||
use crate::{actor, audio, camera, chat, commands, effects, hud, nature, var, world};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
||||
const MAX_TRANSMISSION_DISTANCE: f32 = 100.0;
|
||||
|
@ -27,9 +28,11 @@ impl Plugin for ActorPlugin {
|
|||
));
|
||||
app.add_systems(PostUpdate, (
|
||||
handle_vehicle_enter_exit,
|
||||
update_id2pos,
|
||||
));
|
||||
app.add_event::<VehicleEnterExitEvent>();
|
||||
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 WantsMaxRotation(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)]
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use crate::{actor, chat, hud, nature, shading, world};
|
|||
use regex::Regex;
|
||||
use std::f32::consts::PI;
|
||||
use std::f64::consts::PI as PI64;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct CommandsPlugin;
|
||||
impl Plugin for CommandsPlugin {
|
||||
|
@ -39,6 +38,7 @@ struct ParserState {
|
|||
// Actor fields
|
||||
id: String,
|
||||
pos: DVec3,
|
||||
relative_to: Option<String>,
|
||||
model: Option<String>,
|
||||
model_scale: f32,
|
||||
rotation: Quat,
|
||||
|
@ -86,6 +86,7 @@ impl Default for ParserState {
|
|||
|
||||
id: "".to_string(),
|
||||
pos: DVec3::new(0.0, 0.0, 0.0),
|
||||
relative_to: None,
|
||||
model: None,
|
||||
model_scale: 1.0,
|
||||
rotation: Quat::IDENTITY,
|
||||
|
@ -135,7 +136,6 @@ pub fn load_defs(
|
|||
let mut state = ParserState::default();
|
||||
let mut command;
|
||||
let mut parameters;
|
||||
let mut id2pos: HashMap<String, DVec3> = HashMap::new();
|
||||
|
||||
let mut line_nr = -1;
|
||||
while let Some(line) = lines.next() {
|
||||
|
@ -207,18 +207,7 @@ pub fn load_defs(
|
|||
}
|
||||
}
|
||||
["relativeto", id] => {
|
||||
// NOTE: call this command before "id", otherwise actors that
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
state.relative_to = Some(id.to_string());
|
||||
}
|
||||
["orbit", radius_str, phase_str] => {
|
||||
if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) {
|
||||
|
@ -239,7 +228,6 @@ pub fn load_defs(
|
|||
}
|
||||
["id", id] => {
|
||||
state.id = id.to_string();
|
||||
id2pos.insert(state.id.clone(), state.pos.clone());
|
||||
}
|
||||
["alive", "yes"] => {
|
||||
state.is_alive = true;
|
||||
|
@ -468,10 +456,25 @@ fn spawn_entities(
|
|||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut materials_jupiter: ResMut<Assets<shading::JupitersRing>>,
|
||||
mut id2pos: ResMut<actor::Id2Pos>,
|
||||
) {
|
||||
for state_wrapper in er_spawn.read() {
|
||||
let state = &state_wrapper.0;
|
||||
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 mut actor = commands.spawn_empty();
|
||||
|
@ -484,7 +487,7 @@ fn spawn_entities(
|
|||
actor.insert(SleepingDisabled);
|
||||
actor.insert(world::DespawnOnPlayerDeath);
|
||||
actor.insert(actor::HitPoints::default());
|
||||
actor.insert(Position::from(state.pos));
|
||||
actor.insert(Position::from(relative_pos));
|
||||
actor.insert(Rotation::from(state.rotation));
|
||||
if state.is_sphere {
|
||||
let sphere_texture_handle = if let Some(model) = &state.model {
|
||||
|
@ -603,6 +606,10 @@ fn spawn_entities(
|
|||
..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() {
|
||||
actor.insert(chat::Talker {
|
||||
actor_id: state.id.clone(),
|
||||
|
@ -661,10 +668,10 @@ fn spawn_entities(
|
|||
ring_radius: nature::JUPITER_RING_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()
|
||||
},
|
||||
Position::new(state.pos),
|
||||
Position::new(relative_pos),
|
||||
Rotation::from(Quat::IDENTITY),
|
||||
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
||||
));
|
||||
|
|
Loading…
Add table
Reference in a new issue