Make dashback more lenient
This commit is contained in:
@@ -3,7 +3,11 @@ use std::time::Duration;
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fighter::{FighterECB, FighterFacingDirection, FighterTranslation, FighterVisual, visual::FighterAnimations}, player::Player,
|
fighter::{
|
||||||
|
FighterECB, FighterFacingDirection, FighterTranslation, FighterVisual,
|
||||||
|
visual::FighterAnimations,
|
||||||
|
},
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
@@ -26,7 +30,11 @@ pub struct FighterAnimationFrame {
|
|||||||
|
|
||||||
impl FighterAnimationFrame {
|
impl FighterAnimationFrame {
|
||||||
pub const fn new(kind: AnimKind, repeat: bool) -> Self {
|
pub const fn new(kind: AnimKind, repeat: bool) -> Self {
|
||||||
Self { kind, frame: 0, repeat }
|
Self {
|
||||||
|
kind,
|
||||||
|
frame: 0,
|
||||||
|
repeat,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self, kind: AnimKind, repeat: bool) {
|
pub fn reset(&mut self, kind: AnimKind, repeat: bool) {
|
||||||
@@ -78,16 +86,28 @@ pub fn setup_fighter_animation_player(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_animation(children: Query<(&mut Transform, &FighterFacingDirection, &FighterAnimationFrame), With<FighterVisual>>) {
|
pub fn apply_animation(
|
||||||
|
children: Query<
|
||||||
|
(
|
||||||
|
&mut Transform,
|
||||||
|
&FighterFacingDirection,
|
||||||
|
&FighterAnimationFrame,
|
||||||
|
),
|
||||||
|
With<FighterVisual>,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
for (mut trf, facing_direction, frame) in children {
|
for (mut trf, facing_direction, frame) in children {
|
||||||
// Melee model scale is in decimeters
|
// Melee model scale is in decimeters
|
||||||
trf.rotation = Quat::IDENTITY;
|
trf.rotation = Quat::IDENTITY;
|
||||||
if let AnimKind::Turn = frame.kind {
|
if let AnimKind::Turn = frame.kind {
|
||||||
trf.rotate_local_y(std::f32::consts::PI * -0.5 * facing_direction.to_sign().to_num::<f32>());
|
trf.rotate_local_y(
|
||||||
|
std::f32::consts::PI * -0.5 * facing_direction.to_sign().to_num::<f32>(),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
trf.rotate_local_y(std::f32::consts::PI * 0.5 * facing_direction.to_sign().to_num::<f32>());
|
trf.rotate_local_y(
|
||||||
|
std::f32::consts::PI * 0.5 * facing_direction.to_sign().to_num::<f32>(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub struct FighterAttributes {
|
|||||||
|
|
||||||
pub air_dodge_duration: u32,
|
pub air_dodge_duration: u32,
|
||||||
pub air_dodge_velocity: FGi32,
|
pub air_dodge_velocity: FGi32,
|
||||||
pub air_dodge_decay: FGi32
|
pub air_dodge_decay: FGi32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FighterAttributes {
|
impl FighterAttributes {
|
||||||
|
|||||||
+13
-9
@@ -10,7 +10,10 @@ use crate::fighter::ecb::FighterPreviousECB;
|
|||||||
use crate::fighter::manifest::{FighterManifest, FighterManifestRegistry};
|
use crate::fighter::manifest::{FighterManifest, FighterManifestRegistry};
|
||||||
use crate::fighter::state::StateNameDebug;
|
use crate::fighter::state::StateNameDebug;
|
||||||
use crate::fighter::visual::FighterAnimations;
|
use crate::fighter::visual::FighterAnimations;
|
||||||
use crate::fighter::{Fighter, FighterECB, FighterFacingDirection, FighterPreviousTranslation, FighterTranslation, FighterVelocity};
|
use crate::fighter::{
|
||||||
|
Fighter, FighterECB, FighterFacingDirection, FighterPreviousTranslation, FighterTranslation,
|
||||||
|
FighterVelocity,
|
||||||
|
};
|
||||||
use crate::input::FighterInput;
|
use crate::input::FighterInput;
|
||||||
use crate::match_loading::MatchPlayer;
|
use crate::match_loading::MatchPlayer;
|
||||||
|
|
||||||
@@ -45,26 +48,27 @@ pub fn fighter_debug(
|
|||||||
ui.label(format!("{:?}", vel));
|
ui.label(format!("{:?}", vel));
|
||||||
ui.label(format!("{:?}", input.get_last_frame()));
|
ui.label(format!("{:?}", input.get_last_frame()));
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn animation_debug(
|
pub fn animation_debug(
|
||||||
query: Query<(
|
query: Query<(&GlobalTransform, &FighterAnimationFrame, &FighterAnimations)>,
|
||||||
&GlobalTransform,
|
|
||||||
&FighterAnimationFrame,
|
|
||||||
&FighterAnimations,
|
|
||||||
)>,
|
|
||||||
baked_anims: Res<Assets<BakedFighterAnimations>>,
|
baked_anims: Res<Assets<BakedFighterAnimations>>,
|
||||||
mut gizmos: Gizmos,
|
mut gizmos: Gizmos,
|
||||||
) {
|
) {
|
||||||
for (global_transform, frame, anims) in query {
|
for (global_transform, frame, anims) in query {
|
||||||
let baked: &BakedFighterAnimations = baked_anims.get(&anims.baked).expect("Baked anims should be in");
|
let baked: &BakedFighterAnimations = baked_anims
|
||||||
|
.get(&anims.baked)
|
||||||
|
.expect("Baked anims should be in");
|
||||||
for bone in &baked.bone_names {
|
for bone in &baked.bone_names {
|
||||||
let out = anims.sample_bone(&baked_anims, *frame, bone);
|
let out = anims.sample_bone(&baked_anims, *frame, bone);
|
||||||
if let Some(out) = out {
|
if let Some(out) = out {
|
||||||
let pos = global_transform.transform_point(Vec3::new(out.cols[3][0].to_num(), out.cols[3][1].to_num(), out.cols[3][2].to_num()));
|
let pos = global_transform.transform_point(Vec3::new(
|
||||||
|
out.cols[3][0].to_num(),
|
||||||
|
out.cols[3][1].to_num(),
|
||||||
|
out.cols[3][2].to_num(),
|
||||||
|
));
|
||||||
gizmos.cross(pos, 0.5, bevy::color::palettes::css::RED);
|
gizmos.cross(pos, 0.5, bevy::color::palettes::css::RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-6
@@ -36,10 +36,22 @@ pub fn snapshot_fighter_ecb(fighters: Query<(&FighterECB, &mut FighterPreviousEC
|
|||||||
|
|
||||||
impl FighterECB {
|
impl FighterECB {
|
||||||
pub fn to_3d_lineloop(&self, trf: Transform) -> [Vec3; 4] {
|
pub fn to_3d_lineloop(&self, trf: Transform) -> [Vec3; 4] {
|
||||||
let rel_up = trf.transform_point(Vec3::new(0.0, (self.vertical_half + self.vertical_half).to_num(), 0.0));
|
let rel_up = trf.transform_point(Vec3::new(
|
||||||
|
0.0,
|
||||||
|
(self.vertical_half + self.vertical_half).to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
let rel_down = trf.transform_point(Vec3::new(0.0, 0.0, 0.0));
|
let rel_down = trf.transform_point(Vec3::new(0.0, 0.0, 0.0));
|
||||||
let rel_left = trf.transform_point(Vec3::new((-self.horizontal_half).to_num(), self.vertical_half.to_num(), 0.0));
|
let rel_left = trf.transform_point(Vec3::new(
|
||||||
let rel_right = trf.transform_point(Vec3::new(self.horizontal_half.to_num(), self.vertical_half.to_num(), 0.0));
|
(-self.horizontal_half).to_num(),
|
||||||
|
self.vertical_half.to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
|
let rel_right = trf.transform_point(Vec3::new(
|
||||||
|
self.horizontal_half.to_num(),
|
||||||
|
self.vertical_half.to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
[rel_up, rel_right, rel_down, rel_left]
|
[rel_up, rel_right, rel_down, rel_left]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +62,22 @@ impl FighterECB {
|
|||||||
|
|
||||||
impl FighterPreviousECB {
|
impl FighterPreviousECB {
|
||||||
pub fn to_3d_lineloop(&self, trf: Transform) -> [Vec3; 4] {
|
pub fn to_3d_lineloop(&self, trf: Transform) -> [Vec3; 4] {
|
||||||
let rel_up = trf.transform_point(Vec3::new(0.0, (self.vertical_half + self.vertical_half).to_num(), 0.0));
|
let rel_up = trf.transform_point(Vec3::new(
|
||||||
|
0.0,
|
||||||
|
(self.vertical_half + self.vertical_half).to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
let rel_down = trf.transform_point(Vec3::new(0.0, 0.0, 0.0));
|
let rel_down = trf.transform_point(Vec3::new(0.0, 0.0, 0.0));
|
||||||
let rel_left = trf.transform_point(Vec3::new((-self.horizontal_half).to_num(), self.vertical_half.to_num(), 0.0));
|
let rel_left = trf.transform_point(Vec3::new(
|
||||||
let rel_right = trf.transform_point(Vec3::new(self.horizontal_half.to_num(), self.vertical_half.to_num(), 0.0));
|
(-self.horizontal_half).to_num(),
|
||||||
|
self.vertical_half.to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
|
let rel_right = trf.transform_point(Vec3::new(
|
||||||
|
self.horizontal_half.to_num(),
|
||||||
|
self.vertical_half.to_num(),
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
[rel_up, rel_right, rel_down, rel_left]
|
[rel_up, rel_right, rel_down, rel_left]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-5
@@ -7,8 +7,8 @@ use bevy_ggrs::prelude::*;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod animation;
|
pub mod animation;
|
||||||
pub mod baked_animation;
|
|
||||||
pub mod attributes;
|
pub mod attributes;
|
||||||
|
pub mod baked_animation;
|
||||||
pub mod collision;
|
pub mod collision;
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
pub mod ecb;
|
pub mod ecb;
|
||||||
@@ -28,8 +28,16 @@ pub use motion::{FighterPreviousTranslation, FighterTranslation, FighterVelocity
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fighter::{
|
fighter::{
|
||||||
animation::animation_init, manifest::FighterManifest, state::{FighterState, fall::FallState}, visual::FighterAnimations,
|
animation::animation_init,
|
||||||
}, input::FighterInput, math::{int::FGi32, vec::FGVec2}, player::Player, schedule::GameplaySet, stage::line::StageCollision,
|
manifest::FighterManifest,
|
||||||
|
state::{FighterState, fall::FallState},
|
||||||
|
visual::FighterAnimations,
|
||||||
|
},
|
||||||
|
input::FighterInput,
|
||||||
|
math::{int::FGi32, vec::FGVec2},
|
||||||
|
player::Player,
|
||||||
|
schedule::GameplaySet,
|
||||||
|
stage::line::StageCollision,
|
||||||
};
|
};
|
||||||
use state::state_interrupt_system;
|
use state::state_interrupt_system;
|
||||||
|
|
||||||
@@ -91,7 +99,7 @@ pub struct FighterVisual;
|
|||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Fighter {
|
pub struct Fighter {
|
||||||
id: FighterId,
|
id: FighterId,
|
||||||
pub manifest: Handle<FighterManifest>
|
pub manifest: Handle<FighterManifest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for FighterPlugin {
|
impl Plugin for FighterPlugin {
|
||||||
@@ -174,7 +182,7 @@ pub fn spawn_fighter(
|
|||||||
},
|
},
|
||||||
Fighter {
|
Fighter {
|
||||||
id: manifest.1.id,
|
id: manifest.1.id,
|
||||||
manifest: manifest.0
|
manifest: manifest.0,
|
||||||
},
|
},
|
||||||
FighterFacingDirection::Right,
|
FighterFacingDirection::Right,
|
||||||
FighterECB {
|
FighterECB {
|
||||||
@@ -189,5 +197,6 @@ pub fn spawn_fighter(
|
|||||||
animation::FighterAnimationFrame::new(animation::AnimKind::Wait, true),
|
animation::FighterAnimationFrame::new(animation::AnimKind::Wait, true),
|
||||||
FighterVisual,
|
FighterVisual,
|
||||||
FighterInput::default(),
|
FighterInput::default(),
|
||||||
|
crate::camera::FighterCameraExtents::default(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::fighter::collision;
|
|||||||
use crate::fighter::state::fall::FallState;
|
use crate::fighter::state::fall::FallState;
|
||||||
use crate::fighter::state::ground::{self, GroundedMotionResult, GroundedStateCommon};
|
use crate::fighter::state::ground::{self, GroundedMotionResult, GroundedStateCommon};
|
||||||
use crate::fighter::state::land::LandingState;
|
use crate::fighter::state::land::LandingState;
|
||||||
use crate::fighter::state::{FighterState, air, dash, jump, wait, walk};
|
use crate::fighter::state::{air, dash, jump, wait, walk, FighterState};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
pub struct TurnState {
|
pub struct TurnState {
|
||||||
@@ -80,9 +80,13 @@ pub fn check_input(
|
|||||||
grounded_common: &GroundedStateCommon,
|
grounded_common: &GroundedStateCommon,
|
||||||
) -> Option<FighterState> {
|
) -> Option<FighterState> {
|
||||||
let input_frame = state_context.input.get_last_frame();
|
let input_frame = state_context.input.get_last_frame();
|
||||||
|
let smash_input_frame_threshold = state_context
|
||||||
|
.game_settings
|
||||||
|
.input_common
|
||||||
|
.smash_input_frame_threshold;
|
||||||
if !input_frame.movement.x.is_zero()
|
if !input_frame.movement.x.is_zero()
|
||||||
&& input_frame.movement.x.signum() != state_context.facing_direction.to_sign()
|
&& input_frame.movement.x.signum() != state_context.facing_direction.to_sign()
|
||||||
|
&& state_context.input.get_frames_in_smash_move_deadzone() > smash_input_frame_threshold
|
||||||
{
|
{
|
||||||
return Some(FighterState::Turn(TurnState {
|
return Some(FighterState::Turn(TurnState {
|
||||||
grounded_common: grounded_common.clone(),
|
grounded_common: grounded_common.clone(),
|
||||||
|
|||||||
@@ -18,20 +18,18 @@ pub struct WaitState {
|
|||||||
impl FighterStateImpl for WaitState {
|
impl FighterStateImpl for WaitState {
|
||||||
const NAME: &'static str = "Wait";
|
const NAME: &'static str = "Wait";
|
||||||
fn check_interrupt(&self, state_context: &mut FighterStateContext) -> Option<FighterState> {
|
fn check_interrupt(&self, state_context: &mut FighterStateContext) -> Option<FighterState> {
|
||||||
if let Some(state) = ground::grounded_movement_standstill_common_interrupts(
|
if let Some(state) = ground::grounded_movement_common_interrupts(state_context, &self.grounded_common) {
|
||||||
|
Some(state)
|
||||||
|
} else if let Some(state) = ground::grounded_movement_standstill_common_interrupts(
|
||||||
state_context,
|
state_context,
|
||||||
&self.grounded_common,
|
&self.grounded_common)
|
||||||
) {
|
{
|
||||||
// Prevent transitioning into myself
|
// Don't transition into yourself
|
||||||
if let FighterState::Wait(_) = state {
|
if let FighterState::Wait(_) = state {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(state)
|
Some(state)
|
||||||
}
|
}
|
||||||
} else if let Some(state) =
|
|
||||||
ground::grounded_movement_common_interrupts(state_context, &self.grounded_common)
|
|
||||||
{
|
|
||||||
Some(state)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use super::{FighterStateContext, FighterStateImpl, dash, ground, wait};
|
|||||||
use crate::fighter::animation::AnimKind;
|
use crate::fighter::animation::AnimKind;
|
||||||
use crate::fighter::state::FighterState;
|
use crate::fighter::state::FighterState;
|
||||||
use crate::fighter::state::fall::FallState;
|
use crate::fighter::state::fall::FallState;
|
||||||
|
use crate::fighter::state::turn;
|
||||||
use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon};
|
use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
@@ -16,7 +17,10 @@ pub struct WalkState {
|
|||||||
impl FighterStateImpl for WalkState {
|
impl FighterStateImpl for WalkState {
|
||||||
const NAME: &'static str = "Walk";
|
const NAME: &'static str = "Walk";
|
||||||
fn check_interrupt(&self, state_context: &mut FighterStateContext) -> Option<FighterState> {
|
fn check_interrupt(&self, state_context: &mut FighterStateContext) -> Option<FighterState> {
|
||||||
if let Some(state) =
|
if let Some(state) = turn::check_input(state_context, &self.grounded_common) {
|
||||||
|
return Some(state)
|
||||||
|
}
|
||||||
|
else if let Some(state) =
|
||||||
ground::grounded_movement_common_interrupts(state_context, &self.grounded_common)
|
ground::grounded_movement_common_interrupts(state_context, &self.grounded_common)
|
||||||
{
|
{
|
||||||
return Some(state);
|
return Some(state);
|
||||||
|
|||||||
+5
-1
@@ -94,6 +94,10 @@ impl FighterInput {
|
|||||||
pub fn reduce_command_lifetime(&mut self, command: FighterCommands) {
|
pub fn reduce_command_lifetime(&mut self, command: FighterCommands) {
|
||||||
self.command_lifetimes[command] = self.command_lifetimes[command].saturating_sub(1);
|
self.command_lifetimes[command] = self.command_lifetimes[command].saturating_sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_frames_in_smash_move_deadzone(&self) -> u8 {
|
||||||
|
self.frames_in_smash_move_deadzone
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns this frame's rolled-back inputs into per-fighter [`FighterInput`]
|
/// Turns this frame's rolled-back inputs into per-fighter [`FighterInput`]
|
||||||
@@ -124,7 +128,7 @@ pub fn postprocess_input(
|
|||||||
if prev_x_abs < reset_deadzone
|
if prev_x_abs < reset_deadzone
|
||||||
|| input.prev_frame.movement.x.signum() != input.current_frame.movement.x.signum()
|
|| input.prev_frame.movement.x.signum() != input.current_frame.movement.x.signum()
|
||||||
{
|
{
|
||||||
input.frames_in_smash_move_deadzone = 0;
|
input.frames_in_smash_move_deadzone = 1;
|
||||||
} else {
|
} else {
|
||||||
input.frames_in_smash_move_deadzone = input.frames_in_smash_move_deadzone.saturating_add(1);
|
input.frames_in_smash_move_deadzone = input.frames_in_smash_move_deadzone.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-19
@@ -2,37 +2,62 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use bevy_asset_loader::asset_collection::AssetCollection;
|
use bevy_asset_loader::asset_collection::AssetCollection;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum_macros::{EnumIter};
|
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, game_settings::GameSettings, math::{int::FGi32, vec::FGVec2}, stage::{StagePoly, line::{StageCollision, StagePolyLineSegmentType, StagePolyType}},
|
AppState,
|
||||||
|
game_settings::GameSettings,
|
||||||
|
math::{int::FGi32, vec::FGVec2},
|
||||||
|
stage::{
|
||||||
|
StagePoly,
|
||||||
|
line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
/// Per-stage presentation tuning for the standard match camera.
|
/// Per-stage presentation tuning for the standard match camera.
|
||||||
///
|
///
|
||||||
/// Values use gameplay world units on the XY plane
|
/// Spatial values use gameplay world units on the XY plane. Angle values use
|
||||||
|
/// degrees
|
||||||
#[derive(Component, Serialize, Deserialize, Clone, Reflect)]
|
#[derive(Component, Serialize, Deserialize, Clone, Reflect)]
|
||||||
#[reflect(opaque)]
|
#[reflect(opaque)]
|
||||||
pub struct StageCameraProfile {
|
pub struct StageCameraProfile {
|
||||||
|
/// World-space left edge of the camera range.
|
||||||
pub left: f32,
|
pub left: f32,
|
||||||
|
/// World-space right edge of the camera range.
|
||||||
pub right: f32,
|
pub right: f32,
|
||||||
|
/// World-space bottom edge of the camera range.
|
||||||
pub bottom: f32,
|
pub bottom: f32,
|
||||||
|
/// World-space top edge of the camera range.
|
||||||
pub top: f32,
|
pub top: f32,
|
||||||
|
/// Neutral focus point used for empty framing and dynamic pan calculations.
|
||||||
pub origin: Vec2,
|
pub origin: Vec2,
|
||||||
|
/// Vertical perspective field of view for the standard match camera.
|
||||||
pub vertical_fov_degrees: f32,
|
pub vertical_fov_degrees: f32,
|
||||||
|
/// Nearest allowed positive Z distance from the gameplay plane.
|
||||||
pub min_depth: f32,
|
pub min_depth: f32,
|
||||||
|
/// Farthest allowed positive Z distance from the gameplay plane.
|
||||||
pub max_depth: f32,
|
pub max_depth: f32,
|
||||||
|
/// Multiplies fighter camera extents after the player-count scale.
|
||||||
pub subject_scale: f32,
|
pub subject_scale: f32,
|
||||||
|
/// Multiplies the facing-forward horizontal fighter camera extent.
|
||||||
|
pub fighter_forward_extent_scale: f32,
|
||||||
|
/// Multiplies the standard camera's interest and eye follow speeds.
|
||||||
pub tracking_smoothness: f32,
|
pub tracking_smoothness: f32,
|
||||||
pub vertical_tilt_degrees: f32,
|
/// Constant vertical pitch added after dynamic vertical pan is clamped.
|
||||||
pub horizontal_pan_coefficient: f32,
|
pub vertical_pan_degrees: f32,
|
||||||
pub vertical_pan_coefficient: f32,
|
/// Dynamic horizontal pan in degrees for every world unit from 0,0
|
||||||
|
pub horizontal_pan_degrees_per_unit: f32,
|
||||||
|
/// Dynamic vertical pan in degrees for every world unit from the vertical reference line
|
||||||
|
pub vertical_pan_degrees_per_unit: f32,
|
||||||
|
/// Symmetric limit on dynamic horizontal pan, before any other adjustment.
|
||||||
pub max_horizontal_pan_degrees: f32,
|
pub max_horizontal_pan_degrees: f32,
|
||||||
|
/// Maximum upward dynamic vertical pan, before constant pitch is added.
|
||||||
pub max_upward_pan_degrees: f32,
|
pub max_upward_pan_degrees: f32,
|
||||||
|
/// Magnitude of the maximum downward dynamic vertical pan, before constant
|
||||||
|
/// pitch is added.
|
||||||
pub max_downward_pan_degrees: f32,
|
pub max_downward_pan_degrees: f32,
|
||||||
pub max_downward_expansion: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter)]
|
#[derive(Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter)]
|
||||||
@@ -101,7 +126,6 @@ fn fail(next_state: &mut NextState<AppState>, message: &str) {
|
|||||||
next_state.set(AppState::CommonAssetLoadFailed);
|
next_state.set(AppState::CommonAssetLoadFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn prepare_stage_manifests(
|
pub fn prepare_stage_manifests(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
handles: Res<StageManifestAssets>,
|
handles: Res<StageManifestAssets>,
|
||||||
@@ -154,13 +178,13 @@ pub fn prepare_stage_manifests(
|
|||||||
|
|
||||||
impl StageManifest {
|
impl StageManifest {
|
||||||
pub fn to_collision(&self) -> StageCollision {
|
pub fn to_collision(&self) -> StageCollision {
|
||||||
let stage_polys: Vec<StagePoly> = self.polygons.iter().map(|def| {
|
let stage_polys: Vec<StagePoly> = self
|
||||||
StagePoly::build(def.poly_type, &def.lines)
|
.polygons
|
||||||
}).collect();
|
.iter()
|
||||||
|
.map(|def| StagePoly::build(def.poly_type, &def.lines))
|
||||||
|
.collect();
|
||||||
|
|
||||||
StageCollision {
|
StageCollision { stage_polys }
|
||||||
stage_polys
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,24 +199,33 @@ impl StageCameraProfile {
|
|||||||
&& self.min_depth.is_finite()
|
&& self.min_depth.is_finite()
|
||||||
&& self.max_depth.is_finite()
|
&& self.max_depth.is_finite()
|
||||||
&& self.subject_scale.is_finite()
|
&& self.subject_scale.is_finite()
|
||||||
|
&& self.fighter_forward_extent_scale.is_finite()
|
||||||
&& self.tracking_smoothness.is_finite()
|
&& self.tracking_smoothness.is_finite()
|
||||||
&& self.vertical_tilt_degrees.is_finite()
|
&& self.vertical_pan_degrees.is_finite()
|
||||||
&& self.horizontal_pan_coefficient.is_finite()
|
&& self.horizontal_pan_degrees_per_unit.is_finite()
|
||||||
&& self.vertical_pan_coefficient.is_finite()
|
&& self.vertical_pan_degrees_per_unit.is_finite()
|
||||||
&& self.max_horizontal_pan_degrees.is_finite()
|
&& self.max_horizontal_pan_degrees.is_finite()
|
||||||
&& self.max_upward_pan_degrees.is_finite()
|
&& self.max_upward_pan_degrees.is_finite()
|
||||||
&& self.max_downward_pan_degrees.is_finite()
|
&& self.max_downward_pan_degrees.is_finite()
|
||||||
&& self.max_downward_expansion.is_finite()
|
|
||||||
&& self.left < self.right
|
&& self.left < self.right
|
||||||
&& self.bottom < self.top
|
&& self.bottom < self.top
|
||||||
|
&& (self.left..=self.right).contains(&self.origin.x)
|
||||||
|
&& (self.bottom..=self.top).contains(&self.origin.y)
|
||||||
&& (0.0..180.0).contains(&self.vertical_fov_degrees)
|
&& (0.0..180.0).contains(&self.vertical_fov_degrees)
|
||||||
&& self.min_depth > 0.0
|
&& self.min_depth > 0.0
|
||||||
&& self.min_depth <= self.max_depth
|
&& self.min_depth <= self.max_depth
|
||||||
&& self.subject_scale > 0.0
|
&& self.subject_scale > 0.0
|
||||||
|
&& self.fighter_forward_extent_scale > 0.0
|
||||||
&& self.tracking_smoothness >= 0.0
|
&& self.tracking_smoothness >= 0.0
|
||||||
&& self.max_horizontal_pan_degrees >= 0.0
|
&& self.max_horizontal_pan_degrees >= 0.0
|
||||||
&& self.max_upward_pan_degrees >= 0.0
|
&& self.max_upward_pan_degrees >= 0.0
|
||||||
&& self.max_downward_pan_degrees >= 0.0
|
&& self.max_downward_pan_degrees >= 0.0
|
||||||
&& self.max_downward_expansion >= 0.0
|
&& self.vertical_fov_degrees * 0.5 + self.max_horizontal_pan_degrees < 90.0
|
||||||
|
&& self.vertical_fov_degrees * 0.5
|
||||||
|
+ self.vertical_pan_degrees.abs()
|
||||||
|
+ self
|
||||||
|
.max_upward_pan_degrees
|
||||||
|
.max(self.max_downward_pan_degrees)
|
||||||
|
< 90.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user