mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Show hitbox cylinders based on actual ECS data, and add a settings toggle in voxygen for it.
This commit is contained in:
parent
364890653f
commit
2a5e66400f
@ -10,6 +10,7 @@
|
||||
"hud.settings.press_behavior.hold": "Hold",
|
||||
"hud.settings.help_window": "Help Window",
|
||||
"hud.settings.debug_info": "Debug Info",
|
||||
"hud.settings.show_hitboxes": "Show hitboxes",
|
||||
"hud.settings.tips_on_startup": "Tips-On-Startup",
|
||||
"hud.settings.ui_scale": "UI-Scale",
|
||||
"hud.settings.relative_scaling": "Relative Scaling",
|
||||
|
@ -36,6 +36,8 @@ widget_ids! {
|
||||
load_tips_button_label,
|
||||
debug_button,
|
||||
debug_button_label,
|
||||
hitboxes_button,
|
||||
hitboxes_button_label,
|
||||
ch_title,
|
||||
ch_transp_slider,
|
||||
ch_transp_value,
|
||||
@ -239,9 +241,33 @@ impl<'a> Widget for Interface<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.debug_button_label, ui);
|
||||
|
||||
// Hitboxes
|
||||
let show_hitboxes = ToggleButton::new(
|
||||
self.global_state.settings.interface.toggle_hitboxes,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.debug_button, 8.0)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.hitboxes_button, ui);
|
||||
|
||||
if self.global_state.settings.interface.toggle_hitboxes != show_hitboxes {
|
||||
events.push(ToggleHitboxes(show_hitboxes));
|
||||
}
|
||||
|
||||
Text::new(&self.localized_strings.get("hud.settings.show_hitboxes"))
|
||||
.right_from(state.ids.hitboxes_button, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.hitboxes_button)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.hitboxes_button_label, ui);
|
||||
|
||||
// Ui Scale
|
||||
Text::new(&self.localized_strings.get("hud.settings.ui_scale"))
|
||||
.down_from(state.ids.debug_button, 20.0)
|
||||
.down_from(state.ids.hitboxes_button, 20.0)
|
||||
.font_size(self.fonts.cyri.scale(18))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
|
@ -1,6 +1,4 @@
|
||||
use super::{
|
||||
super::{AaMode, Bound, Consts, GlobalsLayouts, Vertex as VertexTrait},
|
||||
};
|
||||
use super::super::{AaMode, Bound, Consts, GlobalsLayouts, Vertex as VertexTrait};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use std::mem;
|
||||
use vek::*;
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::render::{
|
||||
Bound, Consts, DebugLocals, DebugVertex, FirstPassDrawer, Mesh,
|
||||
Model, Quad, Renderer, Tri,
|
||||
Bound, Consts, DebugLocals, DebugVertex, FirstPassDrawer, Mesh, Model, Quad, Renderer, Tri,
|
||||
};
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use vek::*;
|
||||
|
@ -44,6 +44,7 @@ use crate::{
|
||||
window::{AnalogGameInput, Event, GameInput},
|
||||
Direction, Error, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use settings_change::Language::ChangeLanguage;
|
||||
|
||||
/// The action to perform after a tick
|
||||
@ -73,7 +74,7 @@ pub struct SessionState {
|
||||
selected_entity: Option<(specs::Entity, std::time::Instant)>,
|
||||
interactable: Option<Interactable>,
|
||||
saved_zoom_dist: Option<f32>,
|
||||
player_hitbox: DebugShapeId,
|
||||
hitboxes: HashMap<specs::Entity, DebugShapeId>,
|
||||
}
|
||||
|
||||
/// Represents an active game session (i.e., the one being played).
|
||||
@ -101,10 +102,6 @@ impl SessionState {
|
||||
let hud = Hud::new(global_state, &client.borrow());
|
||||
let walk_forward_dir = scene.camera().forward_xy();
|
||||
let walk_right_dir = scene.camera().right_xy();
|
||||
let player_hitbox = scene.debug.add_shape(DebugShape::Cylinder {
|
||||
radius: 0.4,
|
||||
height: 1.75,
|
||||
});
|
||||
|
||||
Self {
|
||||
scene,
|
||||
@ -125,7 +122,7 @@ impl SessionState {
|
||||
selected_entity: None,
|
||||
interactable: None,
|
||||
saved_zoom_dist: None,
|
||||
player_hitbox,
|
||||
hitboxes: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,16 +142,54 @@ impl SessionState {
|
||||
span!(_guard, "tick", "Session::tick");
|
||||
|
||||
let mut client = self.client.borrow_mut();
|
||||
if let Some(player_pos) = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_component::<Pos>()
|
||||
.get(client.entity())
|
||||
{
|
||||
let pos = [player_pos.0.x, player_pos.0.y, player_pos.0.z, 0.0];
|
||||
self.scene
|
||||
.debug
|
||||
.set_pos_and_color(self.player_hitbox, pos, [1.0, 0.0, 0.0, 0.5]);
|
||||
let ecs = client.state().ecs();
|
||||
let mut current_entities = hashbrown::HashSet::new();
|
||||
let scene = &mut self.scene;
|
||||
let hitboxes = &mut self.hitboxes;
|
||||
if global_state.settings.interface.toggle_hitboxes {
|
||||
let positions = ecs.read_component::<Pos>();
|
||||
let colliders = ecs.read_component::<comp::Collider>();
|
||||
let groups = ecs.read_component::<comp::Group>();
|
||||
for (entity, pos, collider, group) in
|
||||
(&ecs.entities(), &positions, &colliders, groups.maybe()).join()
|
||||
{
|
||||
if let comp::Collider::Box {
|
||||
radius,
|
||||
z_min,
|
||||
z_max,
|
||||
} = collider
|
||||
{
|
||||
current_entities.insert(entity);
|
||||
let shape_id = hitboxes.entry(entity).or_insert_with(|| {
|
||||
scene.debug.add_shape(DebugShape::Cylinder {
|
||||
radius: *radius,
|
||||
height: *z_max - *z_min,
|
||||
})
|
||||
});
|
||||
let hb_pos = [pos.0.x, pos.0.y, pos.0.z + *z_min, 0.0];
|
||||
let color = if group == Some(&comp::group::ENEMY) {
|
||||
[1.0, 0.0, 0.0, 0.5]
|
||||
} else if group == Some(&comp::group::NPC) {
|
||||
[0.0, 0.0, 1.0, 0.5]
|
||||
} else {
|
||||
[0.0, 1.0, 0.0, 0.5]
|
||||
};
|
||||
scene.debug.set_pos_and_color(*shape_id, hb_pos, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut to_remove = Vec::new();
|
||||
hitboxes.retain(|k, v| {
|
||||
let keep = current_entities.contains(k);
|
||||
if !keep {
|
||||
to_remove.push(*v);
|
||||
}
|
||||
keep
|
||||
});
|
||||
for shape_id in to_remove.into_iter() {
|
||||
scene.debug.remove_shape(shape_id);
|
||||
}
|
||||
}
|
||||
for event in client.tick(self.inputs.clone(), dt, crate::ecs::sys::add_local_systems)? {
|
||||
match event {
|
||||
|
@ -96,6 +96,7 @@ pub enum Interface {
|
||||
SpeechBubbleIcon(bool),
|
||||
ToggleHelp(bool),
|
||||
ToggleDebug(bool),
|
||||
ToggleHitboxes(bool),
|
||||
ToggleTips(bool),
|
||||
|
||||
CrosshairTransp(f32),
|
||||
@ -445,6 +446,9 @@ impl SettingsChange {
|
||||
Interface::ToggleDebug(toggle_debug) => {
|
||||
settings.interface.toggle_debug = toggle_debug;
|
||||
},
|
||||
Interface::ToggleHitboxes(toggle_hitboxes) => {
|
||||
settings.interface.toggle_hitboxes = toggle_hitboxes;
|
||||
},
|
||||
Interface::ToggleTips(loading_tips) => {
|
||||
settings.interface.loading_tips = loading_tips;
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ use vek::*;
|
||||
#[serde(default)]
|
||||
pub struct InterfaceSettings {
|
||||
pub toggle_debug: bool,
|
||||
pub toggle_hitboxes: bool,
|
||||
pub sct: bool,
|
||||
pub sct_player_batch: bool,
|
||||
pub sct_damage_batch: bool,
|
||||
@ -43,6 +44,7 @@ impl Default for InterfaceSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
toggle_debug: false,
|
||||
toggle_hitboxes: false,
|
||||
sct: true,
|
||||
sct_player_batch: false,
|
||||
sct_damage_batch: false,
|
||||
|
Loading…
Reference in New Issue
Block a user