Hurtbox & changing game speed
This commit is contained in:
Generated
+19
@@ -3163,6 +3163,23 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum_cycling"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "946bc4ae524a5ca6b8f8d2fa284fc51943d1520410854e4630463217be6b2990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum_cycling_derive"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "397cac860ca9b2ced0ff24d662806ad132471f12e371e8f579c1deb29de3a294"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enumn"
|
name = "enumn"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
@@ -3532,6 +3549,8 @@ dependencies = [
|
|||||||
"bincode",
|
"bincode",
|
||||||
"bitfields",
|
"bitfields",
|
||||||
"clap",
|
"clap",
|
||||||
|
"enum_cycling",
|
||||||
|
"enum_cycling_derive",
|
||||||
"fixed",
|
"fixed",
|
||||||
"gc-adapter-neo",
|
"gc-adapter-neo",
|
||||||
"gltf",
|
"gltf",
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ bevy_common_assets = { version = "0.17.0", features = ["ron"] }
|
|||||||
bevy_asset_loader = "0.27.0"
|
bevy_asset_loader = "0.27.0"
|
||||||
gc-adapter-neo = { version = "1.0.0", features = ["libusb"] }
|
gc-adapter-neo = { version = "1.0.0", features = ["libusb"] }
|
||||||
rhai = "1.26.0"
|
rhai = "1.26.0"
|
||||||
|
enum_cycling = "0.2.1"
|
||||||
|
enum_cycling_derive = "0.2.1"
|
||||||
|
|
||||||
# Enable a large amount of optimization in the dev profile for dependencies.
|
# Enable a large amount of optimization in the dev profile for dependencies.
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
|
|||||||
+104
-26
@@ -2,8 +2,14 @@
|
|||||||
|
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
use bevy::{prelude::*, settings::{SaveSettingsDeferred, SettingsGroup, ReflectSettingsGroup}};
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup},
|
||||||
|
};
|
||||||
use bevy_egui::{EguiContexts, EguiPrimaryContextPass, egui};
|
use bevy_egui::{EguiContexts, EguiPrimaryContextPass, egui};
|
||||||
|
use bevy_ggrs::RollbackFrameRate;
|
||||||
|
use enum_cycling::EnumCycle;
|
||||||
|
use enum_cycling_derive::EnumCycle;
|
||||||
|
|
||||||
use crate::player::Player;
|
use crate::player::Player;
|
||||||
|
|
||||||
@@ -42,6 +48,31 @@ impl PresentationMotionMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(EnumCycle, Reflect)]
|
||||||
|
pub enum GameSpeedDebug {
|
||||||
|
Full,
|
||||||
|
Half,
|
||||||
|
Quarter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameSpeedDebug {
|
||||||
|
pub const fn label(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
GameSpeedDebug::Full => "1.0x",
|
||||||
|
GameSpeedDebug::Half => "0.5x",
|
||||||
|
GameSpeedDebug::Quarter => "0.25x",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frame_rate(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
GameSpeedDebug::Full => 60,
|
||||||
|
GameSpeedDebug::Half => 30,
|
||||||
|
GameSpeedDebug::Quarter => 15,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FighterDebugRowKind {
|
impl FighterDebugRowKind {
|
||||||
const ALL: [Self; 6] = [
|
const ALL: [Self; 6] = [
|
||||||
Self::None,
|
Self::None,
|
||||||
@@ -100,6 +131,9 @@ enum DebugMenuEntry {
|
|||||||
MotionSampling {
|
MotionSampling {
|
||||||
label: &'static str,
|
label: &'static str,
|
||||||
},
|
},
|
||||||
|
GameSpeed {
|
||||||
|
label: &'static str,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const FIGHTER_MENU: &[DebugMenuEntry] = &[
|
const FIGHTER_MENU: &[DebugMenuEntry] = &[
|
||||||
@@ -124,10 +158,15 @@ const FIGHTER_MENU: &[DebugMenuEntry] = &[
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const WORLD_MENU: &[DebugMenuEntry] = &[DebugMenuEntry::Toggle {
|
const WORLD_MENU: &[DebugMenuEntry] = &[
|
||||||
label: "Stage collision",
|
DebugMenuEntry::Toggle {
|
||||||
flag: DebugFlag::StageCollision,
|
label: "Stage collision",
|
||||||
}];
|
flag: DebugFlag::StageCollision,
|
||||||
|
},
|
||||||
|
DebugMenuEntry::GameSpeed {
|
||||||
|
label: "Game speed",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const DIAGNOSTICS_MENU: &[DebugMenuEntry] = &[DebugMenuEntry::Toggle {
|
const DIAGNOSTICS_MENU: &[DebugMenuEntry] = &[DebugMenuEntry::Toggle {
|
||||||
label: "Network stats",
|
label: "Network stats",
|
||||||
@@ -169,6 +208,7 @@ enum DebugMenuPage {
|
|||||||
PlayerList,
|
PlayerList,
|
||||||
PlayerRows(usize),
|
PlayerRows(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, SettingsGroup, Reflect)]
|
#[derive(Resource, SettingsGroup, Reflect)]
|
||||||
#[reflect(Resource, SettingsGroup, Default)]
|
#[reflect(Resource, SettingsGroup, Default)]
|
||||||
pub struct DebugSettings {
|
pub struct DebugSettings {
|
||||||
@@ -190,6 +230,7 @@ pub struct DebugSettings {
|
|||||||
pub camera: bool,
|
pub camera: bool,
|
||||||
pub draw_through_geometry: bool,
|
pub draw_through_geometry: bool,
|
||||||
pub motion_sampling: PresentationMotionMode,
|
pub motion_sampling: PresentationMotionMode,
|
||||||
|
pub game_speed: GameSpeedDebug,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DebugSettings {
|
impl Default for DebugSettings {
|
||||||
@@ -208,6 +249,7 @@ impl Default for DebugSettings {
|
|||||||
camera: false,
|
camera: false,
|
||||||
draw_through_geometry: false,
|
draw_through_geometry: false,
|
||||||
motion_sampling: PresentationMotionMode::default(),
|
motion_sampling: PresentationMotionMode::default(),
|
||||||
|
game_speed: GameSpeedDebug::Full,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,6 +332,10 @@ impl DebugSettings {
|
|||||||
self.motion_sampling.cycle();
|
self.motion_sampling.cycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cycle_game_speed(&mut self) {
|
||||||
|
self.motion_sampling.cycle();
|
||||||
|
}
|
||||||
|
|
||||||
fn rows_mut(&mut self, handle: usize) -> &mut [FighterDebugRowKind; PLAYER_DEBUG_ROW_COUNT] {
|
fn rows_mut(&mut self, handle: usize) -> &mut [FighterDebugRowKind; PLAYER_DEBUG_ROW_COUNT] {
|
||||||
self.player_rows
|
self.player_rows
|
||||||
.entry(handle)
|
.entry(handle)
|
||||||
@@ -377,6 +423,50 @@ fn handle_palette_input(
|
|||||||
let selected = settings.selected_mut();
|
let selected = settings.selected_mut();
|
||||||
*selected = (*selected + 1) % page_len;
|
*selected = (*selected + 1) % page_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let direction = if gamepad.just_pressed(GamepadButton::DPadLeft) {
|
||||||
|
Some(-1)
|
||||||
|
} else if gamepad.just_pressed(GamepadButton::DPadRight) {
|
||||||
|
Some(1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(direction) = direction {
|
||||||
|
match page {
|
||||||
|
DebugMenuPage::Static(entries) => {
|
||||||
|
if let Some(entry) = entries.get(settings.selected()) {
|
||||||
|
match entry {
|
||||||
|
DebugMenuEntry::MotionSampling { .. } => settings.cycle_motion_sampling(),
|
||||||
|
DebugMenuEntry::GameSpeed { .. } => {
|
||||||
|
if direction > 0 {
|
||||||
|
settings.game_speed = settings.game_speed.up();
|
||||||
|
} else {
|
||||||
|
settings.game_speed = settings.game_speed.down();
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.insert_resource(RollbackFrameRate(
|
||||||
|
settings.game_speed.frame_rate(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebugMenuPage::PlayerList => todo!(),
|
||||||
|
DebugMenuPage::PlayerRows(_) => {
|
||||||
|
let DebugMenuPage::PlayerRows(handle) = page else {
|
||||||
|
unreachable!("player row navigation must have a player row page")
|
||||||
|
};
|
||||||
|
let selected = settings.selected();
|
||||||
|
let rows = settings.rows_mut(handle);
|
||||||
|
rows[selected] = rows[selected].cycle(direction);
|
||||||
|
|
||||||
|
commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if matches!(page, DebugMenuPage::PlayerRows(_)) {
|
if matches!(page, DebugMenuPage::PlayerRows(_)) {
|
||||||
let direction = if gamepad.just_pressed(GamepadButton::DPadLeft) {
|
let direction = if gamepad.just_pressed(GamepadButton::DPadLeft) {
|
||||||
Some(-1)
|
Some(-1)
|
||||||
@@ -385,26 +475,7 @@ fn handle_palette_input(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
if let Some(direction) = direction {
|
if let Some(direction) = direction {}
|
||||||
let DebugMenuPage::PlayerRows(handle) = page else {
|
|
||||||
unreachable!("player row navigation must have a player row page")
|
|
||||||
};
|
|
||||||
let selected = settings.selected();
|
|
||||||
let rows = settings.rows_mut(handle);
|
|
||||||
rows[selected] = rows[selected].cycle(direction);
|
|
||||||
|
|
||||||
commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let DebugMenuPage::Static(entries) = page
|
|
||||||
&& matches!(
|
|
||||||
entries.get(settings.selected()),
|
|
||||||
Some(DebugMenuEntry::MotionSampling { .. })
|
|
||||||
)
|
|
||||||
&& (gamepad.just_pressed(GamepadButton::DPadLeft)
|
|
||||||
|| gamepad.just_pressed(GamepadButton::DPadRight))
|
|
||||||
{
|
|
||||||
settings.cycle_motion_sampling();
|
|
||||||
}
|
}
|
||||||
if gamepad.just_pressed(GamepadButton::South) {
|
if gamepad.just_pressed(GamepadButton::South) {
|
||||||
match page {
|
match page {
|
||||||
@@ -412,12 +483,13 @@ fn handle_palette_input(
|
|||||||
DebugMenuEntry::Toggle { flag, .. } => {
|
DebugMenuEntry::Toggle { flag, .. } => {
|
||||||
settings.toggle_flag(flag);
|
settings.toggle_flag(flag);
|
||||||
commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.1)));
|
commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.1)));
|
||||||
},
|
}
|
||||||
DebugMenuEntry::Submenu { entries, .. } => {
|
DebugMenuEntry::Submenu { entries, .. } => {
|
||||||
settings.push_page(DebugMenuPage::Static(entries));
|
settings.push_page(DebugMenuPage::Static(entries));
|
||||||
}
|
}
|
||||||
DebugMenuEntry::PlayerSlots { .. } => settings.push_page(DebugMenuPage::PlayerList),
|
DebugMenuEntry::PlayerSlots { .. } => settings.push_page(DebugMenuPage::PlayerList),
|
||||||
DebugMenuEntry::MotionSampling { .. } => settings.cycle_motion_sampling(),
|
DebugMenuEntry::MotionSampling { .. } => settings.cycle_motion_sampling(),
|
||||||
|
DebugMenuEntry::GameSpeed { .. } => {}
|
||||||
},
|
},
|
||||||
DebugMenuPage::PlayerList if page_len != 0 => {
|
DebugMenuPage::PlayerList if page_len != 0 => {
|
||||||
let handle = player_handles[settings.selected()];
|
let handle = player_handles[settings.selected()];
|
||||||
@@ -483,6 +555,12 @@ fn draw_palette(
|
|||||||
settings.motion_sampling.label()
|
settings.motion_sampling.label()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
DebugMenuEntry::GameSpeed { label } => {
|
||||||
|
ui.label(format!(
|
||||||
|
"{marker} {label}: {}",
|
||||||
|
settings.game_speed.label()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ impl AttackHitbox {
|
|||||||
/// Knockback growth is authored in percent (110 means 1.1x).
|
/// Knockback growth is authored in percent (110 means 1.1x).
|
||||||
const KB_GROWTH_SCALE: FGi32 = FGi32::lit("0.01");
|
const KB_GROWTH_SCALE: FGi32 = FGi32::lit("0.01");
|
||||||
const DAMAGE_TERM_DIVISOR: FGi32 = FGi32::lit("20.0");
|
const DAMAGE_TERM_DIVISOR: FGi32 = FGi32::lit("20.0");
|
||||||
const DAMAGE_BONUS: FGi32 = FGi32::lit("2.0"); // effective damage floor in the damage term
|
const DAMAGE_BONUS: FGi32 = FGi32::lit("2.0"); // effective damage floor in the damage term
|
||||||
const CHARGE_SMASH_INTERRUPTION_MODIFIER: FGi32 = FGi32::lit("1.2");
|
const CHARGE_SMASH_INTERRUPTION_MODIFIER: FGi32 = FGi32::lit("1.2");
|
||||||
const CROUCH_CANCEL_MODIFIER: FGi32 = FGi32::lit("0.666667");
|
const CROUCH_CANCEL_MODIFIER: FGi32 = FGi32::lit("0.666667");
|
||||||
|
|
||||||
|
|||||||
+68
-7
@@ -1,5 +1,7 @@
|
|||||||
//! Fighter debug views: gizmos and the egui inspector window.
|
//! Fighter debug views: gizmos and the egui inspector window.
|
||||||
|
|
||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
use bevy::color::palettes::css::ORANGE;
|
use bevy::color::palettes::css::ORANGE;
|
||||||
use bevy::gizmos::primitives::dim3::Capsule3dBuilder;
|
use bevy::gizmos::primitives::dim3::Capsule3dBuilder;
|
||||||
use bevy::{color::palettes::css::YELLOW, prelude::*};
|
use bevy::{color::palettes::css::YELLOW, prelude::*};
|
||||||
@@ -9,10 +11,11 @@ use crate::debug_tools::{DebugSettings, FighterDebugRowKind};
|
|||||||
use crate::fighter::animation::FighterAnimationFrame;
|
use crate::fighter::animation::FighterAnimationFrame;
|
||||||
use crate::fighter::baked_animation::{BakedFighterAnimations, FighterBoneMatrices};
|
use crate::fighter::baked_animation::{BakedFighterAnimations, FighterBoneMatrices};
|
||||||
use crate::fighter::ecb::FighterPreviousECB;
|
use crate::fighter::ecb::FighterPreviousECB;
|
||||||
|
use crate::fighter::manifest::FighterManifest;
|
||||||
use crate::fighter::state::StateNameDebug;
|
use crate::fighter::state::StateNameDebug;
|
||||||
use crate::fighter::visual::FighterAnimations;
|
use crate::fighter::visual::FighterAnimations;
|
||||||
use crate::fighter::{
|
use crate::fighter::{
|
||||||
FighterECB, FighterFacingDirection, FighterHitboxes, FighterPreviousTranslation,
|
Fighter, FighterECB, FighterFacingDirection, FighterHitboxes, FighterPreviousTranslation,
|
||||||
FighterTranslation, FighterVelocity,
|
FighterTranslation, FighterVelocity,
|
||||||
};
|
};
|
||||||
use crate::input::FighterInput;
|
use crate::input::FighterInput;
|
||||||
@@ -157,6 +160,52 @@ pub fn animation_debug(query: Query<(&GlobalTransform, &FighterBoneMatrices)>, m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hurtbox_debug(
|
||||||
|
query: Query<(
|
||||||
|
&FighterBoneMatrices,
|
||||||
|
&FighterTranslation,
|
||||||
|
&FighterFacingDirection,
|
||||||
|
&Fighter,
|
||||||
|
)>,
|
||||||
|
manifests: Res<Assets<FighterManifest>>,
|
||||||
|
mut gizmos: Gizmos,
|
||||||
|
) {
|
||||||
|
for (matrices, translation, facing_direction, fighter) in query {
|
||||||
|
let manifest = manifests
|
||||||
|
.get(&fighter.manifest)
|
||||||
|
.expect("Manifest should be valid");
|
||||||
|
let fighter_trf = translation.get_3d_transform(facing_direction);
|
||||||
|
for hurtbox in manifest.hurtboxes.iter() {
|
||||||
|
let bone_matrix = matrices.get_current(&hurtbox.bone);
|
||||||
|
|
||||||
|
if let Some(bone_matrix) = bone_matrix {
|
||||||
|
let to_global = fighter_trf.mul(bone_matrix);
|
||||||
|
let capsule = Capsule3d {
|
||||||
|
half_length: hurtbox.half_length.to_num(),
|
||||||
|
radius: hurtbox.radius.to_num(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let hurtbox_trf = Transform::IDENTITY
|
||||||
|
.with_rotation(Quat::from_euler(
|
||||||
|
EulerRot::XYZ,
|
||||||
|
f32::to_radians(hurtbox.rotation.x.to_num()),
|
||||||
|
f32::to_radians(hurtbox.rotation.y.to_num()),
|
||||||
|
f32::to_radians(hurtbox.rotation.z.to_num()),
|
||||||
|
))
|
||||||
|
.with_translation(hurtbox.offset.to_vec3());
|
||||||
|
|
||||||
|
let hurtbox_trf = Transform::from_matrix(to_global.to_mat4()).mul(hurtbox_trf);
|
||||||
|
|
||||||
|
gizmos.primitive_3d(
|
||||||
|
&capsule,
|
||||||
|
hurtbox_trf.to_isometry(),
|
||||||
|
bevy::color::palettes::css::YELLOW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn attack_debug(
|
pub fn attack_debug(
|
||||||
query: Query<(
|
query: Query<(
|
||||||
&FighterHitboxes,
|
&FighterHitboxes,
|
||||||
@@ -164,12 +213,11 @@ pub fn attack_debug(
|
|||||||
&FighterTranslation,
|
&FighterTranslation,
|
||||||
&FighterFacingDirection,
|
&FighterFacingDirection,
|
||||||
&FighterAnimationFrame,
|
&FighterAnimationFrame,
|
||||||
&GlobalTransform
|
|
||||||
)>,
|
)>,
|
||||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||||
mut gizmos: Gizmos,
|
mut gizmos: Gizmos,
|
||||||
) {
|
) {
|
||||||
for (hitboxes, matrices, translation, facing_direction, frame, global_trf) in query {
|
for (hitboxes, matrices, translation, facing_direction, frame) in query {
|
||||||
if let Some(script) = &hitboxes.attack_script {
|
if let Some(script) = &hitboxes.attack_script {
|
||||||
let script = attack_scripts
|
let script = attack_scripts
|
||||||
.get(script)
|
.get(script)
|
||||||
@@ -194,7 +242,11 @@ pub fn attack_debug(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if script.hitboxes[*i].start_frame == frame.frame {
|
if script.hitboxes[*i].start_frame == frame.frame {
|
||||||
gizmos.sphere(curr_pos_draw, radius.to_num(), bevy::color::palettes::css::RED);
|
gizmos.sphere(
|
||||||
|
curr_pos_draw,
|
||||||
|
radius.to_num(),
|
||||||
|
bevy::color::palettes::css::RED,
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +260,6 @@ pub fn attack_debug(
|
|||||||
prev_pos.z.to_num(),
|
prev_pos.z.to_num(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
let dist = Dir3::new_and_length(curr_pos_draw - prev_pos_draw);
|
let dist = Dir3::new_and_length(curr_pos_draw - prev_pos_draw);
|
||||||
|
|
||||||
if let Ok((aim_dir, dist)) = dist {
|
if let Ok((aim_dir, dist)) = dist {
|
||||||
@@ -231,8 +282,18 @@ pub fn attack_debug(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gizmos.cross(curr_trf.transform_point(FGVec3::lit("0.0", "0.0", "0.0")).to_vec3(), 1.0, bevy::color::palettes::css::BLUE);
|
gizmos.cross(
|
||||||
gizmos.cross(curr_trf.to_mat4().transform_point(Vec3::ZERO), 1.0, bevy::color::palettes::css::HOT_PINK);
|
curr_trf
|
||||||
|
.transform_point(FGVec3::lit("0.0", "0.0", "0.0"))
|
||||||
|
.to_vec3(),
|
||||||
|
1.0,
|
||||||
|
bevy::color::palettes::css::BLUE,
|
||||||
|
);
|
||||||
|
gizmos.cross(
|
||||||
|
curr_trf.to_mat4().transform_point(Vec3::ZERO),
|
||||||
|
1.0,
|
||||||
|
bevy::color::palettes::css::HOT_PINK,
|
||||||
|
);
|
||||||
|
|
||||||
gizmos.axes(curr_trf.to_mat4(), 1.0);
|
gizmos.axes(curr_trf.to_mat4(), 1.0);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+13
-1
@@ -7,7 +7,7 @@ use strum::IntoEnumIterator;
|
|||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, fighter::{FighterAttributes, FighterCameraProfile, animation::AnimKind, attack::AttackKind}, game_settings::GameSettings,
|
AppState, fighter::{FighterAttributes, FighterCameraProfile, animation::AnimKind, attack::AttackKind}, game_settings::GameSettings, math::{int::FGi32, vec3::FGVec3},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, EnumIter)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, EnumIter)]
|
||||||
@@ -15,6 +15,17 @@ pub enum FighterId {
|
|||||||
TestFighter,
|
TestFighter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Asset, Reflect, Default)]
|
||||||
|
pub struct FighterHurtbox {
|
||||||
|
pub bone: String,
|
||||||
|
pub offset: FGVec3,
|
||||||
|
pub rotation: FGVec3,
|
||||||
|
#[reflect(ignore)]
|
||||||
|
pub half_length: FGi32,
|
||||||
|
#[reflect(ignore)]
|
||||||
|
pub radius: FGi32
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Asset, Reflect)]
|
#[derive(Serialize, Deserialize, Clone, Asset, Reflect)]
|
||||||
pub struct FighterManifest {
|
pub struct FighterManifest {
|
||||||
pub id: FighterId,
|
pub id: FighterId,
|
||||||
@@ -24,6 +35,7 @@ pub struct FighterManifest {
|
|||||||
pub camera: FighterCameraProfile,
|
pub camera: FighterCameraProfile,
|
||||||
pub animations: HashMap<AnimKind, String>,
|
pub animations: HashMap<AnimKind, String>,
|
||||||
pub attack_scripts: HashMap<AttackKind, String>,
|
pub attack_scripts: HashMap<AttackKind, String>,
|
||||||
|
pub hurtboxes: Vec<FighterHurtbox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ impl Plugin for FighterPlugin {
|
|||||||
FixedPostUpdate,
|
FixedPostUpdate,
|
||||||
debug::attack_debug.run_if(crate::debug_tools::attack_hitboxes_enabled),
|
debug::attack_debug.run_if(crate::debug_tools::attack_hitboxes_enabled),
|
||||||
)
|
)
|
||||||
|
.add_systems(
|
||||||
|
FixedPostUpdate,
|
||||||
|
debug::hurtbox_debug
|
||||||
|
)
|
||||||
.rollback_component_with_clone::<FighterState>()
|
.rollback_component_with_clone::<FighterState>()
|
||||||
.rollback_component_with_clone::<FighterHitboxes>()
|
.rollback_component_with_clone::<FighterHitboxes>()
|
||||||
.checksum_component_with_hash::<FighterState>()
|
.checksum_component_with_hash::<FighterState>()
|
||||||
|
|||||||
@@ -33,3 +33,9 @@ impl FGVec3 {
|
|||||||
Vec3::new(self.x.to_num(), self.y.to_num(), self.z.to_num())
|
Vec3::new(self.x.to_num(), self.y.to_num(), self.z.to_num())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(&str, &str, &str)> for FGVec3 {
|
||||||
|
fn from((x, y, z): (&str, &str, &str)) -> Self {
|
||||||
|
Self::lit(x, y, z)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user