WIP targeting world objects with mouse click

This commit is contained in:
yuni 2024-04-05 18:14:12 +02:00
parent c12dd41845
commit a37ba60eaf
4 changed files with 62 additions and 3 deletions

View file

@ -3,7 +3,7 @@ extern crate regex;
use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*;
use bevy::math::DVec3;
use crate::{actor, chat, nature, world};
use crate::{actor, chat, hud, nature, world};
use regex::Regex;
use std::f32::consts::PI;
use std::f64::consts::PI as PI64;
@ -49,6 +49,7 @@ struct ParserState {
is_alive: bool,
is_suited: bool,
is_vehicle: bool,
is_clickable: bool,
has_physics: bool,
wants_maxrotation: Option<f64>,
wants_maxvelocity: Option<f64>,
@ -102,6 +103,7 @@ impl Default for ParserState {
is_alive: false,
is_suited: false,
is_vehicle: false,
is_clickable: true,
has_physics: true,
wants_maxrotation: None,
wants_maxvelocity: None,
@ -263,6 +265,9 @@ pub fn load_defs(
["vehicle", "yes"] => {
state.is_vehicle = true;
}
["clickable", "no"] => {
state.is_clickable = false;
}
["moon", "yes"] => {
state.model_scale *= 3.0;
}
@ -652,6 +657,9 @@ fn spawn_entities(
..default()
});
}
if state.is_clickable {
actor.insert(hud::IsClickable);
}
if let Some(value) = state.wants_maxrotation {
actor.insert(actor::WantsMaxRotation(value));
}

View file

@ -21,6 +21,7 @@ actor 0 593051 0 suit
thrust 1.2 1 1 300 1.5
rotationy 0.65
engine monopropellant
clickable no
actor 10 -30 20 MeteorAceGT
relativeto player
@ -32,6 +33,7 @@ actor 10 -30 20 MeteorAceGT
camdistance 50
mass 3000
angularmomentum 0.1 0.1 0.3
clickable no
actor 0 0 0 io
relativeto jupiter

View file

@ -2,6 +2,7 @@ use crate::{actor, audio, chat, nature, settings};
use bevy::prelude::*;
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
use bevy_xpbd_3d::prelude::*;
use bevy::math::DVec3;
use std::collections::VecDeque;
use std::time::SystemTime;
@ -34,6 +35,8 @@ impl Plugin for HudPlugin {
#[derive(Component)] struct ChatText;
#[derive(Component)] struct Reticule;
#[derive(Component)] struct ToggleableHudElement;
#[derive(Component)] pub struct IsClickable;
#[derive(Component)] pub struct IsTargeted;
#[derive(Resource)]
struct FPSUpdateTimer(Timer);
@ -424,6 +427,7 @@ fn update(
mut query_chat: Query<&mut Text, (With<ChatText>, Without<GaugesText>)>,
query_all_actors: Query<&actor::Actor>,
settings: Res<settings::Settings>,
q_target: Query<&Position, With<IsTargeted>>,
) {
// TODO only when hud is actually on
if timer.0.tick(time.delta()).just_finished() || log.needs_rerendering {
@ -459,13 +463,31 @@ fn update(
text.sections[13].value = format!("{vitals:.0}%");
let all_actors = query_all_actors.iter().len();
text.sections[15].value = format!("{all_actors:.0}");
let (x, y, z) = (pos.x / 1.0e3, pos.y / 1.0e3, pos.z / 1.0e3);
text.sections[7].value = format!("{x:.0}km / {z:.0}km / {y:.0}km");
let integrity = suit.integrity * 100.0;
text.sections[17].value = format!("{integrity:.0}%");
let speed = cam_v.length();
let kmh = speed * 60.0 * 60.0 / 1000.0;
text.sections[19].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
// Target display
let target: Option<DVec3>;
if let Ok(targetpos) = q_target.get_single() {
target = Some(targetpos.0);
}
else if q_target.is_empty() {
target = Some(DVec3::new(0.0, 0.0, 0.0));
}
else {
target = None;
}
if let Some(target_pos) = target {
let dist = pos.0 - target_pos;
let (x, y, z) = (dist.x, dist.y, dist.z);
text.sections[7].value = format!("{x:.0}m / {z:.0}m / {y:.0}m");
}
else {
text.sections[7].value = format!("ERROR: MULTIPLE TARGETS");
}
}
}
@ -517,12 +539,17 @@ fn update(
}
fn handle_input(
mut commands: Commands,
keyboard_input: Res<ButtonInput<KeyCode>>,
mouse_input: Res<ButtonInput<MouseButton>>,
mut settings: ResMut<settings::Settings>,
mut q_hud: Query<&mut Visibility, With<ToggleableHudElement>>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_togglemusic: EventWriter<audio::ToggleMusicEvent>,
mut ambient_light: ResMut<AmbientLight>,
q_objects: Query<(Entity, &Transform), (With<IsClickable>, Without<IsTargeted>)>,
q_target: Query<Entity, With<IsTargeted>>,
q_camera: Query<&Transform, With<Camera>>,
) {
if keyboard_input.just_pressed(settings.key_togglehud) {
if settings.hud_active {
@ -542,4 +569,24 @@ fn handle_input(
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
ew_togglemusic.send(audio::ToggleMusicEvent());
}
if mouse_input.just_pressed(settings.key_selectobject) {
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
if q_target.is_empty() {
if let Ok(camtrans) = q_camera.get_single() {
for (entity, trans) in &q_objects {
// Use Transform instead of Position because we're basing this
// not on the player mesh but on the camera, which doesn't have a position.
if trans.translation.distance(camtrans.translation) < 50.0 {
commands.entity(entity).insert(IsTargeted);
break;
}
}
}
}
else {
for entity in &q_target {
commands.entity(entity).remove::<IsTargeted>();
}
}
}
}

View file

@ -13,6 +13,7 @@ pub struct Settings {
pub font_size_conversations: f32,
pub hud_active: bool,
pub third_person: bool,
pub key_selectobject: MouseButton,
pub key_togglehud: KeyCode,
pub key_exit: KeyCode,
pub key_restart: KeyCode,
@ -86,6 +87,7 @@ impl Default for Settings {
font_size_conversations: 32.0,
hud_active: false,
third_person: false,
key_selectobject: MouseButton::Left,
key_togglehud: KeyCode::Tab,
key_exit: KeyCode::Escape,
key_restart: KeyCode::F12,