Some other bullshit

This commit is contained in:
2026-09-12 14:55:40 +02:00
parent 74a635785e
commit 6e01147125
21 changed files with 206 additions and 89 deletions
-1
View File
@@ -49,7 +49,6 @@ pub fn apply_animation(
>, >,
) { ) {
for (mut trf, facing_direction, frame) in children { for (mut trf, facing_direction, frame) in children {
// 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( trf.rotate_local_y(
+18 -2
View File
@@ -149,14 +149,16 @@ pub fn fighter_debug(
pub fn animation_debug(query: Query<(&GlobalTransform, &FighterBoneMatrices)>, mut gizmos: Gizmos) { pub fn animation_debug(query: Query<(&GlobalTransform, &FighterBoneMatrices)>, mut gizmos: Gizmos) {
for (global_transform, matrices) in query { for (global_transform, matrices) in query {
let (_, rotation, translation) = global_transform.to_scale_rotation_translation();
let marker_transform = Transform::from_translation(translation).with_rotation(rotation);
for (_, matrix) in matrices.iter() { for (_, matrix) in matrices.iter() {
let pos = global_transform.transform_point(Vec3::new( let pos = marker_transform.transform_point(Vec3::new(
matrix.cols[3][0].to_num(), matrix.cols[3][0].to_num(),
matrix.cols[3][1].to_num(), matrix.cols[3][1].to_num(),
matrix.cols[3][2].to_num(), matrix.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);
gizmos.axes(*global_transform, 1.0); gizmos.axes(marker_transform, 1.0);
} }
} }
} }
@@ -290,6 +292,20 @@ fn capsule_wireframe() -> &'static CapsuleWireframe {
mod capsule_debug_tests { mod capsule_debug_tests {
use super::*; use super::*;
#[test]
fn animation_markers_ignore_visual_scale() {
let global = GlobalTransform::from(Transform {
translation: Vec3::new(3.0, 4.0, 5.0),
rotation: Quat::from_rotation_y(std::f32::consts::FRAC_PI_2),
scale: Vec3::splat(10.0),
});
let (_, rotation, translation) = global.to_scale_rotation_translation();
let marker_transform = Transform::from_translation(translation).with_rotation(rotation);
let marker = marker_transform.transform_point(Vec3::new(2.0, 0.0, 0.0));
assert!(marker.abs_diff_eq(Vec3::new(3.0, 4.0, 3.0), 1e-5));
}
#[test] #[test]
fn capsule_wireframe_caps_extend_in_opposite_directions() { fn capsule_wireframe_caps_extend_in_opposite_directions() {
let wireframe = capsule_wireframe(); let wireframe = capsule_wireframe();
+18 -6
View File
@@ -1,9 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use bevy::{ use bevy::{asset::UntypedHandle, prelude::*};
asset::UntypedHandle,
prelude::*,
};
use bevy_asset_loader::asset_collection::AssetCollection; use bevy_asset_loader::asset_collection::AssetCollection;
use ron_asset_manager::prelude::RonAsset; use ron_asset_manager::prelude::RonAsset;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -11,10 +8,16 @@ 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, math::{int::FGi32, vec3::FGVec3}, texture_reference::TextureReference, AppState,
fighter::{FighterAttributes, FighterCameraProfile, animation::AnimKind, attack::AttackKind},
game_settings::GameSettings,
math::{int::FGi32, vec3::FGVec3},
texture_reference::TextureReference,
}; };
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, EnumIter, Default)] #[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, EnumIter, Default,
)]
pub enum FighterId { pub enum FighterId {
#[default] #[default]
TestFighter, TestFighter,
@@ -35,6 +38,8 @@ pub struct FighterHurtbox {
pub struct FighterManifest { pub struct FighterManifest {
pub id: FighterId, pub id: FighterId,
pub model_path: String, pub model_path: String,
#[reflect(ignore)]
pub model_scale: FGi32,
pub baked_animation_path: String, pub baked_animation_path: String,
#[asset] #[asset]
#[dependency] #[dependency]
@@ -108,6 +113,13 @@ pub fn prepare_fighter_manifests(
); );
return; return;
} }
if manifest.model_scale <= FGi32::ZERO {
fail(
&mut next_state,
&format!("{:?} has a non-positive model scale", manifest.id),
);
return;
}
if manifest.baked_animation_path.is_empty() { if manifest.baked_animation_path.is_empty() {
fail( fail(
&mut next_state, &mut next_state,
+8 -4
View File
@@ -22,12 +22,15 @@
//! appears in `Add Component`. No registration code is needed. //! appears in `Add Component`. No registration code is needed.
use bevy::{ use bevy::{
asset::processor::{AssetProcessor, ProcessorState}, prelude::*, settings::SettingsPlugin, tasks::block_on, asset::processor::{AssetProcessor, ProcessorState},
prelude::*,
settings::SettingsPlugin,
tasks::block_on,
}; };
use bevy_asset_loader::prelude::*; use bevy_asset_loader::prelude::*;
use ron_asset_manager::RonAssetPlugin;
use bevy_wind_waker_shader::prelude::*; use bevy_wind_waker_shader::prelude::*;
use clap::Parser; use clap::Parser;
use ron_asset_manager::RonAssetPlugin;
use crate::{ use crate::{
camera::MatchCameraPlugin, fighter::manifest::FighterManifest, game_settings::GameSettings, camera::MatchCameraPlugin, fighter::manifest::FighterManifest, game_settings::GameSettings,
@@ -42,13 +45,13 @@ pub mod game_settings;
pub mod input; pub mod input;
pub mod match_loading; pub mod match_loading;
mod math; mod math;
pub mod menus;
pub mod netcode; pub mod netcode;
pub mod player; pub mod player;
pub mod replay; pub mod replay;
pub mod schedule; pub mod schedule;
pub mod scripting; pub mod scripting;
pub mod stage; pub mod stage;
pub mod menus;
pub mod texture_reference; pub mod texture_reference;
#[derive(States, Debug, Clone, Copy, Eq, PartialEq, Hash, Default)] #[derive(States, Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
@@ -61,6 +64,7 @@ pub enum AppState {
LoadStageManifests, LoadStageManifests,
PrepareStageManifests, PrepareStageManifests,
CommonAssetLoadFailed, CommonAssetLoadFailed,
PreMainMenu,
MainMenu, MainMenu,
CharacterSelect, CharacterSelect,
StageSelect, StageSelect,
@@ -139,7 +143,7 @@ impl Plugin for GamePlugin {
stage::manifest::prepare_stage_manifests, stage::manifest::prepare_stage_manifests,
) )
.add_systems( .add_systems(
OnEnter(AppState::MainMenu), OnEnter(AppState::PreMainMenu),
match_loading::initiate_default_match, match_loading::initiate_default_match,
) )
.add_systems( .add_systems(
+9 -5
View File
@@ -169,9 +169,6 @@ pub fn initiate_default_match(
} }
return; return;
} }
if !args.synctest {
return;
}
let players = (0..args.players) let players = (0..args.players)
.map(|handle| MatchPlayer { .map(|handle| MatchPlayer {
handle, handle,
@@ -270,7 +267,13 @@ pub fn prepare_match(
scripts: character.attack_scripts.clone(), scripts: character.attack_scripts.clone(),
}; };
prepared.push((scene, animations, attack_scripts, manifest_handle)); prepared.push((
scene,
animations,
attack_scripts,
manifest_handle,
manifest.model_scale,
));
} }
let session = match create_session(&args, request.players.len()) { let session = match create_session(&args, request.players.len()) {
@@ -300,7 +303,7 @@ pub fn prepare_match(
stage_manifest.camera.clone(), stage_manifest.camera.clone(),
); );
for (index, (player, (scene, animations, attack_scripts, manifest_handle))) in for (index, (player, (scene, animations, attack_scripts, manifest_handle, model_scale))) in
request.players.iter().zip(prepared).enumerate() request.players.iter().zip(prepared).enumerate()
{ {
let spawn_x = (index as i32 * 2 + 1 - request.players.len() as i32) * 5; let spawn_x = (index as i32 * 2 + 1 - request.players.len() as i32) * 5;
@@ -309,6 +312,7 @@ pub fn prepare_match(
player.handle, player.handle,
FGVec2::new(FGi32::from_num(spawn_x), FGi32::lit("12.5")), FGVec2::new(FGi32::from_num(spawn_x), FGi32::lit("12.5")),
manifest_handle.clone(), manifest_handle.clone(),
model_scale,
animations, animations,
attack_scripts, attack_scripts,
WorldAssetRoot(scene), WorldAssetRoot(scene),
+3 -2
View File
@@ -1,13 +1,14 @@
use bevy::{picking::Pickable, prelude::*, text::FontSourceTemplate, ui::widget::ImageNodeSize}; use bevy::{picking::Pickable, prelude::*, text::FontSourceTemplate, ui::widget::ImageNodeSize};
use crate::{ use crate::{
fighter::{FighterId, manifest::FighterManifest}, menus::{button::FGUiButton, style::FGUiButtonType}, fighter::{FighterId, manifest::FighterManifest},
menus::{button::FGUiButton, style::FGUiButtonType},
}; };
#[derive(Component, Clone, FromTemplate)] #[derive(Component, Clone, FromTemplate)]
pub struct CharacterBox { pub struct CharacterBox {
pub fighter_manifest: Handle<FighterManifest>, pub fighter_manifest: Handle<FighterManifest>,
pub fighter_id: FighterId pub fighter_id: FighterId,
} }
impl CharacterBox { impl CharacterBox {
+1 -3
View File
@@ -1,3 +1 @@
pub enum CharacterSelectErrors { pub enum CharacterSelectErrors {}
}
+20 -6
View File
@@ -5,8 +5,20 @@ use bevy::{
use bevy_egui::egui::accesskit::TextAlign; use bevy_egui::egui::accesskit::TextAlign;
use crate::{ use crate::{
AppState, fighter::manifest::{FighterManifest, FighterManifestRegistry}, game_settings::CommonAssets, input::{LocalInputAssignments, LocalInputSource}, menus::{ AppState,
MenuMarker, build_menu_with_props, button::FGUiButton, character_select::{character_box::CharacterBox, token::CharacterSelectToken}, cursor::{FGMenuCursor, MenuCursorInputSource}, errors::MenuErrors::{self, FighterManifestNotFound}, match_config::{MenuMatchConfig, MenuMatchPlayerSlot}, scaling, spawn_menu, style::{FGUiButtonType, FGUiStyle}, wrap_menu, fighter::manifest::{FighterManifest, FighterManifestRegistry},
game_settings::CommonAssets,
input::{LocalInputAssignments, LocalInputSource},
menus::{
MenuMarker, build_menu_with_props,
button::FGUiButton,
character_select::{character_box::CharacterBox, token::CharacterSelectToken},
cursor::{FGMenuCursor, MenuCursorInputSource},
errors::MenuErrors::{self, FighterManifestNotFound},
match_config::{MenuMatchConfig, MenuMatchPlayerSlot},
scaling, spawn_menu,
style::{FGUiButtonType, FGUiStyle},
wrap_menu,
}, },
}; };
@@ -142,7 +154,6 @@ pub fn handle_fighter_slot_addition(
common_assets: Res<CommonAssets>, common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>, styles: Res<Assets<FGUiStyle>>,
) { ) {
for addition in addition.read() { for addition in addition.read() {
let slot = addition.slot; let slot = addition.slot;
create_portrait( create_portrait(
@@ -155,7 +166,6 @@ pub fn handle_fighter_slot_addition(
&addition.input_source, &addition.input_source,
); );
} }
} }
pub fn css_auto_assign_slots( pub fn css_auto_assign_slots(
@@ -220,7 +230,11 @@ pub fn update_start_banner_visibility(
config: Res<MenuMatchConfig>, config: Res<MenuMatchConfig>,
) { ) {
let match_ready = config.all_players_ready(); let match_ready = config.all_players_ready();
commands.entity(banner.into_inner()).insert(if match_ready {Visibility::Visible} else {Visibility::Hidden}); commands.entity(banner.into_inner()).insert(if match_ready {
Visibility::Visible
} else {
Visibility::Hidden
});
} }
pub fn copy_cursor_transform_to_token( pub fn copy_cursor_transform_to_token(
@@ -269,4 +283,4 @@ pub fn despawn_tokens(tokens: Query<Entity, With<CharacterSelectToken>>, mut com
for token in tokens { for token in tokens {
commands.entity(token).despawn(); commands.entity(token).despawn();
} }
} }
+9 -8
View File
@@ -7,16 +7,13 @@ use crate::menus::style::FGUiStyle;
#[derive(Component, Clone)] #[derive(Component, Clone)]
pub struct CharacterSelectToken { pub struct CharacterSelectToken {
pub slot: usize, pub slot: usize,
pub cursor: Entity pub cursor: Entity,
} }
impl CharacterSelectToken { impl CharacterSelectToken {
pub fn create(cursor: Entity, slot: usize, style: &FGUiStyle) -> impl Bundle { pub fn create(cursor: Entity, slot: usize, style: &FGUiStyle) -> impl Bundle {
( (
CharacterSelectToken { CharacterSelectToken { slot, cursor },
slot,
cursor
},
Pickable::IGNORE, Pickable::IGNORE,
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -26,9 +23,13 @@ impl CharacterSelectToken {
}, },
ImageNode { ImageNode {
image: style.css_token.handle.handle.clone(), image: style.css_token.handle.handle.clone(),
color: style.player_colors.get(slot).copied().unwrap_or(Color::WHITE), color: style
.player_colors
.get(slot)
.copied()
.unwrap_or(Color::WHITE),
..default() ..default()
} },
) )
} }
} }
+28 -17
View File
@@ -9,7 +9,12 @@ use bevy::{
}; };
use crate::{ use crate::{
input::{LocalInputAssignments, LocalInputSource}, menus::{input::{MenuInput, MenuInputState}, scaling, style::FGUiStyle}, input::{LocalInputAssignments, LocalInputSource},
menus::{
input::{MenuInput, MenuInputState},
scaling,
style::FGUiStyle,
},
}; };
#[derive(Default)] #[derive(Default)]
@@ -30,7 +35,7 @@ impl FGMenuCursor {
pub fn create_cursor( pub fn create_cursor(
input_source: MenuCursorInputSource, input_source: MenuCursorInputSource,
style: &FGUiStyle, style: &FGUiStyle,
pointer_id: PointerId pointer_id: PointerId,
) -> impl Bundle { ) -> impl Bundle {
let circle_icon = style.cursor.handle().clone(); let circle_icon = style.cursor.handle().clone();
( (
@@ -57,22 +62,22 @@ impl FGMenuCursor {
) )
} }
pub fn create_shared_cursor(style: &FGUiStyle) -> impl Bundle { pub fn create_shared_cursor(style: &FGUiStyle) -> impl Bundle {
Self::create_cursor( Self::create_cursor(MenuCursorInputSource::Any, style, PointerId::Mouse)
MenuCursorInputSource::Any,
style,
PointerId::Mouse
)
} }
pub fn create_player_cursor( pub fn create_player_cursor(
player_slot: usize, player_slot: usize,
style: &FGUiStyle, style: &FGUiStyle,
input_source: &LocalInputSource, input_source: &LocalInputSource,
) -> impl Bundle { ) -> impl Bundle {
let pointer_id = if matches!(input_source, LocalInputSource::Keyboard) {PointerId::Mouse} else {PointerId::Custom(Uuid::new_v4())}; let pointer_id = if matches!(input_source, LocalInputSource::Keyboard) {
PointerId::Mouse
} else {
PointerId::Custom(Uuid::new_v4())
};
Self::create_cursor( Self::create_cursor(
MenuCursorInputSource::Player(player_slot), MenuCursorInputSource::Player(player_slot),
style, style,
pointer_id pointer_id,
) )
} }
} }
@@ -81,19 +86,17 @@ impl FGMenuCursor {
pub fn copy_mouse_input( pub fn copy_mouse_input(
mut query: Query<(&FGMenuCursor, &mut PointerLocation, &PointerId)>, mut query: Query<(&FGMenuCursor, &mut PointerLocation, &PointerId)>,
assignments: Res<LocalInputAssignments>, assignments: Res<LocalInputAssignments>,
mut input_events: MessageReader<Pointer<Move>> mut input_events: MessageReader<Pointer<Move>>,
) { ) {
for event in input_events.read() { for event in input_events.read() {
if let PointerId::Mouse = event.pointer_id { if let PointerId::Mouse = event.pointer_id {
for (cursor, mut location, _) in query.iter_mut() { for (cursor, mut location, _) in query.iter_mut() {
let is_mouse = match cursor.input_source { let is_mouse = match cursor.input_source {
MenuCursorInputSource::Any => true, MenuCursorInputSource::Any => true,
MenuCursorInputSource::Player(slot) => { MenuCursorInputSource::Player(slot) => assignments
assignments.get(slot).map(|(_, source)| { .get(slot)
matches!(source, LocalInputSource::Keyboard) .map(|(_, source)| matches!(source, LocalInputSource::Keyboard))
}).unwrap_or_default() .unwrap_or_default(),
},
}; };
if is_mouse { if is_mouse {
@@ -185,7 +188,15 @@ pub fn update_cursor_transform(
let camera = camera.into_inner(); let camera = camera.into_inner();
for (mut node, location) in query { for (mut node, location) in query {
let ui_pos = scaling::logical_to_ui_position(location.location.as_ref().map(|d| d.position).unwrap_or_default(), camera, &ui_scale); let ui_pos = scaling::logical_to_ui_position(
location
.location
.as_ref()
.map(|d| d.position)
.unwrap_or_default(),
camera,
&ui_scale,
);
node.left = px(ui_pos.x); node.left = px(ui_pos.x);
node.top = px(ui_pos.y); node.top = px(ui_pos.y);
} }
+1 -1
View File
@@ -8,4 +8,4 @@ pub enum MenuErrors {
FighterManifestNotFound, FighterManifestNotFound,
#[error("Match config error: {0:?}")] #[error("Match config error: {0:?}")]
MatchConfigError(#[from] MenuMatchConfigErrors), MatchConfigError(#[from] MenuMatchConfigErrors),
} }
+13 -6
View File
@@ -91,10 +91,14 @@ impl MenuInput {
self.accept.accumulate(&other.accept); self.accept.accumulate(&other.accept);
self.back.accumulate(&other.back); self.back.accumulate(&other.back);
self.start.accumulate(&other.start); self.start.accumulate(&other.start);
self.movement_digital_up.accumulate(&other.movement_digital_up); self.movement_digital_up
self.movement_digital_down.accumulate(&other.movement_digital_down); .accumulate(&other.movement_digital_up);
self.movement_digital_left.accumulate(&other.movement_digital_left); self.movement_digital_down
self.movement_digital_right.accumulate(&other.movement_digital_right); .accumulate(&other.movement_digital_down);
self.movement_digital_left
.accumulate(&other.movement_digital_left);
self.movement_digital_right
.accumulate(&other.movement_digital_right);
self.movement = self.movement.clamp_length_max(1.0); self.movement = self.movement.clamp_length_max(1.0);
} }
} }
@@ -247,9 +251,12 @@ pub fn sample_menu_inputs(
state state
.inputs .inputs
.push((LocalInputSource::Keyboard, keyboard_input(&key, &map))); .push((LocalInputSource::Keyboard, keyboard_input(&key, &map)));
let mut prev_joystick_states: Vec<(LocalInputSource, MenuJoystickState)> = vec![]; let mut prev_joystick_states: Vec<(LocalInputSource, MenuJoystickState)> = vec![];
std::mem::swap(&mut prev_joystick_states, &mut state.prev_frame_joystick_state); std::mem::swap(
&mut prev_joystick_states,
&mut state.prev_frame_joystick_state,
);
for (entity, pad) in pads.iter() { for (entity, pad) in pads.iter() {
let local_source = LocalInputSource::Gamepad(entity); let local_source = LocalInputSource::Gamepad(entity);
+5 -5
View File
@@ -190,7 +190,10 @@ impl Plugin for MenuPlugin {
) )
.add_systems( .add_systems(
PreUpdate, PreUpdate,
(character_select::css_auto_assign_slots, character_select::handle_fighter_slot_addition) (
character_select::css_auto_assign_slots,
character_select::handle_fighter_slot_addition,
)
.chain() .chain()
.run_if(in_state(AppState::CharacterSelect)) .run_if(in_state(AppState::CharacterSelect))
.run_if(any_with_component::<CharacterSelectScreen>), .run_if(any_with_component::<CharacterSelectScreen>),
@@ -214,14 +217,11 @@ impl Plugin for MenuPlugin {
OnEnter(AppState::StageSelect), OnEnter(AppState::StageSelect),
stage_select::setup_stage_select, stage_select::setup_stage_select,
) )
.add_observer(stage_select::stage_selected.run_if(in_state(AppState::StageSelect)), .add_observer(stage_select::stage_selected.run_if(in_state(AppState::StageSelect)))
)
.add_systems( .add_systems(
OnExit(AppState::StageSelect), OnExit(AppState::StageSelect),
(cursor::despawn_cursors, despawn_menu), (cursor::despawn_cursors, despawn_menu),
) )
//--------- //---------
// STAGE SELECT END // STAGE SELECT END
//--------- //---------
+26 -6
View File
@@ -48,7 +48,7 @@ pub fn process_inputs(
action_state.pressed_actions.clear(); action_state.pressed_actions.clear();
let input = menu_inputs.aggregate(); let input = menu_inputs.aggregate();
let has_direction = input.movement.length() != 0.0; let has_direction = input.movement.length() != 0.0;
let mut dir_distances = [ let mut dir_distances = [
(input.movement_digital_up, input.movement.dot(Vec2::Y)), (input.movement_digital_up, input.movement.dot(Vec2::Y)),
(input.movement_digital_down, input.movement.dot(Vec2::NEG_Y)), (input.movement_digital_down, input.movement.dot(Vec2::NEG_Y)),
@@ -82,12 +82,32 @@ pub fn process_inputs(
false false
}; };
if curr_dir.is_just_pressed() || repeat_press { if curr_dir.is_just_pressed() || repeat_press {
if input.movement.y > 0.0 { action_state.pressed_actions.insert(DirectionalNavigationAction::Up); } if input.movement.y > 0.0 {
if input.movement.y < 0.0 { action_state.pressed_actions.insert(DirectionalNavigationAction::Down); } action_state
if input.movement.x < 0.0 { action_state.pressed_actions.insert(DirectionalNavigationAction::Left); } .pressed_actions
if input.movement.x > 0.0 { action_state.pressed_actions.insert(DirectionalNavigationAction::Right); } .insert(DirectionalNavigationAction::Up);
}
if input.movement.y < 0.0 {
action_state
.pressed_actions
.insert(DirectionalNavigationAction::Down);
}
if input.movement.x < 0.0 {
action_state
.pressed_actions
.insert(DirectionalNavigationAction::Left);
}
if input.movement.x > 0.0 {
action_state
.pressed_actions
.insert(DirectionalNavigationAction::Right);
}
}
if input.accept.is_pressed() {
action_state
.pressed_actions
.insert(DirectionalNavigationAction::Select);
} }
if input.accept.is_pressed() { action_state.pressed_actions.insert(DirectionalNavigationAction::Select); }
} }
const FOCUSED_BORDER: Srgba = bevy::color::palettes::tailwind::BLUE_50; const FOCUSED_BORDER: Srgba = bevy::color::palettes::tailwind::BLUE_50;
+10 -3
View File
@@ -30,8 +30,15 @@ pub fn ui_scaling_system(
} }
} }
pub fn world_to_ui_position(pos: Vec2, camera: &Camera, camera_transform: &GlobalTransform, ui_scale: &UiScale) -> Vec2 { pub fn world_to_ui_position(
let viewport_position = camera.world_to_viewport(camera_transform, Vec3::new(pos.x, pos.y, 0.0)).unwrap(); pos: Vec2,
camera: &Camera,
camera_transform: &GlobalTransform,
ui_scale: &UiScale,
) -> Vec2 {
let viewport_position = camera
.world_to_viewport(camera_transform, Vec3::new(pos.x, pos.y, 0.0))
.unwrap();
let viewport_rect = camera.logical_viewport_rect().unwrap(); let viewport_rect = camera.logical_viewport_rect().unwrap();
@@ -46,4 +53,4 @@ pub fn logical_to_ui_position(pos: Vec2, camera: &Camera, ui_scale: &UiScale) ->
let ui_position = (pos - viewport_rect.min) / ui_scale.0; let ui_position = (pos - viewport_rect.min) / ui_scale.0;
ui_position ui_position
} }
+19 -5
View File
@@ -1,9 +1,19 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::{ use crate::{
AppState, game_settings::CommonAssets, match_loading::initiate_match, menus::{ AppState,
MenuMarker, button::FGUiButton, cursor, match_config::MenuMatchConfig, spawn_menu, stage_select::stage_box::StageBox, style::{FGUiButtonType, FGUiStyle}, game_settings::CommonAssets,
}, stage::manifest::{StageManifest, StageManifestRegistry}, match_loading::initiate_match,
menus::{
MenuMarker,
button::FGUiButton,
cursor,
match_config::MenuMatchConfig,
spawn_menu,
stage_select::stage_box::StageBox,
style::{FGUiButtonType, FGUiStyle},
},
stage::manifest::{StageManifest, StageManifestRegistry},
}; };
pub mod stage_box; pub mod stage_box;
@@ -64,12 +74,16 @@ pub fn stage_selected(
query: Query<&StageBox>, query: Query<&StageBox>,
mut commands: Commands, mut commands: Commands,
mut next_state: ResMut<NextState<AppState>>, mut next_state: ResMut<NextState<AppState>>,
mut match_config: ResMut<MenuMatchConfig> mut match_config: ResMut<MenuMatchConfig>,
) -> Result { ) -> Result {
let stage_box = query.get(ev.event_target()); let stage_box = query.get(ev.event_target());
if let Ok(stage_box) = stage_box { if let Ok(stage_box) = stage_box {
match_config.stage = Some(stage_box.stage_id); match_config.stage = Some(stage_box.stage_id);
initiate_match(&mut commands, &mut next_state, match_config.to_pending_match()?); initiate_match(
&mut commands,
&mut next_state,
match_config.to_pending_match()?,
);
} }
Ok(()) Ok(())
} }
+4 -2
View File
@@ -1,13 +1,15 @@
use bevy::{picking::Pickable, prelude::*, text::FontSourceTemplate, ui::widget::ImageNodeSize}; use bevy::{picking::Pickable, prelude::*, text::FontSourceTemplate, ui::widget::ImageNodeSize};
use crate::{ use crate::{
fighter::{FighterId, manifest::FighterManifest}, menus::{button::FGUiButton, style::FGUiButtonType}, stage::manifest::{StageId, StageManifest}, fighter::{FighterId, manifest::FighterManifest},
menus::{button::FGUiButton, style::FGUiButtonType},
stage::manifest::{StageId, StageManifest},
}; };
#[derive(Component, Clone, FromTemplate)] #[derive(Component, Clone, FromTemplate)]
pub struct StageBox { pub struct StageBox {
pub stage_manifest: Handle<StageManifest>, pub stage_manifest: Handle<StageManifest>,
pub stage_id: StageId pub stage_id: StageId,
} }
impl StageBox { impl StageBox {
+1 -1
View File
@@ -1,8 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use bevy::prelude::*; use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use ron_asset_manager::prelude::*; use ron_asset_manager::prelude::*;
use serde::{Deserialize, Serialize};
use crate::texture_reference::TextureReference; use crate::texture_reference::TextureReference;
+1 -1
View File
@@ -346,7 +346,7 @@ fn finish_playback(
commands.remove_resource::<ReplayRuntime>(); commands.remove_resource::<ReplayRuntime>();
commands.remove_resource::<LoadedReplay>(); commands.remove_resource::<LoadedReplay>();
commands.insert_resource(ReplayComplete); commands.insert_resource(ReplayComplete);
next_state.set(AppState::MainMenu); next_state.set(AppState::PreMainMenu);
} }
} }
+2 -1
View File
@@ -19,9 +19,10 @@ pub enum GameplaySet {
StateUpdate, StateUpdate,
/// Integrate velocities into positions. /// Integrate velocities into positions.
Physics, Physics,
/// Solve collision boxes
Animation,
/// Resolve the integrated positions against the stage. /// Resolve the integrated positions against the stage.
Collision, Collision,
Animation,
} }
/// Declares the order of [`GameplaySet`] inside [`GgrsSchedule`]. Added by /// Declares the order of [`GameplaySet`] inside [`GgrsSchedule`]. Added by
+10 -4
View File
@@ -7,10 +7,14 @@ use strum::IntoEnumIterator;
use strum_macros::EnumIter; use strum_macros::EnumIter;
use crate::{ use crate::{
AppState, game_settings::GameSettings, math::vec::FGVec2, stage::{ AppState,
game_settings::GameSettings,
math::vec::FGVec2,
stage::{
StagePoly, StagePoly,
line::{StageCollision, StagePolyLineSegmentType, StagePolyType}, line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
}, texture_reference::TextureReference, },
texture_reference::TextureReference,
}; };
use bevy::prelude::*; use bevy::prelude::*;
@@ -58,7 +62,9 @@ pub struct StageCameraProfile {
pub max_downward_pan_degrees: f32, pub max_downward_pan_degrees: f32,
} }
#[derive(Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter, Default)] #[derive(
Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter, Default,
)]
pub enum StageId { pub enum StageId {
#[default] #[default]
TestStage, TestStage,
@@ -176,7 +182,7 @@ pub fn prepare_stage_manifests(
} }
commands.insert_resource(StageManifestRegistry(registry)); commands.insert_resource(StageManifestRegistry(registry));
next_state.set(AppState::MainMenu); next_state.set(AppState::PreMainMenu);
} }
impl StageManifest { impl StageManifest {