Modular animation system, spawnpoints, weapons, equipment events.
This commit is contained in:
parent
57587d1586
commit
af2e23b275
|
@ -2,8 +2,8 @@ use bevy::prelude::{Component, Quat, Vec3};
|
||||||
|
|
||||||
use crate::logic::core::guns::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
use crate::logic::core::guns::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Clone)]
|
||||||
pub struct FirearmData<'a> {
|
pub struct FirearmData {
|
||||||
/// Where the bullets will come out of, and muzzle flash will be spawned out of.
|
/// Where the bullets will come out of, and muzzle flash will be spawned out of.
|
||||||
pub firing_point: Vec3,
|
pub firing_point: Vec3,
|
||||||
pub caliber: Caliber,
|
pub caliber: Caliber,
|
||||||
|
@ -14,9 +14,8 @@ pub struct FirearmData<'a> {
|
||||||
/// Amount of seconds it takes for gun to come down from shooting
|
/// Amount of seconds it takes for gun to come down from shooting
|
||||||
/// Also is the time it takes for the gun to aim in or aim out.
|
/// Also is the time it takes for the gun to aim in or aim out.
|
||||||
pub rebound_time_seconds: f32,
|
pub rebound_time_seconds: f32,
|
||||||
pub asset_path: &'a str,
|
|
||||||
|
|
||||||
pub identifier: String,
|
pub asset_path: String,
|
||||||
|
|
||||||
pub vertical_recoil_modifier: f32,
|
pub vertical_recoil_modifier: f32,
|
||||||
pub horizontal_recoil_modifier: f32,
|
pub horizontal_recoil_modifier: f32,
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
use bevy::prelude::Component;
|
use bevy::prelude::Component;
|
||||||
|
|
||||||
|
use crate::setup::equipment::Equipment;
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct PlayerData {
|
||||||
|
pub equipment: Equipment,
|
||||||
|
}
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Player;
|
pub struct Player(pub PlayerData);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct PlayerHand;
|
pub struct PlayerHand;
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::logic::core::guns::firearm::Firearm;
|
|
||||||
|
|
||||||
pub const MAX_LINEAR_PLAYER_VELOCITY: f32 = 20.0;
|
pub const MAX_LINEAR_PLAYER_VELOCITY: f32 = 20.0;
|
||||||
pub const PLAYER_ACCELERATION: f32 = 20.0;
|
pub const PLAYER_ACCELERATION: f32 = 20.0;
|
||||||
pub const PLAYER_JUMP_FORCE: f32 = 900.0;
|
pub const PLAYER_JUMP_FORCE: f32 = 900.0;
|
||||||
|
@ -25,5 +23,3 @@ pub const PLAYER_LATERAL_ACCELERATION_WHILE_SPRINTING_MULTIPLIER: f32 = 0.2;
|
||||||
pub const PLAYER_LATERAL_ACCELERATION_MULTIPLIER: f32 = 1.0;
|
pub const PLAYER_LATERAL_ACCELERATION_MULTIPLIER: f32 = 1.0;
|
||||||
|
|
||||||
pub const PLAYER_LINEAR_DAMPING_TIME_OFFSET_AFTER_JUMP_IN_MS: u128 = 20;
|
pub const PLAYER_LINEAR_DAMPING_TIME_OFFSET_AFTER_JUMP_IN_MS: u128 = 20;
|
||||||
|
|
||||||
pub const DEFAULT_PLAYER_FIREARM: Firearm = Firearm::M4A1;
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Caliber {
|
pub enum Caliber {
|
||||||
NATO556,
|
NATO556,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[derive(Event)]
|
||||||
|
pub struct SpawnFirearmEvent();
|
||||||
/// System that checks if player
|
|
||||||
pub fn equip_firearm() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -26,7 +26,6 @@ impl Firearm {
|
||||||
1.0, 1.2, 1.3, -1.6, 1.5, -1.7, -1.5, 1.5, -1.5, 2.0 // 10 for now
|
1.0, 1.2, 1.3, -1.6, 1.5, -1.7, -1.5, 1.5, -1.5, 2.0 // 10 for now
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
asset_path: "weapons/m4a1_rifle.glb",
|
|
||||||
|
|
||||||
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
||||||
final_rotation: Quat::default(),
|
final_rotation: Quat::default(),
|
||||||
|
@ -43,8 +42,7 @@ impl Firearm {
|
||||||
y: -0.45,
|
y: -0.45,
|
||||||
z: -2.7,
|
z: -2.7,
|
||||||
},
|
},
|
||||||
identifier: String::from("m4a1_rifle"),
|
asset_path: String::from("weapons/m4a1_rifle.glb"),
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn holdable_object_data(&self) -> HoldableObjectData {
|
pub fn holdable_object_data(&self) -> HoldableObjectData {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
pub mod caliber;
|
pub mod caliber;
|
||||||
pub mod firearm;
|
pub mod firearm;
|
||||||
pub mod player_firing;
|
pub mod player_firing;
|
||||||
pub mod spawn_firearm;
|
|
||||||
pub mod spray_pattern;
|
pub mod spray_pattern;
|
||||||
pub mod equip_firearm;
|
pub mod equip_firearm;
|
|
@ -2,8 +2,8 @@ use std::time::Duration;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Resource, Reflect)]
|
#[derive(Component, Reflect)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Component)]
|
||||||
pub struct PlayerFiringInfo {
|
pub struct PlayerFiringInfo {
|
||||||
/// Timestamp since last round fired from the gun. (seconds)
|
/// Timestamp since last round fired from the gun. (seconds)
|
||||||
pub last_shot_timestamp: f32,
|
pub last_shot_timestamp: f32,
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use bevy::{prelude::*, gltf::Gltf};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
comps::core::markers::{holdable::InPlayerHands, player::PlayerHand, firearm::{MagazineData, FirearmData}},
|
|
||||||
constants::player_values::DEFAULT_PLAYER_FIREARM,
|
|
||||||
utils, setup::{animations::FirearmAnimations, assets::{GltfAssets, GltfAssetType}},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{player_firing::PlayerFiringInfo, firearm::Firearm};
|
|
||||||
|
|
||||||
pub fn spawn_firearm_on_player_hands(
|
|
||||||
mut commands: Commands,
|
|
||||||
query: Query<Entity, With<PlayerHand>>,
|
|
||||||
mut player_firing_info: ResMut<PlayerFiringInfo>,
|
|
||||||
assets_gltf: Res<GltfAssets>,
|
|
||||||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
|
||||||
) {
|
|
||||||
if let Some(asset_handle) = assets_gltf.assets.iter().find(|asset| asset.asset_type == GltfAssetType::Firearm(Firearm::M4A1)) {
|
|
||||||
if let Some(gltf) = loaded_gltf_assets.get(&asset_handle.asset) {
|
|
||||||
for entity in query.iter() {
|
|
||||||
let mut firearm_transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
|
||||||
firearm_transform.rotate_y(utils::rad_deg::radians_from_degrees(
|
|
||||||
DEFAULT_PLAYER_FIREARM.holdable_object_data().y_rot,
|
|
||||||
));
|
|
||||||
|
|
||||||
let scene = gltf.scenes[0].clone();
|
|
||||||
|
|
||||||
let firearm = commands
|
|
||||||
.spawn((
|
|
||||||
SceneBundle {
|
|
||||||
scene,
|
|
||||||
visibility: Visibility::Inherited,
|
|
||||||
transform: firearm_transform,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
DEFAULT_PLAYER_FIREARM.firearm_data(),
|
|
||||||
DEFAULT_PLAYER_FIREARM.holdable_object_data(),
|
|
||||||
MagazineData { rounds_shot: 0, max_capacity: DEFAULT_PLAYER_FIREARM.firearm_data().max_capacity },
|
|
||||||
InPlayerHands,
|
|
||||||
|
|
||||||
))
|
|
||||||
.id();
|
|
||||||
|
|
||||||
commands.entity(entity).push_children(&[firearm]);
|
|
||||||
let time_in_secs_between_each_round =
|
|
||||||
1.0 / DEFAULT_PLAYER_FIREARM.firearm_data().fire_rate * 60.0;
|
|
||||||
player_firing_info.full_auto_timer = Timer::new(
|
|
||||||
Duration::from_secs_f32(time_in_secs_between_each_round),
|
|
||||||
TimerMode::Once,
|
|
||||||
);
|
|
||||||
// Load animations
|
|
||||||
//commands.insert_resource(FirearmAnimations { reload_magazine: asset_server.load(format!("{}#Animation0", DEFAULT_PLAYER_FIREARM.firearm_data().asset_path))})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct FirearmSprayPattern {
|
pub struct FirearmSprayPattern {
|
||||||
pub vertical: Vec<f32>,
|
pub vertical: Vec<f32>,
|
||||||
pub horizontal: Vec<f32>,
|
pub horizontal: Vec<f32>,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::PlayerHand},
|
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}},
|
||||||
logic::core::guns::player_firing::PlayerFiringInfo, utils::rad_deg::radians_from_degrees, setup::animations::FirearmAnimations,
|
logic::core::guns::player_firing::PlayerFiringInfo, utils::rad_deg::radians_from_degrees, setup::{animations::AllFirearmAnimations, load_state::GameLoadState},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn capture_hand_usage(
|
pub fn capture_hand_usage(
|
||||||
|
@ -11,36 +11,48 @@ pub fn capture_hand_usage(
|
||||||
mut hand_query: Query<&mut Transform, With<PlayerHand>>,
|
mut hand_query: Query<&mut Transform, With<PlayerHand>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
|
||||||
mut player_firing_info: ResMut<PlayerFiringInfo>,
|
|
||||||
mut firearm_query: Query<
|
mut firearm_query: Query<
|
||||||
(&mut Transform, &'static FirearmData, &mut MagazineData),
|
(&mut Transform, &'static FirearmData, &mut MagazineData),
|
||||||
(With<InPlayerHands>, Without<PlayerHand>),
|
(With<InPlayerHands>, Without<PlayerHand>),
|
||||||
>,
|
>,
|
||||||
|
player_query: Query<&Player>,
|
||||||
|
mut player_firing_info_query: Query<&mut PlayerFiringInfo, With<Player>>,
|
||||||
|
all_firearm_animations: Res<AllFirearmAnimations>,
|
||||||
|
mut animation_players: Query<&mut AnimationPlayer>,
|
||||||
animation_clips: Res<Assets<AnimationClip>>,
|
animation_clips: Res<Assets<AnimationClip>>,
|
||||||
mut players: Query<&mut AnimationPlayer>,
|
|
||||||
|
game_load_state: Res<GameLoadState>,
|
||||||
) {
|
) {
|
||||||
|
if !game_load_state.player_loaded {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(player_firearm) = player_query.single().0.equipment.primary_firearm.clone() {
|
||||||
|
for mut player_firing_info in player_firing_info_query.iter_mut() {
|
||||||
player_firing_info.full_auto_timer.tick(time.delta());
|
player_firing_info.full_auto_timer.tick(time.delta());
|
||||||
|
|
||||||
for (mut _firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
for (mut _firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
||||||
for mut hand_transform in hand_query.iter_mut() {
|
for mut hand_transform in hand_query.iter_mut() {
|
||||||
|
|
||||||
if player_firing_info.is_reloading {
|
if player_firing_info.is_reloading {
|
||||||
for player in &mut players {
|
for animation_player in &mut animation_players {
|
||||||
/*if let Some(reload_animation) = animation_clips.get(&animations.reload_magazine) {
|
if let Some(firearm_animations) = all_firearm_animations.animations.iter().find(|animation| &animation.firearm == &player_firearm) {
|
||||||
if player.elapsed() >= reload_animation.duration() {
|
if let Some(animation_clip) = animation_clips.get(&firearm_animations.reload_magazine) {
|
||||||
|
if animation_player.elapsed() >= animation_clip.duration() {
|
||||||
magazine_data.rounds_shot = 0;
|
magazine_data.rounds_shot = 0;
|
||||||
player_firing_info.is_reloading = false;
|
player_firing_info.is_reloading = false;
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { // Player is not in a reload animation
|
} else { // Player is not in a reload animation
|
||||||
if keyboard_input.just_pressed(KeyCode::R) {
|
if keyboard_input.just_pressed(KeyCode::R) {
|
||||||
// Start reload animation
|
// Start reload animation
|
||||||
/*for mut player in &mut players {
|
for mut animation_player in &mut animation_players {
|
||||||
player.start(animations.reload_magazine.clone_weak());
|
if let Some(firearm_animations) = all_firearm_animations.animations.iter().find(|animation| &animation.firearm == &player_firearm) {
|
||||||
|
animation_player.start(firearm_animations.reload_magazine.clone_weak());
|
||||||
player_firing_info.is_reloading = true;
|
player_firing_info.is_reloading = true;
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
// Set is_reloading = true
|
// Set is_reloading = true
|
||||||
// At the end of reload animation, set magazine data to capacity = 0
|
// At the end of reload animation, set magazine data to capacity = 0
|
||||||
}
|
}
|
||||||
|
@ -106,5 +118,7 @@ pub fn capture_hand_usage(
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{prelude::*, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}};
|
||||||
use bevy_inspector_egui::quick::WorldInspectorPlugin;
|
use bevy_inspector_egui::quick::WorldInspectorPlugin;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
use logic::core::guns::player_firing::PlayerFiringInfo;
|
use logic::core::guns::player_firing::PlayerFiringInfo;
|
||||||
|
@ -26,6 +26,8 @@ fn setup_plugins(application: &mut App) {
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
.add_plugins(WorldInspectorPlugin::new())
|
.add_plugins(WorldInspectorPlugin::new())
|
||||||
|
.add_plugins(LogDiagnosticsPlugin::default())
|
||||||
|
.add_plugins(FrameTimeDiagnosticsPlugin::default())
|
||||||
.register_type::<PlayerFiringInfo>();
|
.register_type::<PlayerFiringInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,13 @@ use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::controller::capture_input,
|
comps::core::controller::capture_input,
|
||||||
logic::core::{
|
logic::core::player::{
|
||||||
guns::{player_firing::PlayerFiringInfo, spawn_firearm::spawn_firearm_on_player_hands},
|
|
||||||
player::{
|
|
||||||
camera_player_sync::{
|
camera_player_sync::{
|
||||||
follow_cursor_with_camera, update_camera_vertical_position, MouseMovementSettings,
|
follow_cursor_with_camera, update_camera_vertical_position, MouseMovementSettings,
|
||||||
},
|
},
|
||||||
hands::capture_hand_usage,
|
hands::capture_hand_usage,
|
||||||
player_vertical_sync::sync_player_y_state,
|
player_vertical_sync::sync_player_y_state,
|
||||||
},
|
}, setup::{assets::load_all_assets, load_state::GameLoadState, spawn::add_all_spawners, animations::{load_animations, AllFirearmAnimations}, equipment::{EquipmentChangeEvent, change_equipment}},
|
||||||
}, setup::{assets::load_all_assets, load_state::GameLoadState, spawn::add_all_spawners, animations::load_animations},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -21,18 +18,13 @@ use super::{
|
||||||
pub fn load_scene(application: &mut App) {
|
pub fn load_scene(application: &mut App) {
|
||||||
application.insert_resource(GameLoadState::default());
|
application.insert_resource(GameLoadState::default());
|
||||||
application.insert_resource(MouseMovementSettings::default());
|
application.insert_resource(MouseMovementSettings::default());
|
||||||
application.insert_resource(PlayerFiringInfo::default());
|
application.insert_resource(AllFirearmAnimations::default());
|
||||||
// Startup
|
// Startup
|
||||||
application.add_systems(PreStartup, load_all_assets);
|
application.add_systems(PreStartup, load_all_assets);
|
||||||
application.add_systems(Startup, spawn_ground);
|
application.add_systems(Startup, spawn_ground);
|
||||||
application.add_systems(Startup, spawn_obstacles);
|
application.add_systems(Startup, spawn_obstacles);
|
||||||
application.add_systems(Startup, setup_lighting);
|
application.add_systems(Startup, setup_lighting);
|
||||||
application.add_systems(Startup, set_spawn_points);
|
application.add_systems(Startup, set_spawn_points);
|
||||||
|
|
||||||
application.add_systems(
|
|
||||||
PostStartup,
|
|
||||||
spawn_firearm_on_player_hands,
|
|
||||||
);
|
|
||||||
// Update
|
// Update
|
||||||
add_all_spawners(application);
|
add_all_spawners(application);
|
||||||
application.add_systems(Update, capture_input);
|
application.add_systems(Update, capture_input);
|
||||||
|
@ -44,4 +36,8 @@ pub fn load_scene(application: &mut App) {
|
||||||
application.add_systems(Update, set_skybox_if_loaded);
|
application.add_systems(Update, set_skybox_if_loaded);
|
||||||
application.add_systems(Update, update_camera_vertical_position);
|
application.add_systems(Update, update_camera_vertical_position);
|
||||||
application.add_systems(Update, capture_hand_usage);
|
application.add_systems(Update, capture_hand_usage);
|
||||||
|
|
||||||
|
application.add_systems(Update, change_equipment);
|
||||||
|
|
||||||
|
application.add_event::<EquipmentChangeEvent>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{setup::spawn::SpawnPoint, comps::core::markers::player::Player};
|
use crate::{setup::{spawn::SpawnPoint, equipment::Equipment}, comps::core::markers::player::{Player, PlayerData}, logic::core::guns::firearm::Firearm};
|
||||||
|
|
||||||
pub fn set_spawn_points(mut commands: Commands) {
|
pub fn set_spawn_points(mut commands: Commands) {
|
||||||
commands.spawn(SpawnPoint { at: Transform::from_xyz(3.0, 5.0, 2.0), what: Player });
|
commands.spawn(SpawnPoint { at: Transform::from_xyz(3.0, 5.0, 2.0), what: Player(PlayerData{ equipment: Equipment { primary_firearm: Some(Firearm::M4A1) }}) });
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ use crate::logic::core::guns::firearm::Firearm;
|
||||||
|
|
||||||
use super::{assets::GltfAssets, load_state::GameLoadState};
|
use super::{assets::GltfAssets, load_state::GameLoadState};
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource, Default)]
|
||||||
pub struct AllFirearmAnimations {
|
pub struct AllFirearmAnimations {
|
||||||
pub animations: Vec<FirearmAnimations>,
|
pub animations: Vec<FirearmAnimations>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use bevy::{prelude::*, gltf::Gltf};
|
||||||
|
|
||||||
|
use crate::{logic::core::guns::{firearm::Firearm, player_firing::PlayerFiringInfo}, comps::core::markers::{player::{Player, PlayerHand}, firearm::{MagazineData, FirearmData}, holdable::InPlayerHands}, utils};
|
||||||
|
|
||||||
|
use super::assets::{GltfAssets, GltfAssetType};
|
||||||
|
|
||||||
|
#[derive(Event)]
|
||||||
|
pub struct EquipmentChangeEvent(pub Equipment);
|
||||||
|
/// Foundation for inventory System.
|
||||||
|
#[derive(Component, Clone, Default)]
|
||||||
|
pub struct Equipment {
|
||||||
|
pub primary_firearm: Option<Firearm>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called whenever player wants to change equipment
|
||||||
|
pub fn change_equipment(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut equipment_change_event_reader: EventReader<EquipmentChangeEvent>,
|
||||||
|
mut player_query: Query<(&mut Player, &mut PlayerFiringInfo)>,
|
||||||
|
mut player_hands_query: Query<Entity, With<PlayerHand>>,
|
||||||
|
|
||||||
|
assets_gltf: Res<GltfAssets>,
|
||||||
|
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||||
|
) {
|
||||||
|
for equipment_change_event in equipment_change_event_reader.iter() {
|
||||||
|
// TODO: Equipment change
|
||||||
|
let (mut player, player_firing_info) = player_query.single_mut() ;
|
||||||
|
// Primary firearm change
|
||||||
|
if equipment_change_event.0.primary_firearm != player.0.equipment.primary_firearm {
|
||||||
|
|
||||||
|
let player_hands = player_hands_query.single_mut();
|
||||||
|
|
||||||
|
commands.entity(player_hands).clear_children(); // Don't do this without keeping the state from the last mag
|
||||||
|
if let Some(new_firearm) = equipment_change_event.0.primary_firearm.clone() {
|
||||||
|
spawn_firearm_on_player_hands(&mut commands, player_firing_info, player_hands, &assets_gltf, &loaded_gltf_assets, new_firearm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the player's equipment to the newly spawned equipment
|
||||||
|
player.0.equipment.primary_firearm = equipment_change_event.0.primary_firearm.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_firearm_on_player_hands(
|
||||||
|
commands: &mut Commands,
|
||||||
|
mut player_firing_info: Mut<PlayerFiringInfo>,
|
||||||
|
player_hands: Entity,
|
||||||
|
assets_gltf: &GltfAssets,
|
||||||
|
loaded_gltf_assets: &Assets<Gltf>,
|
||||||
|
firearm: Firearm,
|
||||||
|
) {
|
||||||
|
if let Some(asset_handle) = assets_gltf.assets.iter().find(|asset| asset.asset_type == GltfAssetType::Firearm(firearm.clone())) {
|
||||||
|
if let Some(gltf) = loaded_gltf_assets.get(&asset_handle.asset) {
|
||||||
|
let mut firearm_transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
||||||
|
firearm_transform.rotate_y(utils::rad_deg::radians_from_degrees(
|
||||||
|
firearm.holdable_object_data().y_rot,
|
||||||
|
));
|
||||||
|
|
||||||
|
let scene = gltf.scenes[0].clone();
|
||||||
|
let firearm_data: FirearmData = firearm.firearm_data();
|
||||||
|
let firearm_entity = commands
|
||||||
|
.spawn((
|
||||||
|
SceneBundle {
|
||||||
|
scene,
|
||||||
|
visibility: Visibility::Inherited,
|
||||||
|
transform: firearm_transform,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
firearm_data.clone(),
|
||||||
|
firearm.holdable_object_data(),
|
||||||
|
MagazineData { rounds_shot: 0, max_capacity: firearm_data.max_capacity },
|
||||||
|
InPlayerHands,
|
||||||
|
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
|
||||||
|
commands.entity(player_hands).push_children(&[firearm_entity]);
|
||||||
|
|
||||||
|
|
||||||
|
let time_in_secs_between_each_round =
|
||||||
|
1.0 / firearm_data.fire_rate * 60.0;
|
||||||
|
player_firing_info.full_auto_timer = Timer::new(
|
||||||
|
Duration::from_secs_f32(time_in_secs_between_each_round),
|
||||||
|
TimerMode::Once,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,3 +3,4 @@ pub mod animations;
|
||||||
pub mod load_state;
|
pub mod load_state;
|
||||||
pub mod spawn;
|
pub mod spawn;
|
||||||
pub mod spawners;
|
pub mod spawners;
|
||||||
|
pub mod equipment;
|
|
@ -4,11 +4,11 @@ use bevy_rapier3d::prelude::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::markers::{
|
comps::core::markers::{
|
||||||
camera::MainCamera,
|
camera::MainCamera,
|
||||||
player::{Player, PlayerHand},
|
player::{Player, PlayerHand, PlayerData},
|
||||||
},
|
},
|
||||||
constants::player_values::{
|
constants::player_values::{
|
||||||
PLAYER_GRAVITY_SCALE, PLAYER_HEIGHT, PLAYER_INITIAL_WEIGHT, PLAYER_LINEAR_DAMPING,
|
PLAYER_GRAVITY_SCALE, PLAYER_HEIGHT, PLAYER_INITIAL_WEIGHT, PLAYER_LINEAR_DAMPING,
|
||||||
}, logic::core::player::player_movement::{PlayerLinearYState, PlayerLinearXZState}, setup::load_state::GameLoadState,
|
}, logic::core::{player::player_movement::{PlayerLinearYState, PlayerLinearXZState}, guns::player_firing::PlayerFiringInfo}, setup::{load_state::GameLoadState, equipment::EquipmentChangeEvent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::setup::spawn::SpawnPoint;
|
use crate::setup::spawn::SpawnPoint;
|
||||||
|
@ -19,6 +19,7 @@ pub fn player_spawner(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
player_sp_query: Query<(Entity, &SpawnPoint<Player>)>,
|
player_sp_query: Query<(Entity, &SpawnPoint<Player>)>,
|
||||||
mut game_load_state: ResMut<GameLoadState>,
|
mut game_load_state: ResMut<GameLoadState>,
|
||||||
|
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||||
) {
|
) {
|
||||||
if game_load_state.player_loaded || !game_load_state.is_everything_except_player_loaded() {
|
if game_load_state.player_loaded || !game_load_state.is_everything_except_player_loaded() {
|
||||||
return;
|
return;
|
||||||
|
@ -52,7 +53,8 @@ pub fn player_spawner(
|
||||||
|
|
||||||
// Spawn player
|
// Spawn player
|
||||||
commands
|
commands
|
||||||
.spawn(Player)
|
.spawn(Player(PlayerData::default()))
|
||||||
|
// Physics
|
||||||
.insert(RigidBody::Dynamic)
|
.insert(RigidBody::Dynamic)
|
||||||
.insert(GravityScale(PLAYER_GRAVITY_SCALE))
|
.insert(GravityScale(PLAYER_GRAVITY_SCALE))
|
||||||
.insert(Collider::capsule_y(PLAYER_HEIGHT, 2.0))
|
.insert(Collider::capsule_y(PLAYER_HEIGHT, 2.0))
|
||||||
|
@ -80,15 +82,19 @@ pub fn player_spawner(
|
||||||
impulse: Vec3::ZERO,
|
impulse: Vec3::ZERO,
|
||||||
torque_impulse: Vec3::ZERO,
|
torque_impulse: Vec3::ZERO,
|
||||||
})
|
})
|
||||||
|
// Controller state
|
||||||
.insert(PlayerLinearYState::Falling)
|
.insert(PlayerLinearYState::Falling)
|
||||||
.insert(PlayerLinearXZState::Stopped)
|
.insert(PlayerLinearXZState::Stopped)
|
||||||
|
// Engine stuff
|
||||||
.insert(VisibilityBundle {
|
.insert(VisibilityBundle {
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
// Data
|
||||||
|
.insert(PlayerFiringInfo::default())
|
||||||
.push_children(&[camera]);
|
.push_children(&[camera]);
|
||||||
|
|
||||||
|
equipment_change_event_writer.send(EquipmentChangeEvent(player_spawn_point.what.0.equipment.clone()));
|
||||||
commands.entity(player_spawn_point_entity).despawn();
|
commands.entity(player_spawn_point_entity).despawn();
|
||||||
game_load_state.player_loaded = true;
|
game_load_state.player_loaded = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue