Interactable hud bug fixes
This commit is contained in:
parent
bc90efbbc4
commit
8afa56d306
@ -1,9 +1,15 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
use crate::{logic::core::player::{player_movement::{
|
use crate::{
|
||||||
|
logic::core::player::{
|
||||||
|
player_movement::{
|
||||||
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
|
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
|
||||||
}, player_values_state::PlayerValuesState}, ui::game::settings::SettingsScreenUIConfiguration};
|
},
|
||||||
|
player_values_state::PlayerValuesState,
|
||||||
|
},
|
||||||
|
ui::game::settings::SettingsScreenUIConfiguration,
|
||||||
|
};
|
||||||
|
|
||||||
use super::markers::player::Player;
|
use super::markers::player::Player;
|
||||||
|
|
||||||
@ -23,7 +29,7 @@ pub fn capture_input(
|
|||||||
>,
|
>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
||||||
player_values_state: Res<PlayerValuesState>
|
player_values_state: Res<PlayerValuesState>,
|
||||||
) {
|
) {
|
||||||
// Don't allocate on each frame. Instead Check if any of the inputs are being pressed and then allocate.
|
// Don't allocate on each frame. Instead Check if any of the inputs are being pressed and then allocate.
|
||||||
if keyboard_input.any_pressed([
|
if keyboard_input.any_pressed([
|
||||||
@ -51,9 +57,19 @@ pub fn capture_input(
|
|||||||
sprint: keyboard_input.pressed(KeyCode::ShiftLeft),
|
sprint: keyboard_input.pressed(KeyCode::ShiftLeft),
|
||||||
};
|
};
|
||||||
if settings_screen_config.settings_menu_shown {
|
if settings_screen_config.settings_menu_shown {
|
||||||
move_player(PlayerMovementInput::default(), player_query, time, player_values_state);
|
move_player(
|
||||||
|
PlayerMovementInput::default(),
|
||||||
|
player_query,
|
||||||
|
time,
|
||||||
|
player_values_state,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
move_player(player_movement_input, player_query, time, player_values_state);
|
move_player(
|
||||||
|
player_movement_input,
|
||||||
|
player_query,
|
||||||
|
time,
|
||||||
|
player_values_state,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct UGrid {
|
pub struct UGrid {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
@ -8,7 +7,10 @@ pub struct UGrid {
|
|||||||
impl UGrid {
|
impl UGrid {
|
||||||
/// Creates a ugrid with width = size and height = size
|
/// Creates a ugrid with width = size and height = size
|
||||||
pub fn new_square(size: u32) -> Self {
|
pub fn new_square(size: u32) -> Self {
|
||||||
Self { width: size, height: size }
|
Self {
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +18,10 @@ impl std::ops::Add for UGrid {
|
|||||||
type Output = UGrid;
|
type Output = UGrid;
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
Self { width: self.width + rhs.width, height: self.height + rhs.height }
|
Self {
|
||||||
|
width: self.width + rhs.width,
|
||||||
|
height: self.height + rhs.height,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +29,9 @@ impl std::ops::Sub for UGrid {
|
|||||||
type Output = UGrid;
|
type Output = UGrid;
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
fn sub(self, rhs: Self) -> Self::Output {
|
||||||
Self { width: self.width - rhs.width, height: self.height - rhs.height }
|
Self {
|
||||||
|
width: self.width - rhs.width,
|
||||||
|
height: self.height - rhs.height,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use bevy::ecs::component::SparseStorage;
|
use bevy::ecs::component::SparseStorage;
|
||||||
|
|
||||||
use crate::comps::core::{items::item::Item, grid::UGrid};
|
use crate::comps::core::{grid::UGrid, items::item::Item};
|
||||||
|
|
||||||
use super::inventory_item::InventoryItem;
|
use super::inventory_item::InventoryItem;
|
||||||
|
|
||||||
@ -8,19 +8,18 @@ use super::inventory_item::InventoryItem;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AnyInventory {
|
pub struct AnyInventory {
|
||||||
size: UGrid,
|
size: UGrid,
|
||||||
items: Vec<InventoryItem>
|
items: Vec<InventoryItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl AnyInventory {
|
impl AnyInventory {
|
||||||
pub fn new(size: UGrid) -> Self {
|
pub fn new(size: UGrid) -> Self {
|
||||||
Self { size, items: Vec::new() }
|
Self {
|
||||||
|
size,
|
||||||
|
items: Vec::new(),
|
||||||
}
|
}
|
||||||
pub fn add_item_at(
|
}
|
||||||
&mut self,
|
pub fn add_item_at(&mut self, position: UGrid, item: impl Item<Storage = SparseStorage>) {
|
||||||
position: UGrid,
|
|
||||||
item: impl Item<Storage = SparseStorage>,
|
|
||||||
) {
|
|
||||||
// Is Item bigger than inventory?
|
// Is Item bigger than inventory?
|
||||||
// Does position + item size exceed bounds?
|
// Does position + item size exceed bounds?
|
||||||
if !self.valid_item_and_size_for_inventory(position, &item) {
|
if !self.valid_item_and_size_for_inventory(position, &item) {
|
||||||
@ -38,17 +37,23 @@ impl AnyInventory {
|
|||||||
let spots_to_occupy = Self::get_spots_from_item_at_pos(position, item);
|
let spots_to_occupy = Self::get_spots_from_item_at_pos(position, item);
|
||||||
for inventory_item in self.items.iter() {
|
for inventory_item in self.items.iter() {
|
||||||
if inventory_item.is_in_range(&spots_to_occupy) {
|
if inventory_item.is_in_range(&spots_to_occupy) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
pub fn get_spots_from_item_at_pos(position: UGrid, item: &impl Item<Storage = SparseStorage>) -> Vec<UGrid> {
|
pub fn get_spots_from_item_at_pos(
|
||||||
|
position: UGrid,
|
||||||
|
item: &impl Item<Storage = SparseStorage>,
|
||||||
|
) -> Vec<UGrid> {
|
||||||
let end_position = position + item.inventory_size();
|
let end_position = position + item.inventory_size();
|
||||||
let mut spots = Vec::new();
|
let mut spots = Vec::new();
|
||||||
for pos_width in position.width..end_position.width {
|
for pos_width in position.width..end_position.width {
|
||||||
for pos_height in position.height..end_position.height {
|
for pos_height in position.height..end_position.height {
|
||||||
spots.push(UGrid { width: pos_width, height: pos_height });
|
spots.push(UGrid {
|
||||||
|
width: pos_width,
|
||||||
|
height: pos_height,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spots
|
spots
|
||||||
|
@ -4,7 +4,6 @@ use bevy::ecs::component::SparseStorage;
|
|||||||
|
|
||||||
use crate::comps::core::{grid::UGrid, items::item::Item};
|
use crate::comps::core::{grid::UGrid, items::item::Item};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InventoryItem {
|
pub struct InventoryItem {
|
||||||
item: Arc<dyn Item<Storage = SparseStorage>>,
|
item: Arc<dyn Item<Storage = SparseStorage>>,
|
||||||
@ -21,19 +20,20 @@ impl InventoryItem {
|
|||||||
pub fn rotated(&self) -> Option<bool> {
|
pub fn rotated(&self) -> Option<bool> {
|
||||||
self.rotated
|
self.rotated
|
||||||
}
|
}
|
||||||
pub fn new(
|
pub fn new(item: impl Item<Storage = SparseStorage>, occupied_spots: Vec<UGrid>) -> Self {
|
||||||
item: impl Item<Storage = SparseStorage>,
|
|
||||||
occupied_spots: Vec<UGrid>,
|
|
||||||
) -> Self {
|
|
||||||
let size = item.inventory_size();
|
let size = item.inventory_size();
|
||||||
let rotated = item.inventory_rotatable().then(|| false);
|
let rotated = item.inventory_rotatable().then(|| false);
|
||||||
Self { item: Arc::new(item), occupied_spots, rotated }
|
Self {
|
||||||
|
item: Arc::new(item),
|
||||||
|
occupied_spots,
|
||||||
|
rotated,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Returns true if there is overlap between both
|
/// Returns true if there is overlap between both
|
||||||
pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool {
|
pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool {
|
||||||
for occupied_spot in self.occupied_spots.iter() {
|
for occupied_spot in self.occupied_spots.iter() {
|
||||||
if spots_to_occupy.contains(occupied_spot) {
|
if spots_to_occupy.contains(occupied_spot) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use bevy::{prelude::*, ecs::component::SparseStorage};
|
use bevy::{ecs::component::SparseStorage, prelude::*};
|
||||||
|
|
||||||
use crate::comps::core::items::item::Item;
|
use crate::comps::core::items::item::Item;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::comps::core::grid::UGrid;
|
use crate::comps::core::grid::UGrid;
|
||||||
|
|
||||||
use super::{item_inventory::ItemInventory, any_inventory::AnyInventory};
|
use super::{any_inventory::AnyInventory, item_inventory::ItemInventory};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct PlayerInventory {
|
pub struct PlayerInventory {
|
||||||
@ -13,6 +13,10 @@ pub struct PlayerInventory {
|
|||||||
|
|
||||||
impl Default for PlayerInventory {
|
impl Default for PlayerInventory {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { primary: Default::default(), secondary: Default::default(), backpack: AnyInventory::new(UGrid::new_square(10)) }
|
Self {
|
||||||
|
primary: Default::default(),
|
||||||
|
secondary: Default::default(),
|
||||||
|
backpack: AnyInventory::new(UGrid::new_square(10)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
46
src/comps/core/items/guns/m4a1.rs
Normal file
46
src/comps/core/items/guns/m4a1.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
comps::core::{
|
||||||
|
grid::UGrid,
|
||||||
|
items::item::{Item, ItemType},
|
||||||
|
markers::holdable::HoldableObjectType,
|
||||||
|
},
|
||||||
|
logic::core::guns::firearm::Firearm,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct M4a1GunItem;
|
||||||
|
|
||||||
|
impl Item for M4a1GunItem {
|
||||||
|
fn get_type(&self) -> ItemType {
|
||||||
|
ItemType::Holdable(HoldableObjectType::Firearm(Firearm::M4A1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asset_path(&self) -> &str {
|
||||||
|
"weapons/m4a1_rifle.glb"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stackable(&self) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inventory_size(&self) -> crate::comps::core::grid::UGrid {
|
||||||
|
UGrid {
|
||||||
|
width: 4,
|
||||||
|
height: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inventory_rotatable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inventory_title(&self) -> String {
|
||||||
|
String::from("M4A1 Rifle")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inventory_description(&self) -> String {
|
||||||
|
String::from("Rifle chambered in 5.56x45mm NATO, shoots 800 rounds per minute.")
|
||||||
|
}
|
||||||
|
}
|
1
src/comps/core/items/guns/mod.rs
Normal file
1
src/comps/core/items/guns/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod m4a1;
|
@ -1,11 +1,17 @@
|
|||||||
use bevy::prelude::*;
|
use crate::{
|
||||||
|
comps::core::{
|
||||||
use crate::comps::core::grid::UGrid;
|
grid::UGrid,
|
||||||
|
markers::{firearm::FirearmData, holdable::HoldableObjectType, interactable::Interactable},
|
||||||
|
},
|
||||||
|
setup::assets::{GltfAssetType, GltfAssets},
|
||||||
|
utils,
|
||||||
|
};
|
||||||
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub enum ItemType {
|
pub enum ItemType {
|
||||||
Holdable,
|
Holdable(HoldableObjectType),
|
||||||
Equippable,
|
Equippable,
|
||||||
Consumable,
|
Consumable,
|
||||||
}
|
}
|
||||||
@ -18,4 +24,72 @@ pub trait Item: Component {
|
|||||||
fn inventory_size(&self) -> UGrid;
|
fn inventory_size(&self) -> UGrid;
|
||||||
fn inventory_rotatable(&self) -> bool;
|
fn inventory_rotatable(&self) -> bool;
|
||||||
fn inventory_title(&self) -> String;
|
fn inventory_title(&self) -> String;
|
||||||
|
fn inventory_description(&self) -> String;
|
||||||
|
fn spawn(
|
||||||
|
&self,
|
||||||
|
commands: &mut Commands,
|
||||||
|
transform: Transform,
|
||||||
|
assets_gltf: &GltfAssets,
|
||||||
|
loaded_gltf_assets: &Assets<Gltf>,
|
||||||
|
) {
|
||||||
|
match self.get_type() {
|
||||||
|
ItemType::Holdable(object_type) => {
|
||||||
|
match object_type {
|
||||||
|
HoldableObjectType::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 firearm_data: FirearmData = firearm.firearm_data();
|
||||||
|
let mut firearm_transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
firearm_transform.rotate_local_y(
|
||||||
|
utils::rad_deg::radians_from_degrees(
|
||||||
|
firearm.holdable_object_data().y_rot,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
firearm_transform.scale =
|
||||||
|
firearm_transform.scale * firearm_data.scale_factor;
|
||||||
|
|
||||||
|
let scene = gltf.scenes[0].clone();
|
||||||
|
let firearm_asset_entity = commands
|
||||||
|
.spawn((
|
||||||
|
SceneBundle {
|
||||||
|
scene,
|
||||||
|
visibility: Visibility::Inherited,
|
||||||
|
transform: firearm_transform,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Name::new(format!(
|
||||||
|
"{} Item Gltf Asset",
|
||||||
|
self.inventory_title()
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
firearm.holdable_object_data(),
|
||||||
|
Name::new(format!("{} Item", self.inventory_title())),
|
||||||
|
TransformBundle {
|
||||||
|
local: transform,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
VisibilityBundle {
|
||||||
|
visibility: Visibility::Visible,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
RigidBody::Dynamic,
|
||||||
|
Collider::cuboid(5.0, 5.0, 5.0),
|
||||||
|
Interactable::Item,
|
||||||
|
))
|
||||||
|
.push_children(&[firearm_asset_entity]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ItemType::Equippable => todo!(),
|
||||||
|
ItemType::Consumable => todo!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
@ -1 +1,2 @@
|
|||||||
|
pub mod guns;
|
||||||
pub mod item;
|
pub mod item;
|
@ -1,8 +1,11 @@
|
|||||||
use bevy::{prelude::{Component, Vec3}, reflect::Reflect, time::Timer};
|
use bevy::{
|
||||||
|
prelude::{Component, Vec3},
|
||||||
|
reflect::Reflect,
|
||||||
|
time::Timer,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::logic::core::guns::caliber::Caliber;
|
use crate::logic::core::guns::caliber::Caliber;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Component, Reflect)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct BulletMarker {
|
pub struct BulletMarker {
|
||||||
pub caliber: Caliber,
|
pub caliber: Caliber,
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use bevy::{prelude::{Component, Quat, Vec3}, reflect::Reflect};
|
use bevy::{
|
||||||
|
prelude::{Component, Quat, Vec3},
|
||||||
|
reflect::Reflect,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::logic::core::guns::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
use crate::logic::core::guns::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::logic::core::guns::firearm::Firearm;
|
||||||
|
|
||||||
/// Anything that can go in the player's hands.
|
/// Anything that can go in the player's hands.
|
||||||
#[derive(Component, Default, Debug, Reflect)]
|
#[derive(Component, Default, Debug, Reflect)]
|
||||||
pub struct HoldableObjectData {
|
pub struct HoldableObjectData {
|
||||||
@ -11,3 +13,8 @@ pub struct HoldableObjectData {
|
|||||||
|
|
||||||
#[derive(Component, Reflect)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct InPlayerHands;
|
pub struct InPlayerHands;
|
||||||
|
|
||||||
|
#[derive(Reflect)]
|
||||||
|
pub enum HoldableObjectType {
|
||||||
|
Firearm(Firearm),
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
pub mod bullet;
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod firearm;
|
pub mod firearm;
|
||||||
pub mod holdable;
|
pub mod holdable;
|
||||||
pub mod player;
|
|
||||||
pub mod muzzle_flash;
|
|
||||||
pub mod bullet;
|
|
||||||
pub mod interactable;
|
pub mod interactable;
|
||||||
|
pub mod muzzle_flash;
|
||||||
|
pub mod player;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub mod controller;
|
pub mod controller;
|
||||||
pub mod markers;
|
|
||||||
pub mod grid;
|
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
pub mod grid;
|
||||||
pub mod inventory;
|
pub mod inventory;
|
||||||
pub mod items;
|
pub mod items;
|
||||||
|
pub mod markers;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -1,8 +1,12 @@
|
|||||||
|
use crate::comps::core::markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
use crate::comps::core::markers::{muzzle_flash::MuzzleFlashMarker, bullet::BulletMarker};
|
|
||||||
|
|
||||||
pub fn despawn_muzzle_flashes(mut commands: Commands, mut query: Query<(&mut MuzzleFlashMarker, Entity)>, time: Res<Time>) {
|
pub fn despawn_muzzle_flashes(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut query: Query<(&mut MuzzleFlashMarker, Entity)>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
for (mut muzzle_flash, entity) in query.iter_mut() {
|
for (mut muzzle_flash, entity) in query.iter_mut() {
|
||||||
muzzle_flash.0.tick(time.delta());
|
muzzle_flash.0.tick(time.delta());
|
||||||
if muzzle_flash.0.finished() {
|
if muzzle_flash.0.finished() {
|
||||||
@ -26,28 +30,41 @@ pub fn despawn_stray_bullets(
|
|||||||
for event in collisions_read.iter() {
|
for event in collisions_read.iter() {
|
||||||
match event {
|
match event {
|
||||||
CollisionEvent::Started(entity_a, entity_b, _) => {
|
CollisionEvent::Started(entity_a, entity_b, _) => {
|
||||||
if entity_a == entity_b { // Avoid inner collisions
|
if entity_a == entity_b {
|
||||||
|
// Avoid inner collisions
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if entity_a == &bullet_entity || entity_b == &bullet_entity{
|
if entity_a == &bullet_entity || entity_b == &bullet_entity {
|
||||||
commands.entity(bullet_entity).remove::<Collider>();
|
commands.entity(bullet_entity).remove::<Collider>();
|
||||||
//commands.entity(bullet_entity).insert(Sensor);
|
//commands.entity(bullet_entity).insert(Sensor);
|
||||||
spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
|
spawn_bullet_hit_marker(
|
||||||
|
&mut commands,
|
||||||
|
transform.translation,
|
||||||
|
&mut meshes,
|
||||||
|
&mut materials,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
CollisionEvent::Stopped(entity_a, entity_b, _) => {
|
CollisionEvent::Stopped(entity_a, entity_b, _) => {
|
||||||
if entity_a == entity_b { // Avoid inner collisions
|
if entity_a == entity_b {
|
||||||
|
// Avoid inner collisions
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if entity_a == &bullet_entity || entity_b == &bullet_entity{
|
if entity_a == &bullet_entity || entity_b == &bullet_entity {
|
||||||
commands.entity(bullet_entity).insert(Collider::ball(bullet.caliber.size()));
|
commands
|
||||||
|
.entity(bullet_entity)
|
||||||
|
.insert(Collider::ball(bullet.caliber.size()));
|
||||||
//commands.entity(bullet_entity).remove::<Sensor>();
|
//commands.entity(bullet_entity).remove::<Sensor>();
|
||||||
//commands.entity(*entity_b).despawn();
|
//commands.entity(*entity_b).despawn();
|
||||||
spawn_bullet_exit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
|
spawn_bullet_exit_marker(
|
||||||
|
&mut commands,
|
||||||
|
transform.translation,
|
||||||
|
&mut meshes,
|
||||||
|
&mut materials,
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} //_ => {}
|
||||||
//_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bullet.timer.finished() {
|
if bullet.timer.finished() {
|
||||||
@ -65,12 +82,15 @@ fn spawn_bullet_hit_marker(
|
|||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
meshes: &mut ResMut<Assets<Mesh>>,
|
||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
commands.spawn(
|
commands.spawn((MaterialMeshBundle {
|
||||||
(
|
|
||||||
MaterialMeshBundle {
|
|
||||||
mesh: {
|
mesh: {
|
||||||
meshes.add(
|
meshes.add(
|
||||||
shape::UVSphere { radius: 0.05, sectors: 36, stacks: 18 }.into()
|
shape::UVSphere {
|
||||||
|
radius: 0.05,
|
||||||
|
sectors: 36,
|
||||||
|
stacks: 18,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
@ -78,14 +98,11 @@ fn spawn_bullet_hit_marker(
|
|||||||
//base_color_texture: Some(Color::GREEN),
|
//base_color_texture: Some(Color::GREEN),
|
||||||
emissive: Color::GREEN,
|
emissive: Color::GREEN,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
||||||
}),
|
}),
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
transform: Transform::from_translation(at),
|
transform: Transform::from_translation(at),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_bullet_exit_marker(
|
fn spawn_bullet_exit_marker(
|
||||||
@ -94,12 +111,15 @@ fn spawn_bullet_exit_marker(
|
|||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
meshes: &mut ResMut<Assets<Mesh>>,
|
||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
commands.spawn(
|
commands.spawn((MaterialMeshBundle {
|
||||||
(
|
|
||||||
MaterialMeshBundle {
|
|
||||||
mesh: {
|
mesh: {
|
||||||
meshes.add(
|
meshes.add(
|
||||||
shape::UVSphere { radius: 0.05, sectors: 36, stacks: 18 }.into()
|
shape::UVSphere {
|
||||||
|
radius: 0.05,
|
||||||
|
sectors: 36,
|
||||||
|
stacks: 18,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
@ -107,12 +127,9 @@ fn spawn_bullet_exit_marker(
|
|||||||
//base_color_texture: Some(Color::GREEN),
|
//base_color_texture: Some(Color::GREEN),
|
||||||
emissive: Color::RED,
|
emissive: Color::RED,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
||||||
}),
|
}),
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
transform: Transform::from_translation(at),
|
transform: Transform::from_translation(at),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
@ -1,4 +1,7 @@
|
|||||||
use crate::comps::core::markers::{firearm::{FirearmData, FiringPoint}, holdable::HoldableObjectData};
|
use crate::comps::core::markers::{
|
||||||
|
firearm::{FirearmData, FiringPoint},
|
||||||
|
holdable::HoldableObjectData,
|
||||||
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use super::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
use super::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
||||||
@ -27,10 +30,10 @@ impl Firearm {
|
|||||||
horizontal_recoil_modifier: 0.5,
|
horizontal_recoil_modifier: 0.5,
|
||||||
recoil_pattern: FirearmSprayPattern {
|
recoil_pattern: FirearmSprayPattern {
|
||||||
vertical: Vec::from([
|
vertical: Vec::from([
|
||||||
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
|
||||||
]),
|
]),
|
||||||
horizontal: Vec::from([
|
horizontal: Vec::from([
|
||||||
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
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -52,7 +55,7 @@ impl Firearm {
|
|||||||
scale_factor: 1.0,
|
scale_factor: 1.0,
|
||||||
asset_path: String::from("weapons/m4a1_rifle.glb"),
|
asset_path: String::from("weapons/m4a1_rifle.glb"),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Firearm::Glock17 => {
|
Firearm::Glock17 => {
|
||||||
FirearmData {
|
FirearmData {
|
||||||
firing_point: FiringPoint {
|
firing_point: FiringPoint {
|
||||||
@ -68,10 +71,10 @@ impl Firearm {
|
|||||||
horizontal_recoil_modifier: 1.0,
|
horizontal_recoil_modifier: 1.0,
|
||||||
recoil_pattern: FirearmSprayPattern {
|
recoil_pattern: FirearmSprayPattern {
|
||||||
vertical: Vec::from([
|
vertical: Vec::from([
|
||||||
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
|
||||||
]),
|
]),
|
||||||
horizontal: Vec::from([
|
horizontal: Vec::from([
|
||||||
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
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -93,7 +96,7 @@ impl Firearm {
|
|||||||
scale_factor: 0.25,
|
scale_factor: 0.25,
|
||||||
asset_path: String::from("weapons/glock_17_pistol.glb"),
|
asset_path: String::from("weapons/glock_17_pistol.glb"),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn holdable_object_data(&self) -> HoldableObjectData {
|
pub fn holdable_object_data(&self) -> HoldableObjectData {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub mod caliber;
|
pub mod caliber;
|
||||||
|
pub mod despawn_shots;
|
||||||
|
pub mod equip_firearm;
|
||||||
pub mod firearm;
|
pub mod firearm;
|
||||||
pub mod player_firing;
|
pub mod player_firing;
|
||||||
pub mod spray_pattern;
|
|
||||||
pub mod equip_firearm;
|
|
||||||
pub mod shoot;
|
pub mod shoot;
|
||||||
pub mod despawn_shots;
|
pub mod spray_pattern;
|
||||||
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
use crate::comps::core::markers::{muzzle_flash::MuzzleFlashMarker, bullet::BulletMarker};
|
use crate::comps::core::markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker};
|
||||||
|
|
||||||
use super::caliber::Caliber;
|
use super::caliber::Caliber;
|
||||||
|
|
||||||
@ -14,14 +14,19 @@ pub fn shoot_bullet(
|
|||||||
firing_point: Transform,
|
firing_point: Transform,
|
||||||
forward: Vec3,
|
forward: Vec3,
|
||||||
up: Vec3,
|
up: Vec3,
|
||||||
caliber: Caliber
|
caliber: Caliber,
|
||||||
) {
|
) {
|
||||||
// Spawn muzzle flash LIGHT
|
// Spawn muzzle flash LIGHT
|
||||||
commands.spawn(
|
commands.spawn((
|
||||||
(PointLightBundle {
|
PointLightBundle {
|
||||||
point_light: PointLight {
|
point_light: PointLight {
|
||||||
//RGB 252, 238, 128
|
//RGB 252, 238, 128
|
||||||
color: Color::Rgba { red: 252., green: 238., blue: 128., alpha: 0.5 },
|
color: Color::Rgba {
|
||||||
|
red: 252.,
|
||||||
|
green: 238.,
|
||||||
|
blue: 128.,
|
||||||
|
alpha: 0.5,
|
||||||
|
},
|
||||||
intensity: 0.005,
|
intensity: 0.005,
|
||||||
range: 50.0,
|
range: 50.0,
|
||||||
shadows_enabled: true,
|
shadows_enabled: true,
|
||||||
@ -30,8 +35,9 @@ pub fn shoot_bullet(
|
|||||||
transform: firing_point,
|
transform: firing_point,
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)))
|
},
|
||||||
);
|
MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)),
|
||||||
|
));
|
||||||
// Spawn Line
|
// Spawn Line
|
||||||
/*commands.spawn(
|
/*commands.spawn(
|
||||||
MaterialMeshBundle {
|
MaterialMeshBundle {
|
||||||
@ -50,7 +56,15 @@ pub fn shoot_bullet(
|
|||||||
}
|
}
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
spawn_bullet(commands, meshes, materials, firing_point, forward, up, caliber);
|
spawn_bullet(
|
||||||
|
commands,
|
||||||
|
meshes,
|
||||||
|
materials,
|
||||||
|
firing_point,
|
||||||
|
forward,
|
||||||
|
up,
|
||||||
|
caliber,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_bullet(
|
pub fn spawn_bullet(
|
||||||
@ -60,24 +74,36 @@ pub fn spawn_bullet(
|
|||||||
firing_point: Transform,
|
firing_point: Transform,
|
||||||
forward: Vec3,
|
forward: Vec3,
|
||||||
_up: Vec3,
|
_up: Vec3,
|
||||||
caliber: Caliber
|
caliber: Caliber,
|
||||||
) {
|
) {
|
||||||
commands.spawn(
|
commands.spawn((
|
||||||
(
|
|
||||||
Name::new("Bullet"),
|
Name::new("Bullet"),
|
||||||
BulletMarker {
|
BulletMarker {
|
||||||
caliber: caliber.clone(),
|
caliber: caliber.clone(),
|
||||||
starting_point: firing_point.translation,
|
starting_point: firing_point.translation,
|
||||||
timer: Timer::new(Duration::from_secs_f32(caliber.max_airtime_secs()), TimerMode::Once)
|
timer: Timer::new(
|
||||||
|
Duration::from_secs_f32(caliber.max_airtime_secs()),
|
||||||
|
TimerMode::Once,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
MaterialMeshBundle {
|
MaterialMeshBundle {
|
||||||
mesh: {
|
mesh: {
|
||||||
meshes.add(
|
meshes.add(
|
||||||
shape::UVSphere { radius: caliber.size(), sectors: 36, stacks: 18 }.into()
|
shape::UVSphere {
|
||||||
|
radius: caliber.size(),
|
||||||
|
sectors: 36,
|
||||||
|
stacks: 18,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::Rgba { red: 253., green: 207., blue: 88., alpha: 1.0 },
|
base_color: Color::Rgba {
|
||||||
|
red: 253.,
|
||||||
|
green: 207.,
|
||||||
|
blue: 88.,
|
||||||
|
alpha: 1.0,
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
@ -98,7 +124,6 @@ pub fn spawn_bullet(
|
|||||||
torque_impulse: Vec3::ZERO,
|
torque_impulse: Vec3::ZERO,
|
||||||
},
|
},
|
||||||
ActiveEvents::COLLISION_EVENTS,
|
ActiveEvents::COLLISION_EVENTS,
|
||||||
Ccd::enabled()
|
Ccd::enabled(),
|
||||||
)
|
));
|
||||||
);
|
|
||||||
}
|
}
|
@ -1,7 +1,5 @@
|
|||||||
use bevy::reflect::Reflect;
|
use bevy::reflect::Reflect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Reflect)]
|
#[derive(Clone, Reflect)]
|
||||||
pub struct FirearmSprayPattern {
|
pub struct FirearmSprayPattern {
|
||||||
pub vertical: Vec<f32>,
|
pub vertical: Vec<f32>,
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -3,7 +3,8 @@ use bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::markers::{camera::MainCamera, player::Player},
|
comps::core::markers::{camera::MainCamera, player::Player},
|
||||||
utils::rad_deg::radians_from_degrees, ui::game::settings::SettingsScreenUIConfiguration,
|
ui::game::settings::SettingsScreenUIConfiguration,
|
||||||
|
utils::rad_deg::radians_from_degrees,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{player_movement::PlayerLinearXZState, player_values_state::PlayerValuesState};
|
use super::{player_movement::PlayerLinearXZState, player_values_state::PlayerValuesState};
|
||||||
@ -80,11 +81,13 @@ pub fn follow_cursor_with_camera(
|
|||||||
) {
|
) {
|
||||||
if let Ok(mut window) = primary_window.get_single_mut() {
|
if let Ok(mut window) = primary_window.get_single_mut() {
|
||||||
if keyboard_input.just_pressed(KeyCode::Escape) {
|
if keyboard_input.just_pressed(KeyCode::Escape) {
|
||||||
if settings_screen_config.settings_menu_shown { // Hide settings screen & Capture Cursor
|
if settings_screen_config.settings_menu_shown {
|
||||||
|
// Hide settings screen & Capture Cursor
|
||||||
settings_screen_config.settings_menu_shown = false;
|
settings_screen_config.settings_menu_shown = false;
|
||||||
window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place
|
window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place
|
||||||
window.cursor.visible = false; // also hide the cursor
|
window.cursor.visible = false; // also hide the cursor
|
||||||
} else { // Show Settings screen & Release Cursor
|
} else {
|
||||||
|
// Show Settings screen & Release Cursor
|
||||||
settings_screen_config.settings_menu_shown = true;
|
settings_screen_config.settings_menu_shown = true;
|
||||||
window.cursor.grab_mode = CursorGrabMode::None; // Release cursor
|
window.cursor.grab_mode = CursorGrabMode::None; // Release cursor
|
||||||
window.cursor.visible = true; // Show cursor
|
window.cursor.visible = true; // Show cursor
|
||||||
@ -112,14 +115,23 @@ pub fn follow_cursor_with_camera(
|
|||||||
for motion in motions.read() {
|
for motion in motions.read() {
|
||||||
let window_scale = window.height().min(window.width());
|
let window_scale = window.height().min(window.width());
|
||||||
if btn.pressed(MouseButton::Right) {
|
if btn.pressed(MouseButton::Right) {
|
||||||
pitch -= ((settings.aimed_sensitivity * motion.delta.y as f64 * window_scale as f64) as f32)
|
pitch -= ((settings.aimed_sensitivity
|
||||||
|
* motion.delta.y as f64
|
||||||
|
* window_scale as f64) as f32)
|
||||||
.to_radians();
|
.to_radians();
|
||||||
yaw -= ((settings.aimed_sensitivity * motion.delta.x as f64 * window_scale as f64) as f32)
|
yaw -= ((settings.aimed_sensitivity
|
||||||
|
* motion.delta.x as f64
|
||||||
|
* window_scale as f64) as f32)
|
||||||
.to_radians();
|
.to_radians();
|
||||||
} else {
|
} else {
|
||||||
pitch -=
|
pitch -= ((settings.sensitivity
|
||||||
((settings.sensitivity * motion.delta.y as f64 * window_scale as f64) as f32).to_radians();
|
* motion.delta.y as f64
|
||||||
yaw -= ((settings.sensitivity * motion.delta.x as f64 * window_scale as f64) as f32).to_radians();
|
* window_scale as f64) as f32)
|
||||||
|
.to_radians();
|
||||||
|
yaw -=
|
||||||
|
((settings.sensitivity * motion.delta.x as f64 * window_scale as f64)
|
||||||
|
as f32)
|
||||||
|
.to_radians();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pitch = pitch.clamp(-1.54, 1.54);
|
pitch = pitch.clamp(-1.54, 1.54);
|
||||||
@ -132,28 +144,53 @@ pub fn follow_cursor_with_camera(
|
|||||||
let right = Vec3::new(local_z.z, camera_transform.translation.y, -local_z.x);
|
let right = Vec3::new(local_z.z, camera_transform.translation.y, -local_z.x);
|
||||||
player_transform.rotation = desired_rotation_quat;
|
player_transform.rotation = desired_rotation_quat;
|
||||||
if keyboard_input.pressed(KeyCode::Q) {
|
if keyboard_input.pressed(KeyCode::Q) {
|
||||||
let final_quat = Quat::from_axis_angle(Vec3::Z, radians_from_degrees(player_values_state.player_lean_angle));
|
let final_quat = Quat::from_axis_angle(
|
||||||
camera_transform.rotation = camera_transform
|
Vec3::Z,
|
||||||
.rotation
|
radians_from_degrees(player_values_state.player_lean_angle),
|
||||||
.lerp(final_quat, time.delta_seconds() / player_values_state.player_lean_time);
|
);
|
||||||
camera_transform.translation = camera_transform.translation.lerp(Vec3 { x: -right.x, y: camera_transform.translation.y, z: -right.z }, time.delta_seconds() / player_values_state.player_lean_time);
|
camera_transform.rotation = camera_transform.rotation.lerp(
|
||||||
|
final_quat,
|
||||||
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
|
camera_transform.translation = camera_transform.translation.lerp(
|
||||||
|
Vec3 {
|
||||||
|
x: -right.x,
|
||||||
|
y: camera_transform.translation.y,
|
||||||
|
z: -right.z,
|
||||||
|
},
|
||||||
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
} else if keyboard_input.pressed(KeyCode::E) {
|
} else if keyboard_input.pressed(KeyCode::E) {
|
||||||
let final_quat =
|
let final_quat = Quat::from_axis_angle(
|
||||||
Quat::from_axis_angle(Vec3::Z, radians_from_degrees(-player_values_state.player_lean_angle));
|
Vec3::Z,
|
||||||
camera_transform.rotation = camera_transform
|
radians_from_degrees(-player_values_state.player_lean_angle),
|
||||||
.rotation
|
);
|
||||||
.lerp(final_quat, time.delta_seconds() / player_values_state.player_lean_time);
|
camera_transform.rotation = camera_transform.rotation.lerp(
|
||||||
camera_transform.translation = camera_transform.translation.lerp(Vec3 { x: right.x, y: camera_transform.translation.y, z: right.z }, time.delta_seconds() / player_values_state.player_lean_time);
|
final_quat,
|
||||||
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
|
camera_transform.translation = camera_transform.translation.lerp(
|
||||||
|
Vec3 {
|
||||||
|
x: right.x,
|
||||||
|
y: camera_transform.translation.y,
|
||||||
|
z: right.z,
|
||||||
|
},
|
||||||
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
camera_transform.rotation = camera_transform
|
camera_transform.rotation = camera_transform.rotation.lerp(
|
||||||
.rotation
|
Quat::default(),
|
||||||
.lerp(Quat::default(), time.delta_seconds() / player_values_state.player_lean_time);
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
|
|
||||||
camera_transform.translation = camera_transform.translation.lerp(Vec3 {
|
camera_transform.translation = camera_transform.translation.lerp(
|
||||||
|
Vec3 {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: camera_transform.translation.y,
|
y: camera_transform.translation.y,
|
||||||
z: 0.0,
|
z: 0.0,
|
||||||
}, time.delta_seconds() / player_values_state.player_lean_time);
|
},
|
||||||
|
time.delta_seconds() / player_values_state.player_lean_time,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,24 @@ use bevy::prelude::*;
|
|||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::{markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}, camera::MainCamera, interactable::Interactable}, events::loot_container::LootContainerEvent},
|
comps::core::{
|
||||||
logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet, firearm::Firearm}, utils::rad_deg::radians_from_degrees, setup::{animations::AllFirearmAnimations, load_state::GameLoadState, equipment::{EquipmentChangeEvent, Equipment}}, ui::game::{settings::SettingsScreenUIConfiguration, hud::hud::HudState},
|
events::loot_container::LootContainerEvent,
|
||||||
|
markers::{
|
||||||
|
camera::MainCamera,
|
||||||
|
firearm::{FirearmData, MagazineData},
|
||||||
|
holdable::InPlayerHands,
|
||||||
|
interactable::Interactable,
|
||||||
|
player::{Player, PlayerHand},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logic::core::guns::{firearm::Firearm, player_firing::PlayerFiringInfo, shoot::shoot_bullet},
|
||||||
|
setup::{
|
||||||
|
animations::AllFirearmAnimations,
|
||||||
|
equipment::{Equipment, EquipmentChangeEvent},
|
||||||
|
load_state::GameLoadState,
|
||||||
|
},
|
||||||
|
ui::game::{hud::hud::HudState, settings::SettingsScreenUIConfiguration},
|
||||||
|
utils::rad_deg::radians_from_degrees,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn capture_hand_usage(
|
pub fn capture_hand_usage(
|
||||||
@ -24,8 +40,7 @@ pub fn capture_hand_usage(
|
|||||||
animation_clips: Res<Assets<AnimationClip>>,
|
animation_clips: Res<Assets<AnimationClip>>,
|
||||||
|
|
||||||
game_load_state: Res<GameLoadState>,
|
game_load_state: Res<GameLoadState>,
|
||||||
#[allow(unused)]
|
#[allow(unused)] mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
|
||||||
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
||||||
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
@ -40,15 +55,16 @@ pub fn capture_hand_usage(
|
|||||||
|
|
||||||
// Equipping stuff
|
// Equipping stuff
|
||||||
|
|
||||||
|
|
||||||
// Equipping gun
|
// Equipping gun
|
||||||
if !settings_screen_config.settings_menu_shown {
|
if !settings_screen_config.settings_menu_shown {
|
||||||
if keyboard_input.just_pressed(KeyCode::Key1) {
|
if keyboard_input.just_pressed(KeyCode::Key1) {
|
||||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::M4A1)));
|
equipment_change_event_writer
|
||||||
|
.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::M4A1)));
|
||||||
} else if keyboard_input.just_pressed(KeyCode::Key2) {
|
} else if keyboard_input.just_pressed(KeyCode::Key2) {
|
||||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::Glock17) ));
|
equipment_change_event_writer
|
||||||
|
.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::Glock17)));
|
||||||
} else if keyboard_input.just_pressed(KeyCode::Key3) {
|
} else if keyboard_input.just_pressed(KeyCode::Key3) {
|
||||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing ));
|
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,11 +75,16 @@ pub fn capture_hand_usage(
|
|||||||
|
|
||||||
for (firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
for (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 animation_player in &mut animation_players {
|
for animation_player in &mut animation_players {
|
||||||
if let Some(firearm_animations) = all_firearm_animations.animations.iter().find(|animation| &animation.firearm == &player_firearm) {
|
if let Some(firearm_animations) = all_firearm_animations
|
||||||
if let Some(animation_clip) = animation_clips.get(&firearm_animations.reload_magazine) {
|
.animations
|
||||||
|
.iter()
|
||||||
|
.find(|animation| &animation.firearm == &player_firearm)
|
||||||
|
{
|
||||||
|
if let Some(animation_clip) =
|
||||||
|
animation_clips.get(&firearm_animations.reload_magazine)
|
||||||
|
{
|
||||||
if animation_player.elapsed() >= animation_clip.duration() {
|
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;
|
||||||
@ -71,12 +92,20 @@ pub fn capture_hand_usage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Player is not in a reload animation
|
} else {
|
||||||
if keyboard_input.just_pressed(KeyCode::R) && !settings_screen_config.settings_menu_shown{
|
// Player is not in a reload animation
|
||||||
|
if keyboard_input.just_pressed(KeyCode::R)
|
||||||
|
&& !settings_screen_config.settings_menu_shown
|
||||||
|
{
|
||||||
// Start reload animation
|
// Start reload animation
|
||||||
for mut animation_player in &mut animation_players {
|
for mut animation_player in &mut animation_players {
|
||||||
if let Some(firearm_animations) = all_firearm_animations.animations.iter().find(|animation| &animation.firearm == &player_firearm) {
|
if let Some(firearm_animations) = all_firearm_animations
|
||||||
animation_player.start(firearm_animations.reload_magazine.clone_weak());
|
.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,29 +113,38 @@ pub fn capture_hand_usage(
|
|||||||
// At the end of reload animation, set magazine data to capacity = 0
|
// At the end of reload animation, set magazine data to capacity = 0
|
||||||
}
|
}
|
||||||
// AIMING IN/OUT
|
// AIMING IN/OUT
|
||||||
if mouse_buttons.pressed(MouseButton::Right) && !settings_screen_config.settings_menu_shown {
|
if mouse_buttons.pressed(MouseButton::Right)
|
||||||
|
&& !settings_screen_config.settings_menu_shown
|
||||||
|
{
|
||||||
let rotation_lerp_quat = hand_transform.rotation.lerp(
|
let rotation_lerp_quat = hand_transform.rotation.lerp(
|
||||||
firearm_data.final_aimed_rotation,
|
firearm_data.final_aimed_rotation,
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
(time.delta_seconds() / firearm_data.rebound_time_seconds)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
);
|
);
|
||||||
let position_lerp_vec3 = hand_transform.translation.lerp(
|
let position_lerp_vec3 = hand_transform.translation.lerp(
|
||||||
firearm_data.final_aimed_position,
|
firearm_data.final_aimed_position,
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
(time.delta_seconds() / firearm_data.rebound_time_seconds)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
);
|
);
|
||||||
hand_transform.rotation = rotation_lerp_quat;
|
hand_transform.rotation = rotation_lerp_quat;
|
||||||
hand_transform.translation = position_lerp_vec3;
|
hand_transform.translation = position_lerp_vec3;
|
||||||
} else {
|
} else {
|
||||||
hand_transform.rotation = hand_transform
|
hand_transform.rotation = hand_transform.rotation.lerp(
|
||||||
.rotation
|
firearm_data.final_rotation,
|
||||||
.lerp(firearm_data.final_rotation, (time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0));
|
(time.delta_seconds() / firearm_data.rebound_time_seconds)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
hand_transform.translation = hand_transform.translation.lerp(
|
hand_transform.translation = hand_transform.translation.lerp(
|
||||||
firearm_data.final_position,
|
firearm_data.final_position,
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
(time.delta_seconds() / firearm_data.rebound_time_seconds)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHOOTING & RECOIL
|
// SHOOTING & RECOIL
|
||||||
if mouse_buttons.pressed(MouseButton::Left) && !settings_screen_config.settings_menu_shown {
|
if mouse_buttons.pressed(MouseButton::Left)
|
||||||
|
&& !settings_screen_config.settings_menu_shown
|
||||||
|
{
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
||||||
// Get recoil numbers from patterns
|
// Get recoil numbers from patterns
|
||||||
@ -129,10 +167,23 @@ pub fn capture_hand_usage(
|
|||||||
|
|
||||||
let firearm_transform = firearm_transform.clone();
|
let firearm_transform = firearm_transform.clone();
|
||||||
// TODO: M4 holdableobject data has a Y ROT of -90. Apply that rotation here if it exists.
|
// TODO: M4 holdableobject data has a Y ROT of -90. Apply that rotation here if it exists.
|
||||||
let firing_point = firearm_transform.translation() + (firearm_transform.forward() * firearm_data.firing_point.forward) + (firearm_transform.up() * firearm_data.firing_point.up) + (firearm_transform.right() * firearm_data.firing_point.right);
|
let firing_point = firearm_transform.translation()
|
||||||
|
+ (firearm_transform.forward()
|
||||||
|
* firearm_data.firing_point.forward)
|
||||||
|
+ (firearm_transform.up() * firearm_data.firing_point.up)
|
||||||
|
+ (firearm_transform.right()
|
||||||
|
* firearm_data.firing_point.right);
|
||||||
let forward = firearm_transform.forward();
|
let forward = firearm_transform.forward();
|
||||||
let up = firearm_transform.up();
|
let up = firearm_transform.up();
|
||||||
shoot_bullet(&mut commands, &mut meshes, &mut materials, Transform::from_translation(firing_point), forward, up, firearm_data.caliber.clone());
|
shoot_bullet(
|
||||||
|
&mut commands,
|
||||||
|
&mut meshes,
|
||||||
|
&mut materials,
|
||||||
|
Transform::from_translation(firing_point),
|
||||||
|
forward,
|
||||||
|
up,
|
||||||
|
firearm_data.caliber.clone(),
|
||||||
|
);
|
||||||
// Increment indexes and timers
|
// Increment indexes and timers
|
||||||
player_firing_info.current_round_index += 1;
|
player_firing_info.current_round_index += 1;
|
||||||
player_firing_info.last_shot_timestamp = time.elapsed_seconds();
|
player_firing_info.last_shot_timestamp = time.elapsed_seconds();
|
||||||
@ -140,13 +191,17 @@ pub fn capture_hand_usage(
|
|||||||
magazine_data.rounds_shot += 1;
|
magazine_data.rounds_shot += 1;
|
||||||
|
|
||||||
// Apply recoil
|
// Apply recoil
|
||||||
hand_transform
|
hand_transform.rotate_x(radians_from_degrees(
|
||||||
.rotate_x(radians_from_degrees(firearm_data.vertical_recoil_modifier * vertical_recoil_number));
|
firearm_data.vertical_recoil_modifier
|
||||||
hand_transform.rotate_y(radians_from_degrees(firearm_data.horizontal_recoil_modifier * horizontal_recoil_number));
|
* vertical_recoil_number,
|
||||||
|
));
|
||||||
|
hand_transform.rotate_y(radians_from_degrees(
|
||||||
|
firearm_data.horizontal_recoil_modifier
|
||||||
|
* horizontal_recoil_number,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
//TODO: play magazine empty sound
|
//TODO: play magazine empty sound
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
@ -154,19 +209,17 @@ pub fn capture_hand_usage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method that is run when player hits interact button.
|
/// Method that is run when player hits interact button.
|
||||||
/// Should raycast where the player is looking and scan for interactable
|
/// Should raycast where the player is looking and scan for interactable
|
||||||
pub fn interact_action(
|
pub fn interact_action(
|
||||||
//mut commands: Commands,
|
//mut commands: Commands,
|
||||||
player_query: Query<&Transform, (With<Player>, Without<MainCamera>)>,
|
player_query: Query<(Entity, &Transform), (With<Player>, Without<MainCamera>)>,
|
||||||
camera_query: Query<&GlobalTransform, (With<MainCamera>, Without<Player>)>,
|
camera_query: Query<&GlobalTransform, (With<MainCamera>, Without<Player>)>,
|
||||||
interactables_query: Query<(Entity, &Interactable)>,
|
interactables_query: Query<(Entity, &Interactable)>,
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
@ -174,7 +227,7 @@ pub fn interact_action(
|
|||||||
mut hud_state: ResMut<HudState>,
|
mut hud_state: ResMut<HudState>,
|
||||||
mut loot_container_event_writer: EventWriter<LootContainerEvent>,
|
mut loot_container_event_writer: EventWriter<LootContainerEvent>,
|
||||||
) {
|
) {
|
||||||
for transform in player_query.iter() {
|
for (player_entity, transform) in player_query.iter() {
|
||||||
for global_transform in camera_query.iter() {
|
for global_transform in camera_query.iter() {
|
||||||
let ray_pos = global_transform.translation();
|
let ray_pos = global_transform.translation();
|
||||||
let ray_dir = transform.forward() * 2.0; // TODO: Move this into global Resource state
|
let ray_dir = transform.forward() * 2.0; // TODO: Move this into global Resource state
|
||||||
@ -182,18 +235,32 @@ pub fn interact_action(
|
|||||||
let solid = true;
|
let solid = true;
|
||||||
|
|
||||||
if let Some((entity, _toi)) = rapier_context.cast_ray(
|
if let Some((entity, _toi)) = rapier_context.cast_ray(
|
||||||
ray_pos, ray_dir, max_toi, solid, QueryFilter::only_fixed()
|
ray_pos,
|
||||||
|
ray_dir,
|
||||||
|
max_toi,
|
||||||
|
solid,
|
||||||
|
QueryFilter::default().exclude_collider(player_entity),
|
||||||
) {
|
) {
|
||||||
for (interactable_entity, interactable) in interactables_query.iter() {
|
for (interactable_entity, interactable) in interactables_query.iter() {
|
||||||
|
println!(
|
||||||
|
"Hit: {:?} == interactable_entity: {:?} interactable: {}",
|
||||||
|
entity, interactable_entity, interactable
|
||||||
|
);
|
||||||
|
//println!("Collided! {}, {}", entity.index(), interactable.to_string());
|
||||||
if interactable_entity == entity {
|
if interactable_entity == entity {
|
||||||
hud_state.interaction_clue_shown = true;
|
hud_state.interaction_clue_shown = true;
|
||||||
if keyboard_input.just_pressed(KeyCode::F) { // TODO: Move this key to Controls state global
|
hud_state.interaction_clue_text = interactable.to_string();
|
||||||
|
println!("{interactable}");
|
||||||
|
if keyboard_input.just_pressed(KeyCode::F) {
|
||||||
|
// TODO: Move this key to Controls state global
|
||||||
println!("Interacted with interactable");
|
println!("Interacted with interactable");
|
||||||
match interactable {
|
match interactable {
|
||||||
Interactable::Holdable => todo!(),
|
Interactable::Holdable => todo!(),
|
||||||
Interactable::Lootable(any_inventory) => loot_container_event_writer.send(LootContainerEvent(any_inventory.clone())),
|
Interactable::Lootable(any_inventory) => {
|
||||||
Interactable::Item => todo!(),
|
loot_container_event_writer
|
||||||
|
.send(LootContainerEvent(any_inventory.clone()))
|
||||||
}
|
}
|
||||||
|
Interactable::Item => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -201,5 +268,6 @@ pub fn interact_action(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
hud_state.interaction_clue_shown = false;
|
hud_state.interaction_clue_shown = false;
|
||||||
}
|
}
|
@ -2,5 +2,5 @@ pub mod camera_effects;
|
|||||||
pub mod camera_player_sync;
|
pub mod camera_player_sync;
|
||||||
pub mod hands;
|
pub mod hands;
|
||||||
pub mod player_movement;
|
pub mod player_movement;
|
||||||
pub mod player_vertical_sync;
|
|
||||||
pub mod player_values_state;
|
pub mod player_values_state;
|
||||||
|
pub mod player_vertical_sync;
|
||||||
|
@ -109,7 +109,7 @@ pub fn move_player(
|
|||||||
With<Player>,
|
With<Player>,
|
||||||
>,
|
>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
player_values_state: Res<PlayerValuesState>
|
player_values_state: Res<PlayerValuesState>,
|
||||||
) {
|
) {
|
||||||
for (
|
for (
|
||||||
mut player_velocity,
|
mut player_velocity,
|
||||||
@ -151,7 +151,7 @@ pub fn move_player(
|
|||||||
player_velocity.linvel,
|
player_velocity.linvel,
|
||||||
time.delta_seconds(),
|
time.delta_seconds(),
|
||||||
sprint_multiplier * crouch_multiplier,
|
sprint_multiplier * crouch_multiplier,
|
||||||
player_values_state.player_acceleration
|
player_values_state.player_acceleration,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if player_movement_input.back {
|
if player_movement_input.back {
|
||||||
@ -164,7 +164,7 @@ pub fn move_player(
|
|||||||
player_velocity.linvel,
|
player_velocity.linvel,
|
||||||
time.delta_seconds(),
|
time.delta_seconds(),
|
||||||
crouch_multiplier,
|
crouch_multiplier,
|
||||||
player_values_state.player_acceleration
|
player_values_state.player_acceleration,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if player_movement_input.right {
|
if player_movement_input.right {
|
||||||
@ -177,11 +177,13 @@ pub fn move_player(
|
|||||||
player_velocity.linvel,
|
player_velocity.linvel,
|
||||||
time.delta_seconds(),
|
time.delta_seconds(),
|
||||||
if player_linear_xz_state.is_sprinting() {
|
if player_linear_xz_state.is_sprinting() {
|
||||||
player_values_state.player_lateral_acceleration_while_sprinting_multiplier * crouch_multiplier
|
player_values_state.player_lateral_acceleration_while_sprinting_multiplier
|
||||||
|
* crouch_multiplier
|
||||||
} else {
|
} else {
|
||||||
player_values_state.player_lateral_acceleration_multiplier * crouch_multiplier
|
player_values_state.player_lateral_acceleration_multiplier
|
||||||
|
* crouch_multiplier
|
||||||
},
|
},
|
||||||
player_values_state.player_acceleration
|
player_values_state.player_acceleration,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if player_movement_input.left {
|
if player_movement_input.left {
|
||||||
@ -194,17 +196,22 @@ pub fn move_player(
|
|||||||
player_velocity.linvel,
|
player_velocity.linvel,
|
||||||
time.delta_seconds(),
|
time.delta_seconds(),
|
||||||
if player_linear_xz_state.is_sprinting() {
|
if player_linear_xz_state.is_sprinting() {
|
||||||
player_values_state.player_lateral_acceleration_while_sprinting_multiplier * crouch_multiplier
|
player_values_state.player_lateral_acceleration_while_sprinting_multiplier
|
||||||
|
* crouch_multiplier
|
||||||
} else {
|
} else {
|
||||||
player_values_state.player_lateral_acceleration_multiplier * crouch_multiplier
|
player_values_state.player_lateral_acceleration_multiplier
|
||||||
|
* crouch_multiplier
|
||||||
},
|
},
|
||||||
player_values_state.player_acceleration
|
player_values_state.player_acceleration,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if player_movement_input.up && player_linear_y_state.is_grounded(&player_values_state.player_jump_cooldown_s) {
|
if player_movement_input.up
|
||||||
player_external_force.impulse = Vec3::new(0.0, player_values_state.player_jump_force, 0.0);
|
&& player_linear_y_state.is_grounded(&player_values_state.player_jump_cooldown_s)
|
||||||
|
{
|
||||||
|
player_external_force.impulse =
|
||||||
|
Vec3::new(0.0, player_values_state.player_jump_force, 0.0);
|
||||||
*player_linear_y_state = PlayerLinearYState::Jumping;
|
*player_linear_y_state = PlayerLinearYState::Jumping;
|
||||||
*player_damping = Damping {
|
*player_damping = Damping {
|
||||||
linear_damping: player_values_state.player_linear_damping_while_jumping,
|
linear_damping: player_values_state.player_linear_damping_while_jumping,
|
||||||
@ -217,10 +224,12 @@ pub fn move_player(
|
|||||||
{
|
{
|
||||||
let positive = player_velocity.linvel.x.is_sign_positive();
|
let positive = player_velocity.linvel.x.is_sign_positive();
|
||||||
if positive {
|
if positive {
|
||||||
player_velocity.linvel.x =
|
player_velocity.linvel.x = player_values_state.max_linear_player_velocity
|
||||||
player_values_state.max_linear_player_velocity * crouch_multiplier * sprint_multiplier
|
* crouch_multiplier
|
||||||
|
* sprint_multiplier
|
||||||
} else {
|
} else {
|
||||||
player_velocity.linvel.x = player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier
|
player_velocity.linvel.x =
|
||||||
|
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if player_velocity.linvel.z.abs()
|
if player_velocity.linvel.z.abs()
|
||||||
@ -228,9 +237,11 @@ pub fn move_player(
|
|||||||
{
|
{
|
||||||
let positive = player_velocity.linvel.z.is_sign_positive();
|
let positive = player_velocity.linvel.z.is_sign_positive();
|
||||||
if positive {
|
if positive {
|
||||||
player_velocity.linvel.z = player_values_state.max_linear_player_velocity * crouch_multiplier
|
player_velocity.linvel.z =
|
||||||
|
player_values_state.max_linear_player_velocity * crouch_multiplier
|
||||||
} else {
|
} else {
|
||||||
player_velocity.linvel.z = player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier
|
player_velocity.linvel.z =
|
||||||
|
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if player_velocity.linvel.x > -1.0
|
if player_velocity.linvel.x > -1.0
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use bevy::{prelude::{Resource, ReflectResource}, reflect::Reflect};
|
use bevy::{
|
||||||
|
prelude::{ReflectResource, Resource},
|
||||||
|
reflect::Reflect,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Resource, Reflect)]
|
#[derive(Resource, Reflect)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
|
@ -9,7 +9,7 @@ use super::{player_movement::PlayerLinearYState, player_values_state::PlayerValu
|
|||||||
pub fn sync_player_y_state(
|
pub fn sync_player_y_state(
|
||||||
mut query: Query<(&Velocity, &mut PlayerLinearYState, &mut Damping), With<Player>>,
|
mut query: Query<(&Velocity, &mut PlayerLinearYState, &mut Damping), With<Player>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
player_values_state: Res<PlayerValuesState>
|
player_values_state: Res<PlayerValuesState>,
|
||||||
) {
|
) {
|
||||||
for (player_velocity, mut player_linear_y_state, mut player_damping) in &mut query {
|
for (player_velocity, mut player_linear_y_state, mut player_damping) in &mut query {
|
||||||
if player_velocity.linvel.y < -1.0 {
|
if player_velocity.linvel.y < -1.0 {
|
||||||
@ -26,7 +26,8 @@ pub fn sync_player_y_state(
|
|||||||
let new_grounded_time = previous_grounded_time + time.delta().as_secs_f64();
|
let new_grounded_time = previous_grounded_time + time.delta().as_secs_f64();
|
||||||
*player_linear_y_state = PlayerLinearYState::Grounded(new_grounded_time);
|
*player_linear_y_state = PlayerLinearYState::Grounded(new_grounded_time);
|
||||||
if new_grounded_time
|
if new_grounded_time
|
||||||
> player_values_state.player_jump_cooldown_s - player_values_state.player_linear_damping_time_offset_after_jump_in_s
|
> player_values_state.player_jump_cooldown_s
|
||||||
|
- player_values_state.player_linear_damping_time_offset_after_jump_in_s
|
||||||
{
|
{
|
||||||
*player_damping = Damping {
|
*player_damping = Damping {
|
||||||
linear_damping: player_values_state.player_linear_damping,
|
linear_damping: player_values_state.player_linear_damping,
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
use scenes::scene1;
|
use scenes::scene1;
|
||||||
use ui::{game::plugin::MainGameUIPlugin, editor::plugin::MainEditorUiPlugin};
|
use ui::{editor::plugin::MainEditorUiPlugin, game::plugin::MainGameUIPlugin};
|
||||||
|
|
||||||
mod comps;
|
mod comps;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod logic;
|
mod logic;
|
||||||
mod scenes;
|
mod scenes;
|
||||||
mod setup;
|
mod setup;
|
||||||
mod utils;
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut application = App::new();
|
let mut application = App::new();
|
||||||
|
@ -7,11 +7,11 @@ pub fn spawn_ground(
|
|||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::cuboid(50.0, 0.1, 50.0), Name::new("Ground")))
|
.spawn((Collider::cuboid(100.0, 0.1, 100.0), Name::new("Ground")))
|
||||||
.insert(TransformBundle::from(Transform::from_xyz(0.0, -2.0, 0.0)))
|
.insert(TransformBundle::from(Transform::from_xyz(0.0, -2.0, 0.0)))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
|
mesh: meshes.add(shape::Plane::from_size(200.0).into()),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::WHITE,
|
base_color: Color::WHITE,
|
||||||
perceptual_roughness: 1.0,
|
perceptual_roughness: 1.0,
|
||||||
|
@ -2,17 +2,30 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::controller::capture_input,
|
comps::core::controller::capture_input,
|
||||||
logic::core::{player::{
|
logic::core::{
|
||||||
|
guns::despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets},
|
||||||
|
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, interact_action},
|
hands::{capture_hand_usage, interact_action},
|
||||||
player_vertical_sync::sync_player_y_state, player_values_state::PlayerValuesState,
|
player_values_state::PlayerValuesState,
|
||||||
}, guns::despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets}}, setup::{assets::load_all_assets, load_state::GameLoadState, spawn::add_all_spawners, animations::{load_animations, AllFirearmAnimations}, equipment::{EquipmentChangeEvent, change_equipment}, spawners::player::player_spawner},
|
player_vertical_sync::sync_player_y_state,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup::{
|
||||||
|
animations::{load_animations, AllFirearmAnimations},
|
||||||
|
assets::load_all_assets,
|
||||||
|
equipment::{change_equipment, EquipmentChangeEvent},
|
||||||
|
load_state::GameLoadState,
|
||||||
|
spawn::add_all_spawners,
|
||||||
|
spawners::player::player_spawner,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ground::spawn_ground, lighting::setup_lighting, obstacles::spawn_obstacles, skybox::set_skybox_if_loaded, spawn_points::set_spawn_points,
|
ground::spawn_ground, items::spawn_items, lighting::setup_lighting, obstacles::spawn_obstacles,
|
||||||
|
skybox::set_skybox_if_loaded, spawn_points::set_spawn_points,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn load_scene(application: &mut App) {
|
pub fn load_scene(application: &mut App) {
|
||||||
@ -23,7 +36,10 @@ pub fn load_scene(application: &mut App) {
|
|||||||
// 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, spawn_items.after(load_all_assets)),
|
||||||
|
);
|
||||||
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);
|
||||||
// Update
|
// Update
|
||||||
|
16
src/scenes/scene1/items.rs
Normal file
16
src/scenes/scene1/items.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
comps::core::items::{guns::m4a1::M4a1GunItem, item::Item},
|
||||||
|
setup::assets::GltfAssets,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn spawn_items(
|
||||||
|
mut commands: Commands,
|
||||||
|
assets_gltf: Res<GltfAssets>,
|
||||||
|
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||||
|
) {
|
||||||
|
let transform = Transform::from_xyz(20.0, 1.0, 10.0);
|
||||||
|
let m4item = M4a1GunItem;
|
||||||
|
m4item.spawn(&mut commands, transform, &assets_gltf, &loaded_gltf_assets);
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
pub fn setup_lighting(mut commands: Commands) {
|
pub fn setup_lighting(mut commands: Commands) {
|
||||||
commands.spawn((SpotLightBundle {
|
commands.spawn((
|
||||||
|
SpotLightBundle {
|
||||||
spot_light: SpotLight {
|
spot_light: SpotLight {
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
intensity: 3000.0,
|
intensity: 3000.0,
|
||||||
@ -12,5 +13,7 @@ pub fn setup_lighting(mut commands: Commands) {
|
|||||||
transform: Transform::from_xyz(20.0, 20.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
|
transform: Transform::from_xyz(20.0, 20.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
visibility: Visibility::Visible,
|
visibility: Visibility::Visible,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("LightSource")));
|
},
|
||||||
|
Name::new("LightSource"),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
pub mod init;
|
pub mod init;
|
||||||
|
|
||||||
pub mod ground;
|
pub mod ground;
|
||||||
|
pub mod items;
|
||||||
pub mod lighting;
|
pub mod lighting;
|
||||||
pub mod obstacles;
|
pub mod obstacles;
|
||||||
pub mod skybox;
|
pub mod skybox;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
use crate::comps::core::{markers::interactable::Interactable, grid::UGrid, inventory::any_inventory::AnyInventory};
|
use crate::comps::core::{
|
||||||
|
grid::UGrid, inventory::any_inventory::AnyInventory, markers::interactable::Interactable,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn spawn_obstacles(
|
pub fn spawn_obstacles(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
@ -15,7 +17,10 @@ pub fn spawn_obstacles(
|
|||||||
let box_4_mesh = shape::Box::new(3.0, 7.0, 3.0).into();
|
let box_4_mesh = shape::Box::new(3.0, 7.0, 3.0).into();
|
||||||
let box_5_mesh = shape::Box::new(2.0, 2.0, 2.0).into();
|
let box_5_mesh = shape::Box::new(2.0, 2.0, 2.0).into();
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::from_bevy_mesh(&box_1_mesh, &Default::default()).unwrap(), Name::new("Obstacle 1")))
|
.spawn((
|
||||||
|
Collider::from_bevy_mesh(&box_1_mesh, &Default::default()).unwrap(),
|
||||||
|
Name::new("Obstacle 1"),
|
||||||
|
))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(box_1_mesh.into()),
|
mesh: meshes.add(box_1_mesh.into()),
|
||||||
@ -29,7 +34,10 @@ pub fn spawn_obstacles(
|
|||||||
});
|
});
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::from_bevy_mesh(&box_2_mesh, &Default::default()).unwrap(), Name::new("Obstacle 2")))
|
.spawn((
|
||||||
|
Collider::from_bevy_mesh(&box_2_mesh, &Default::default()).unwrap(),
|
||||||
|
Name::new("Obstacle 2"),
|
||||||
|
))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(box_2_mesh.into()),
|
mesh: meshes.add(box_2_mesh.into()),
|
||||||
@ -43,7 +51,10 @@ pub fn spawn_obstacles(
|
|||||||
});
|
});
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::from_bevy_mesh(&box_3_mesh, &Default::default()).unwrap(), Name::new("Obstacle 3")))
|
.spawn((
|
||||||
|
Collider::from_bevy_mesh(&box_3_mesh, &Default::default()).unwrap(),
|
||||||
|
Name::new("Obstacle 3"),
|
||||||
|
))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(box_3_mesh.into()),
|
mesh: meshes.add(box_3_mesh.into()),
|
||||||
@ -57,7 +68,10 @@ pub fn spawn_obstacles(
|
|||||||
});
|
});
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::from_bevy_mesh(&box_4_mesh, &Default::default()).unwrap(), Name::new("Obstacle 4")))
|
.spawn((
|
||||||
|
Collider::from_bevy_mesh(&box_4_mesh, &Default::default()).unwrap(),
|
||||||
|
Name::new("Obstacle 4"),
|
||||||
|
))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(box_4_mesh.into()),
|
mesh: meshes.add(box_4_mesh.into()),
|
||||||
@ -72,7 +86,10 @@ pub fn spawn_obstacles(
|
|||||||
|
|
||||||
// CRATE
|
// CRATE
|
||||||
commands
|
commands
|
||||||
.spawn((Collider::from_bevy_mesh(&box_5_mesh, &Default::default()).unwrap(), Name::new("Crate")))
|
.spawn((
|
||||||
|
Collider::from_bevy_mesh(&box_5_mesh, &Default::default()).unwrap(),
|
||||||
|
Name::new("Crate"),
|
||||||
|
))
|
||||||
.insert(RigidBody::Fixed)
|
.insert(RigidBody::Fixed)
|
||||||
.insert(PbrBundle {
|
.insert(PbrBundle {
|
||||||
mesh: meshes.add(box_5_mesh.into()),
|
mesh: meshes.add(box_5_mesh.into()),
|
||||||
@ -84,7 +101,7 @@ pub fn spawn_obstacles(
|
|||||||
transform: Transform::from_xyz(20.0, 2.0, 20.0),
|
transform: Transform::from_xyz(20.0, 2.0, 20.0),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.insert(
|
.insert(Interactable::Lootable(AnyInventory::new(
|
||||||
Interactable::Lootable(AnyInventory::new(UGrid::new_square(10)))
|
UGrid::new_square(10),
|
||||||
);
|
)));
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ pub fn set_skybox_if_loaded(
|
|||||||
mut cubemap: ResMut<Cubemap>,
|
mut cubemap: ResMut<Cubemap>,
|
||||||
mut camera_query: Query<Entity, With<MainCamera>>,
|
mut camera_query: Query<Entity, With<MainCamera>>,
|
||||||
) {
|
) {
|
||||||
if !cubemap.is_loaded && asset_server.get_load_state(&cubemap.image_handle) == Some(LoadState::Loaded)
|
if !cubemap.is_loaded
|
||||||
|
&& asset_server.get_load_state(&cubemap.image_handle) == Some(LoadState::Loaded)
|
||||||
{
|
{
|
||||||
let image = images.get_mut(&cubemap.image_handle).unwrap();
|
let image = images.get_mut(&cubemap.image_handle).unwrap();
|
||||||
// NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
|
// NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
|
||||||
@ -43,7 +44,9 @@ pub fn set_skybox_if_loaded(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for camera_entity in camera_query.iter_mut() {
|
for camera_entity in camera_query.iter_mut() {
|
||||||
commands.entity(camera_entity).insert(Skybox(cubemap.image_handle.clone()));
|
commands
|
||||||
|
.entity(camera_entity)
|
||||||
|
.insert(Skybox(cubemap.image_handle.clone()));
|
||||||
cubemap.is_loaded = true;
|
cubemap.is_loaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{setup::spawn::SpawnPoint, comps::core::markers::player::{Player, PlayerData}};
|
use crate::{
|
||||||
|
comps::core::{
|
||||||
|
items::guns::m4a1::M4a1GunItem,
|
||||||
|
markers::player::{Player, PlayerData},
|
||||||
|
},
|
||||||
|
setup::spawn::SpawnPoint,
|
||||||
|
};
|
||||||
|
|
||||||
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(PlayerData::default()) });
|
commands.spawn(SpawnPoint {
|
||||||
|
at: Transform::from_xyz(3.0, 5.0, 2.0),
|
||||||
|
what: Player(PlayerData::default()),
|
||||||
|
});
|
||||||
|
commands.spawn(SpawnPoint {
|
||||||
|
at: Transform::from_xyz(20.0, 10.0, 10.0),
|
||||||
|
what: M4a1GunItem,
|
||||||
|
});
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use bevy::{prelude::*, gltf::Gltf};
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
|
||||||
use crate::logic::core::guns::firearm::Firearm;
|
use crate::logic::core::guns::firearm::Firearm;
|
||||||
|
|
||||||
@ -14,7 +14,6 @@ pub struct AllFirearmAnimations {
|
|||||||
pub struct FirearmAnimations {
|
pub struct FirearmAnimations {
|
||||||
pub firearm: Firearm,
|
pub firearm: Firearm,
|
||||||
pub reload_magazine: Handle<AnimationClip>,
|
pub reload_magazine: Handle<AnimationClip>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// System to load animations once the Gltf file is loaded.
|
/// System to load animations once the Gltf file is loaded.
|
||||||
@ -31,13 +30,18 @@ pub fn load_animations(
|
|||||||
if assets_gltf.assets.len() != loaded_gltf_assets.len() {
|
if assets_gltf.assets.len() != loaded_gltf_assets.len() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut all_firearm_animations = AllFirearmAnimations { animations: Vec::new() };
|
let mut all_firearm_animations = AllFirearmAnimations {
|
||||||
|
animations: Vec::new(),
|
||||||
|
};
|
||||||
for gltf_asset in assets_gltf.assets.iter() {
|
for gltf_asset in assets_gltf.assets.iter() {
|
||||||
if gltf_asset.asset_type.is_firearm() {
|
if gltf_asset.asset_type.is_firearm() {
|
||||||
if let Some(loaded_gltf) = loaded_gltf_assets.get(&gltf_asset.asset) {
|
if let Some(loaded_gltf) = loaded_gltf_assets.get(&gltf_asset.asset) {
|
||||||
// Needs to have all firearm animations
|
// Needs to have all firearm animations
|
||||||
let reload_animation = &loaded_gltf.animations[0];
|
let reload_animation = &loaded_gltf.animations[0];
|
||||||
all_firearm_animations.animations.push(FirearmAnimations { firearm: gltf_asset.asset_type.get_firearm().clone(), reload_magazine: reload_animation.clone() })
|
all_firearm_animations.animations.push(FirearmAnimations {
|
||||||
|
firearm: gltf_asset.asset_type.get_firearm().clone(),
|
||||||
|
reload_magazine: reload_animation.clone(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use bevy::{prelude::*, gltf::Gltf};
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
|
||||||
use crate::{logic::core::guns::firearm::Firearm, scenes::scene1::skybox::{CUBEMAPS, Cubemap}};
|
use crate::{
|
||||||
|
logic::core::guns::firearm::Firearm,
|
||||||
|
scenes::scene1::skybox::{Cubemap, CUBEMAPS},
|
||||||
|
};
|
||||||
|
|
||||||
use super::load_state::GameLoadState;
|
use super::load_state::GameLoadState;
|
||||||
|
|
||||||
@ -10,18 +13,19 @@ pub enum GltfAssetType {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
Enemy,
|
Enemy,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Reflect, Default)]
|
#[derive(Resource, Reflect, Default)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
pub struct GltfAssets {
|
pub struct GltfAssets {
|
||||||
pub assets: Vec<GltfAsset>
|
pub assets: Vec<GltfAsset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Reflect)]
|
#[derive(Reflect)]
|
||||||
pub struct GltfAsset {
|
pub struct GltfAsset {
|
||||||
pub asset_type: GltfAssetType,
|
pub asset_type: GltfAssetType,
|
||||||
pub asset: Handle<Gltf>,
|
pub asset: Handle<Gltf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn load_all_assets(
|
pub fn load_all_assets(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
@ -32,13 +36,16 @@ pub fn load_all_assets(
|
|||||||
is_loaded: false,
|
is_loaded: false,
|
||||||
image_handle: skybox_handle,
|
image_handle: skybox_handle,
|
||||||
});
|
});
|
||||||
let m4a1_gltf_asset = GltfAsset { asset_type: GltfAssetType::Firearm(Firearm::M4A1), asset: asset_server.load(Firearm::M4A1.firearm_data().asset_path) } ;
|
let m4a1_gltf_asset = GltfAsset {
|
||||||
let glock17_gltf_asset = GltfAsset { asset_type: GltfAssetType::Firearm(Firearm::Glock17), asset: asset_server.load(Firearm::Glock17.firearm_data().asset_path) };
|
asset_type: GltfAssetType::Firearm(Firearm::M4A1),
|
||||||
|
asset: asset_server.load(Firearm::M4A1.firearm_data().asset_path),
|
||||||
|
};
|
||||||
|
let glock17_gltf_asset = GltfAsset {
|
||||||
|
asset_type: GltfAssetType::Firearm(Firearm::Glock17),
|
||||||
|
asset: asset_server.load(Firearm::Glock17.firearm_data().asset_path),
|
||||||
|
};
|
||||||
commands.insert_resource(GltfAssets {
|
commands.insert_resource(GltfAssets {
|
||||||
assets: Vec::from([
|
assets: Vec::from([m4a1_gltf_asset, glock17_gltf_asset]),
|
||||||
m4a1_gltf_asset,
|
|
||||||
glock17_gltf_asset
|
|
||||||
])
|
|
||||||
});
|
});
|
||||||
game_load_state.assets_loaded = true;
|
game_load_state.assets_loaded = true;
|
||||||
// This works becaue this system is called on startup, so commands will finish running when game starts the update phase.
|
// This works becaue this system is called on startup, so commands will finish running when game starts the update phase.
|
||||||
@ -49,7 +56,7 @@ impl GltfAssetType {
|
|||||||
pub fn is_firearm(&self) -> bool {
|
pub fn is_firearm(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
GltfAssetType::Firearm(_) => true,
|
GltfAssetType::Firearm(_) => true,
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_firearm(&self) -> &Firearm {
|
pub fn get_firearm(&self) -> &Firearm {
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{prelude::*, gltf::Gltf};
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
|
||||||
use crate::{logic::core::guns::{firearm::Firearm, player_firing::PlayerFiringInfo}, comps::core::markers::{player::{Player, PlayerHand}, firearm::{MagazineData, FirearmData}, holdable::InPlayerHands}, utils};
|
use crate::{
|
||||||
|
comps::core::markers::{
|
||||||
|
firearm::{FirearmData, MagazineData},
|
||||||
|
holdable::InPlayerHands,
|
||||||
|
player::{Player, PlayerHand},
|
||||||
|
},
|
||||||
|
logic::core::guns::{firearm::Firearm, player_firing::PlayerFiringInfo},
|
||||||
|
utils,
|
||||||
|
};
|
||||||
|
|
||||||
use super::assets::{GltfAssets, GltfAssetType};
|
use super::assets::{GltfAssetType, GltfAssets};
|
||||||
|
|
||||||
#[derive(Event)]
|
#[derive(Event)]
|
||||||
pub struct EquipmentChangeEvent(pub Equipment);
|
pub struct EquipmentChangeEvent(pub Equipment);
|
||||||
@ -29,22 +37,27 @@ pub fn change_equipment(
|
|||||||
for equipment_change_event in equipment_change_event_reader.read() {
|
for equipment_change_event in equipment_change_event_reader.read() {
|
||||||
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
|
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
|
||||||
return;
|
return;
|
||||||
} ;
|
};
|
||||||
// Primary firearm change
|
// Primary firearm change
|
||||||
if equipment_change_event.0 != player.0.equipment {
|
if equipment_change_event.0 != player.0.equipment {
|
||||||
|
|
||||||
let player_hands = player_hands_query.single_mut();
|
let player_hands = player_hands_query.single_mut();
|
||||||
|
|
||||||
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
||||||
if let Equipment::Firearm(new_firearm) = equipment_change_event.0.clone() {
|
if let Equipment::Firearm(new_firearm) = equipment_change_event.0.clone() {
|
||||||
spawn_firearm_on_player_hands(&mut commands, player_firing_info, player_hands, &assets_gltf, &loaded_gltf_assets, new_firearm);
|
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
|
// Set the player's equipment to the newly spawned equipment
|
||||||
player.0.equipment = equipment_change_event.0.clone();
|
player.0.equipment = equipment_change_event.0.clone();
|
||||||
println!("Equipment change done");
|
println!("Equipment change done");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +69,11 @@ fn spawn_firearm_on_player_hands(
|
|||||||
loaded_gltf_assets: &Assets<Gltf>,
|
loaded_gltf_assets: &Assets<Gltf>,
|
||||||
firearm: Firearm,
|
firearm: Firearm,
|
||||||
) {
|
) {
|
||||||
if let Some(asset_handle) = assets_gltf.assets.iter().find(|asset| asset.asset_type == GltfAssetType::Firearm(firearm.clone())) {
|
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) {
|
if let Some(gltf) = loaded_gltf_assets.get(&asset_handle.asset) {
|
||||||
let firearm_data: FirearmData = firearm.firearm_data();
|
let firearm_data: FirearmData = firearm.firearm_data();
|
||||||
let mut firearm_transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
let mut firearm_transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
||||||
@ -67,17 +84,25 @@ fn spawn_firearm_on_player_hands(
|
|||||||
firearm_transform.scale = firearm_transform.scale * firearm_data.scale_factor;
|
firearm_transform.scale = firearm_transform.scale * firearm_data.scale_factor;
|
||||||
|
|
||||||
let scene = gltf.scenes[0].clone();
|
let scene = gltf.scenes[0].clone();
|
||||||
let firearm_asset_entity = commands.spawn((SceneBundle {
|
let firearm_asset_entity = commands
|
||||||
|
.spawn((
|
||||||
|
SceneBundle {
|
||||||
scene,
|
scene,
|
||||||
visibility: Visibility::Inherited,
|
visibility: Visibility::Inherited,
|
||||||
transform: firearm_transform,
|
transform: firearm_transform,
|
||||||
..default()
|
..default()
|
||||||
}, Name::new("Firearm Gltf Asset"))).id();
|
},
|
||||||
|
Name::new("Firearm Gltf Asset"),
|
||||||
|
))
|
||||||
|
.id();
|
||||||
let firearm_entity = commands
|
let firearm_entity = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
firearm_data.clone(),
|
firearm_data.clone(),
|
||||||
firearm.holdable_object_data(),
|
firearm.holdable_object_data(),
|
||||||
MagazineData { rounds_shot: 0, max_capacity: firearm_data.max_capacity },
|
MagazineData {
|
||||||
|
rounds_shot: 0,
|
||||||
|
max_capacity: firearm_data.max_capacity,
|
||||||
|
},
|
||||||
InPlayerHands,
|
InPlayerHands,
|
||||||
Name::new("Firearm"),
|
Name::new("Firearm"),
|
||||||
TransformBundle {
|
TransformBundle {
|
||||||
@ -88,14 +113,15 @@ fn spawn_firearm_on_player_hands(
|
|||||||
visibility: Visibility::Inherited,
|
visibility: Visibility::Inherited,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)).push_children(&[firearm_asset_entity])
|
))
|
||||||
|
.push_children(&[firearm_asset_entity])
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
commands.entity(player_hands).push_children(&[firearm_entity]);
|
commands
|
||||||
|
.entity(player_hands)
|
||||||
|
.push_children(&[firearm_entity]);
|
||||||
|
|
||||||
|
let time_in_secs_between_each_round = 1.0 / firearm_data.fire_rate * 60.0;
|
||||||
let time_in_secs_between_each_round =
|
|
||||||
1.0 / firearm_data.fire_rate * 60.0;
|
|
||||||
player_firing_info.full_auto_timer = Timer::new(
|
player_firing_info.full_auto_timer = Timer::new(
|
||||||
Duration::from_secs_f32(time_in_secs_between_each_round),
|
Duration::from_secs_f32(time_in_secs_between_each_round),
|
||||||
TimerMode::Once,
|
TimerMode::Once,
|
||||||
|
@ -10,7 +10,6 @@ pub struct GameLoadState {
|
|||||||
|
|
||||||
impl GameLoadState {
|
impl GameLoadState {
|
||||||
pub fn is_everything_except_player_loaded(&self) -> bool {
|
pub fn is_everything_except_player_loaded(&self) -> bool {
|
||||||
self.assets_loaded &&
|
self.assets_loaded && self.animations_loaded
|
||||||
self.animations_loaded
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
pub mod assets;
|
|
||||||
pub mod animations;
|
pub mod animations;
|
||||||
|
pub mod assets;
|
||||||
|
pub mod equipment;
|
||||||
pub mod load_state;
|
pub mod load_state;
|
||||||
pub mod spawn;
|
pub mod spawn;
|
||||||
pub mod spawners;
|
pub mod spawners;
|
||||||
pub mod equipment;
|
|
@ -1,14 +1,22 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use super::{spawners::{player::player_spawner, firearm::firearm_spawner}, equipment::change_equipment};
|
use crate::comps::core::items::{guns::m4a1::M4a1GunItem, item::Item};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
equipment::change_equipment,
|
||||||
|
spawners::{item::item_spawner, player::player_spawner},
|
||||||
|
};
|
||||||
|
|
||||||
/// Where some Bundle T will replace this.
|
/// Where some Bundle T will replace this.
|
||||||
#[derive(Component, Reflect)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct SpawnPoint<T: Bundle> {
|
pub struct SpawnPoint<T: Bundle> {
|
||||||
pub at: Transform,
|
pub at: Transform,
|
||||||
pub what: T
|
pub what: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_all_spawners(application: &mut App) {
|
pub fn add_all_spawners(application: &mut App) {
|
||||||
application.add_systems(Update, (player_spawner, firearm_spawner).after(change_equipment));
|
application.add_systems(
|
||||||
|
Update,
|
||||||
|
(player_spawner, item_spawner::<M4a1GunItem>).after(change_equipment),
|
||||||
|
);
|
||||||
}
|
}
|
@ -1,12 +0,0 @@
|
|||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
use crate::{logic::core::guns::firearm::Firearm, setup::{spawn::SpawnPoint, load_state::GameLoadState}};
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn firearm_spawner(
|
|
||||||
mut commands: Commands,
|
|
||||||
firearm_sp_query: Query<(Entity, &SpawnPoint<Firearm>)>,
|
|
||||||
mut game_load_state: ResMut<GameLoadState>,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
22
src/setup/spawners/item.rs
Normal file
22
src/setup/spawners/item.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
comps::core::items::{guns::m4a1::M4a1GunItem, item::Item},
|
||||||
|
setup::{assets::GltfAssets, load_state::GameLoadState, spawn::SpawnPoint},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn item_spawner<T: Item>(
|
||||||
|
mut commands: Commands,
|
||||||
|
item_sp_query: Query<(Entity, &SpawnPoint<T>)>,
|
||||||
|
game_load_state: ResMut<GameLoadState>,
|
||||||
|
assets_gltf: Res<GltfAssets>,
|
||||||
|
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||||
|
) {
|
||||||
|
if game_load_state.is_everything_except_player_loaded() {
|
||||||
|
for (entity, item_sp) in item_sp_query.iter() {
|
||||||
|
let m4 = M4a1GunItem;
|
||||||
|
m4.spawn(&mut commands, item_sp.at, &assets_gltf, &loaded_gltf_assets);
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,2 @@
|
|||||||
|
pub mod item;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
pub mod firearm;
|
|
@ -4,9 +4,16 @@ use bevy_rapier3d::prelude::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
comps::core::markers::{
|
comps::core::markers::{
|
||||||
camera::MainCamera,
|
camera::MainCamera,
|
||||||
player::{Player, PlayerHand, PlayerData},
|
player::{Player, PlayerData, PlayerHand},
|
||||||
},
|
},
|
||||||
logic::core::{player::{player_movement::{PlayerLinearYState, PlayerLinearXZState}, player_values_state::PlayerValuesState}, guns::player_firing::PlayerFiringInfo}, setup::{load_state::GameLoadState, equipment::EquipmentChangeEvent},
|
logic::core::{
|
||||||
|
guns::player_firing::PlayerFiringInfo,
|
||||||
|
player::{
|
||||||
|
player_movement::{PlayerLinearXZState, PlayerLinearYState},
|
||||||
|
player_values_state::PlayerValuesState,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup::{equipment::EquipmentChangeEvent, load_state::GameLoadState},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::setup::spawn::SpawnPoint;
|
use crate::setup::spawn::SpawnPoint;
|
||||||
@ -28,7 +35,9 @@ pub fn player_spawner(
|
|||||||
// Spawn hand
|
// Spawn hand
|
||||||
let player_hand = commands
|
let player_hand = commands
|
||||||
.spawn((PlayerHand, Name::new("Player Hand")))
|
.spawn((PlayerHand, Name::new("Player Hand")))
|
||||||
.insert(TransformBundle::from(Transform::from_xyz(0.6, -0.45, -20.0)))
|
.insert(TransformBundle::from(Transform::from_xyz(
|
||||||
|
0.6, -0.45, -20.0,
|
||||||
|
)))
|
||||||
.insert(VisibilityBundle {
|
.insert(VisibilityBundle {
|
||||||
visibility: Visibility::Inherited,
|
visibility: Visibility::Inherited,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -76,7 +85,9 @@ pub fn player_spawner(
|
|||||||
| LockedAxes::ROTATION_LOCKED_X
|
| LockedAxes::ROTATION_LOCKED_X
|
||||||
| LockedAxes::ROTATION_LOCKED_Y,
|
| LockedAxes::ROTATION_LOCKED_Y,
|
||||||
)
|
)
|
||||||
.insert(ColliderMassProperties::Mass(player_values_state.player_initial_weight))
|
.insert(ColliderMassProperties::Mass(
|
||||||
|
player_values_state.player_initial_weight,
|
||||||
|
))
|
||||||
.insert(ExternalImpulse {
|
.insert(ExternalImpulse {
|
||||||
impulse: Vec3::ZERO,
|
impulse: Vec3::ZERO,
|
||||||
torque_impulse: Vec3::ZERO,
|
torque_impulse: Vec3::ZERO,
|
||||||
@ -94,7 +105,9 @@ pub fn player_spawner(
|
|||||||
.push_children(&[camera]);
|
.push_children(&[camera]);
|
||||||
|
|
||||||
game_load_state.player_loaded = true;
|
game_load_state.player_loaded = true;
|
||||||
equipment_change_event_writer.send(EquipmentChangeEvent(player_spawn_point.what.0.equipment.clone()));
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
use bevy::{prelude::*, window::PrimaryWindow};
|
use bevy::{prelude::*, window::PrimaryWindow};
|
||||||
use bevy_editor_pls::{controls::{self, EditorControls}, default_windows::cameras::EditorCamera};
|
use bevy_editor_pls::{
|
||||||
use bevy_inspector_egui::{egui, bevy_egui::EguiContext, bevy_inspector};
|
controls::{self, EditorControls},
|
||||||
|
default_windows::cameras::EditorCamera,
|
||||||
|
};
|
||||||
|
use bevy_inspector_egui::{bevy_egui::EguiContext, bevy_inspector, egui};
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn inspector_ui(world: &mut World) {
|
pub fn inspector_ui(world: &mut World) {
|
||||||
@ -9,10 +12,8 @@ pub fn inspector_ui(world: &mut World) {
|
|||||||
.single(world)
|
.single(world)
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
egui::Window::new("World")
|
egui::Window::new("World").show(egui_context.get_mut(), |ui| {
|
||||||
.show(egui_context.get_mut(), |ui| {
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
egui::ScrollArea::vertical()
|
|
||||||
.show(ui, |ui| {
|
|
||||||
bevy_inspector::ui_for_world(world, ui);
|
bevy_inspector::ui_for_world(world, ui);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -33,7 +34,9 @@ pub fn editor_controls() -> EditorControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cam3d_controls(
|
pub fn set_cam3d_controls(
|
||||||
mut query: Query<&mut bevy_editor_pls::default_windows::cameras::camera_3d_free::FlycamControls>,
|
mut query: Query<
|
||||||
|
&mut bevy_editor_pls::default_windows::cameras::camera_3d_free::FlycamControls,
|
||||||
|
>,
|
||||||
mut query_camera_transforms: Query<&mut Transform, With<EditorCamera>>,
|
mut query_camera_transforms: Query<&mut Transform, With<EditorCamera>>,
|
||||||
) {
|
) {
|
||||||
for mut controls in query.iter_mut() {
|
for mut controls in query.iter_mut() {
|
||||||
@ -45,7 +48,11 @@ pub fn set_cam3d_controls(
|
|||||||
}
|
}
|
||||||
// TODO: run this after the position update already in the editor plugin
|
// TODO: run this after the position update already in the editor plugin
|
||||||
for mut transform in query_camera_transforms.iter_mut() {
|
for mut transform in query_camera_transforms.iter_mut() {
|
||||||
transform.translation = Vec3 { x: 6.5, y: 28.0, z: 41.6 };
|
transform.translation = Vec3 {
|
||||||
|
x: 6.5,
|
||||||
|
y: 28.0,
|
||||||
|
z: 41.6,
|
||||||
|
};
|
||||||
transform.look_at(Vec3::ZERO, Vec3::Y);
|
transform.look_at(Vec3::ZERO, Vec3::Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//! Editor UI means everything that won't be in the actual game
|
//! Editor UI means everything that won't be in the actual game
|
||||||
pub mod plugin;
|
|
||||||
pub mod inspector;
|
pub mod inspector;
|
||||||
|
pub mod plugin;
|
||||||
/*
|
/*
|
||||||
pub mod panels;
|
pub mod panels;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
@ -2,7 +2,31 @@ use bevy::prelude::*;
|
|||||||
use bevy_editor_pls::EditorPlugin;
|
use bevy_editor_pls::EditorPlugin;
|
||||||
use bevy_inspector_egui::bevy_egui::EguiPlugin;
|
use bevy_inspector_egui::bevy_egui::EguiPlugin;
|
||||||
|
|
||||||
use crate::{logic::core::{guns::{player_firing::PlayerFiringInfo, caliber::Caliber, firearm::Firearm, spray_pattern::FirearmSprayPattern}, player::{player_values_state::PlayerValuesState, camera_player_sync::MouseMovementSettings, player_movement::{PlayerLinearYState, PlayerLinearXZState, PlayerMovementInput}}}, comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::{HoldableObjectData, InPlayerHands}, player::{PlayerData, Player, PlayerHand}}, scenes::scene1::skybox::Cubemap, setup::{animations::{AllFirearmAnimations, FirearmAnimations}, assets::{GltfAssetType, GltfAssets}, equipment::Equipment, load_state::GameLoadState}};
|
use crate::{
|
||||||
|
comps::core::markers::{
|
||||||
|
firearm::{FirearmData, MagazineData},
|
||||||
|
holdable::{HoldableObjectData, InPlayerHands},
|
||||||
|
player::{Player, PlayerData, PlayerHand},
|
||||||
|
},
|
||||||
|
logic::core::{
|
||||||
|
guns::{
|
||||||
|
caliber::Caliber, firearm::Firearm, player_firing::PlayerFiringInfo,
|
||||||
|
spray_pattern::FirearmSprayPattern,
|
||||||
|
},
|
||||||
|
player::{
|
||||||
|
camera_player_sync::MouseMovementSettings,
|
||||||
|
player_movement::{PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput},
|
||||||
|
player_values_state::PlayerValuesState,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scenes::scene1::skybox::Cubemap,
|
||||||
|
setup::{
|
||||||
|
animations::{AllFirearmAnimations, FirearmAnimations},
|
||||||
|
assets::{GltfAssetType, GltfAssets},
|
||||||
|
equipment::Equipment,
|
||||||
|
load_state::GameLoadState,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
use super::inspector::{editor_controls, set_cam3d_controls};
|
use super::inspector::{editor_controls, set_cam3d_controls};
|
||||||
|
|
||||||
@ -14,8 +38,7 @@ pub struct MainEditorUiPlugin;
|
|||||||
|
|
||||||
impl Plugin for MainEditorUiPlugin {
|
impl Plugin for MainEditorUiPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app
|
app.register_type::<PlayerFiringInfo>()
|
||||||
.register_type::<PlayerFiringInfo>()
|
|
||||||
.register_type::<PlayerValuesState>()
|
.register_type::<PlayerValuesState>()
|
||||||
.register_type::<FirearmData>()
|
.register_type::<FirearmData>()
|
||||||
.register_type::<MagazineData>()
|
.register_type::<MagazineData>()
|
||||||
|
@ -9,15 +9,26 @@ pub struct FpsCounterMarker {
|
|||||||
}
|
}
|
||||||
impl FpsCounterMarker {
|
impl FpsCounterMarker {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { timer: Timer::new(Duration::from_secs_f32(0.5), TimerMode::Repeating), frames_elapsed: 0, }
|
Self {
|
||||||
|
timer: Timer::new(Duration::from_secs_f32(0.5), TimerMode::Repeating),
|
||||||
|
frames_elapsed: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_fps_counter(mut commands: Commands, ) {
|
pub fn setup_fps_counter(mut commands: Commands) {
|
||||||
commands.spawn((TextBundle {
|
commands
|
||||||
text: Text::from_section("FPS: 0.0", TextStyle {
|
.spawn((
|
||||||
font_size: 18.0, color: Color::GREEN, ..Default::default()
|
TextBundle {
|
||||||
}).with_alignment(TextAlignment::Center),
|
text: Text::from_section(
|
||||||
|
"FPS: 0.0",
|
||||||
|
TextStyle {
|
||||||
|
font_size: 18.0,
|
||||||
|
color: Color::GREEN,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with_alignment(TextAlignment::Center),
|
||||||
style: Style {
|
style: Style {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
right: Val::Px(10.0),
|
right: Val::Px(10.0),
|
||||||
@ -25,7 +36,9 @@ pub fn setup_fps_counter(mut commands: Commands, ) {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Fps Counter")))
|
},
|
||||||
|
Name::new("Fps Counter"),
|
||||||
|
))
|
||||||
.insert(FpsCounterMarker::new());
|
.insert(FpsCounterMarker::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,5 +4,5 @@ use bevy::prelude::*;
|
|||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
pub struct HudState {
|
pub struct HudState {
|
||||||
pub interaction_clue_shown: bool,
|
pub interaction_clue_shown: bool,
|
||||||
|
pub interaction_clue_text: String,
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use bevy::{prelude::*, ui::FocusPolicy};
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::ui::game::settings::SettingsScreenUIConfiguration;
|
use crate::ui::game::settings::SettingsScreenUIConfiguration;
|
||||||
|
|
||||||
@ -9,51 +9,51 @@ pub struct InteractClueHudMarker;
|
|||||||
|
|
||||||
pub fn setup_interact_clue(mut commands: Commands) {
|
pub fn setup_interact_clue(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
NodeBundle {
|
TextBundle {
|
||||||
style: Style {
|
text: Text::from_section(
|
||||||
display: Display::Flex,
|
"Interact",
|
||||||
width: Val::Percent(100.0),
|
TextStyle {
|
||||||
height: Val::Percent(100.0),
|
font_size: 12.0,
|
||||||
justify_content: JustifyContent::Center,
|
color: Color::WHITE,
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
visibility: Visibility::Hidden,
|
)
|
||||||
background_color: BackgroundColor(Color::NONE),
|
.with_alignment(TextAlignment::Center),
|
||||||
focus_policy: FocusPolicy::Pass,
|
style: Style {
|
||||||
|
position_type: PositionType::Absolute,
|
||||||
|
top: Val::Percent(50.0),
|
||||||
|
left: Val::Percent(50.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Interaction Clue Background"),
|
},
|
||||||
InteractClueHudMarker)
|
visibility: Visibility::Visible,
|
||||||
).with_children(|parent| {
|
|
||||||
parent.spawn((TextBundle {
|
|
||||||
text: Text::from_section("Loot", TextStyle {
|
|
||||||
font_size: 12.0, color: Color::WHITE, ..Default::default()
|
|
||||||
}).with_alignment(TextAlignment::Center),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Interaction Clue text"),
|
},
|
||||||
|
Name::new("Interaction Clue text"),
|
||||||
|
InteractClueHudMarker,
|
||||||
));
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_interact_clue(
|
pub fn update_interact_clue(
|
||||||
//mut commands: Commands,
|
//mut commands: Commands,
|
||||||
interact_clue: Res<HudState>,
|
interact_clue: Res<HudState>,
|
||||||
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
||||||
mut query: Query<&mut Visibility, With<InteractClueHudMarker>>
|
mut query: Query<(&mut Visibility, &mut Text), With<InteractClueHudMarker>>,
|
||||||
) {
|
) {
|
||||||
if !settings_screen_config.is_changed() && !interact_clue.is_changed() {
|
if !settings_screen_config.is_changed() && !interact_clue.is_changed() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for mut vis in query.iter_mut() {
|
for (mut vis, mut text) in query.iter_mut() {
|
||||||
if settings_screen_config.settings_menu_shown {
|
if settings_screen_config.settings_menu_shown {
|
||||||
*vis = Visibility::Hidden;
|
*vis = Visibility::Hidden;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if interact_clue.interaction_clue_shown {
|
if interact_clue.interaction_clue_shown {
|
||||||
*vis = Visibility::Visible;
|
*vis = Visibility::Visible;
|
||||||
|
if let Some(section) = text.sections.first_mut() {
|
||||||
|
section.value = interact_clue.interaction_clue_text.clone();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*vis = Visibility::Hidden;
|
*vis = Visibility::Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
|
pub mod hud;
|
||||||
pub mod interact_clue;
|
pub mod interact_clue;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
pub mod hud;
|
|
@ -4,7 +4,6 @@ use crate::ui::game::hud::hud::HudState;
|
|||||||
|
|
||||||
use super::interact_clue::{setup_interact_clue, update_interact_clue};
|
use super::interact_clue::{setup_interact_clue, update_interact_clue};
|
||||||
|
|
||||||
|
|
||||||
pub struct HudOverlayPlugin;
|
pub struct HudOverlayPlugin;
|
||||||
|
|
||||||
impl Plugin for HudOverlayPlugin {
|
impl Plugin for HudOverlayPlugin {
|
||||||
|
@ -2,15 +2,9 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::comps::core::events::loot_container::LootContainerEvent;
|
use crate::comps::core::events::loot_container::LootContainerEvent;
|
||||||
|
|
||||||
|
|
||||||
/// # Inventory Screen
|
/// # Inventory Screen
|
||||||
/// Should contain player inventory and if player is looting something as well
|
/// Should contain player inventory and if player is looting something as well
|
||||||
pub fn setup_inventory_screen(
|
pub fn setup_inventory_screen(mut commands: Commands) {}
|
||||||
mut commands: Commands,
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_inventory_screen(
|
pub fn update_inventory_screen(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
@ -4,7 +4,6 @@ use crate::comps::core::events::loot_container::LootContainerEvent;
|
|||||||
|
|
||||||
use super::menu::{setup_inventory_screen, update_inventory_screen};
|
use super::menu::{setup_inventory_screen, update_inventory_screen};
|
||||||
|
|
||||||
|
|
||||||
pub struct InventoryMenuPlugin;
|
pub struct InventoryMenuPlugin;
|
||||||
|
|
||||||
impl Plugin for InventoryMenuPlugin {
|
impl Plugin for InventoryMenuPlugin {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Game UI means all the UI that will be part of the actual game
|
//! Game UI means all the UI that will be part of the actual game
|
||||||
pub mod plugin;
|
|
||||||
pub mod fps_counter;
|
pub mod fps_counter;
|
||||||
|
pub mod hud;
|
||||||
|
pub mod inventory;
|
||||||
|
pub mod plugin;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod settings_screen;
|
pub mod settings_screen;
|
||||||
pub mod inventory;
|
|
||||||
pub mod hud;
|
|
@ -2,7 +2,9 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::ui::game::settings::GameConfiguration;
|
use crate::ui::game::settings::GameConfiguration;
|
||||||
|
|
||||||
use super::{fps_counter, settings_screen, settings::SettingsScreenUIConfiguration, inventory, hud};
|
use super::{
|
||||||
|
fps_counter, hud, inventory, settings::SettingsScreenUIConfiguration, settings_screen,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct MainGameUIPlugin;
|
pub struct MainGameUIPlugin;
|
||||||
|
|
||||||
@ -12,15 +14,21 @@ impl Plugin for MainGameUIPlugin {
|
|||||||
app.add_plugins(inventory::plugin::InventoryMenuPlugin);
|
app.add_plugins(inventory::plugin::InventoryMenuPlugin);
|
||||||
app.insert_resource(GameConfiguration::default());
|
app.insert_resource(GameConfiguration::default());
|
||||||
app.insert_resource(SettingsScreenUIConfiguration::default());
|
app.insert_resource(SettingsScreenUIConfiguration::default());
|
||||||
app.add_systems(Startup, (
|
app.add_systems(
|
||||||
|
Startup,
|
||||||
|
(
|
||||||
settings_screen::setup_settings_screen,
|
settings_screen::setup_settings_screen,
|
||||||
fps_counter::setup_fps_counter,
|
fps_counter::setup_fps_counter,
|
||||||
inventory::menu::setup_inventory_screen,
|
inventory::menu::setup_inventory_screen,
|
||||||
));
|
),
|
||||||
app.add_systems(Update, (
|
);
|
||||||
|
app.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
settings_screen::toggle_settings_screen,
|
settings_screen::toggle_settings_screen,
|
||||||
settings_screen::handle_settings_button_click,
|
settings_screen::handle_settings_button_click,
|
||||||
fps_counter::tick_fps_counter,
|
fps_counter::tick_fps_counter,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,9 @@ pub struct SettingsScreenUIConfiguration {
|
|||||||
|
|
||||||
impl Default for SettingsScreenUIConfiguration {
|
impl Default for SettingsScreenUIConfiguration {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { settings_menu_shown: false }
|
Self {
|
||||||
|
settings_menu_shown: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +18,6 @@ impl Default for SettingsScreenUIConfiguration {
|
|||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
pub struct GameConfiguration {
|
pub struct GameConfiguration {
|
||||||
pub fps_counter_enabled: bool,
|
pub fps_counter_enabled: bool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GameConfiguration {
|
impl Default for GameConfiguration {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use bevy::{prelude::*, ui::FocusPolicy, app::AppExit};
|
use bevy::{app::AppExit, prelude::*, ui::FocusPolicy};
|
||||||
|
|
||||||
use super::settings::SettingsScreenUIConfiguration;
|
use super::settings::SettingsScreenUIConfiguration;
|
||||||
|
|
||||||
@ -12,7 +12,8 @@ pub enum SettingsScreenActions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_settings_screen(mut commands: Commands) {
|
pub fn setup_settings_screen(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands
|
||||||
|
.spawn((
|
||||||
NodeBundle {
|
NodeBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
display: Display::Flex,
|
display: Display::Flex,
|
||||||
@ -27,12 +28,14 @@ pub fn setup_settings_screen(mut commands: Commands) {
|
|||||||
background_color: BackgroundColor(Color::rgba(0.0, 0.0, 0.0, 0.9)),
|
background_color: BackgroundColor(Color::rgba(0.0, 0.0, 0.0, 0.9)),
|
||||||
focus_policy: FocusPolicy::Block,
|
focus_policy: FocusPolicy::Block,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Settings Menu"))
|
},
|
||||||
)
|
Name::new("Settings Menu"),
|
||||||
|
))
|
||||||
.insert(SettingsScreenMarker)
|
.insert(SettingsScreenMarker)
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
// RESUME BUTTON
|
// RESUME BUTTON
|
||||||
parent.spawn((
|
parent
|
||||||
|
.spawn((
|
||||||
ButtonBundle {
|
ButtonBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -40,17 +43,27 @@ pub fn setup_settings_screen(mut commands: Commands) {
|
|||||||
background_color: BackgroundColor(Color::NONE),
|
background_color: BackgroundColor(Color::NONE),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Name::new("Resume Button")
|
Name::new("Resume Button"),
|
||||||
))
|
))
|
||||||
.insert(SettingsScreenActions::Resume)
|
.insert(SettingsScreenActions::Resume)
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((TextBundle {
|
parent.spawn((
|
||||||
text: Text::from_section("Resume", TextStyle { font_size: 32.0, ..Default::default() }),
|
TextBundle {
|
||||||
|
text: Text::from_section(
|
||||||
|
"Resume",
|
||||||
|
TextStyle {
|
||||||
|
font_size: 32.0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Resume Button Text")));
|
},
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Name::new("Resume Button Text"),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
// QUIT BUTTON
|
// QUIT BUTTON
|
||||||
parent.spawn((
|
parent
|
||||||
|
.spawn((
|
||||||
ButtonBundle {
|
ButtonBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -59,14 +72,23 @@ pub fn setup_settings_screen(mut commands: Commands) {
|
|||||||
//focus_policy: FocusPolicy::Block,
|
//focus_policy: FocusPolicy::Block,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Name::new("Quit Button")
|
Name::new("Quit Button"),
|
||||||
))
|
))
|
||||||
.insert(SettingsScreenActions::Quit)
|
.insert(SettingsScreenActions::Quit)
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((TextBundle {
|
parent.spawn((
|
||||||
text: Text::from_section("Quit", TextStyle { font_size: 32.0, ..Default::default() }),
|
TextBundle {
|
||||||
|
text: Text::from_section(
|
||||||
|
"Quit",
|
||||||
|
TextStyle {
|
||||||
|
font_size: 32.0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}, Name::new("Quit Button text")));
|
},
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Name::new("Quit Button text"),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
// END BUTTONS
|
// END BUTTONS
|
||||||
});
|
});
|
||||||
@ -77,7 +99,9 @@ pub fn toggle_settings_screen(
|
|||||||
mut settings_screen_query: Query<(&mut Visibility, &mut Style), With<SettingsScreenMarker>>,
|
mut settings_screen_query: Query<(&mut Visibility, &mut Style), With<SettingsScreenMarker>>,
|
||||||
) {
|
) {
|
||||||
if settings.is_changed() {
|
if settings.is_changed() {
|
||||||
for (mut settings_screen_visibility, mut settings_screen_style) in settings_screen_query.iter_mut() {
|
for (mut settings_screen_visibility, mut settings_screen_style) in
|
||||||
|
settings_screen_query.iter_mut()
|
||||||
|
{
|
||||||
if settings.settings_menu_shown {
|
if settings.settings_menu_shown {
|
||||||
*settings_screen_visibility = Visibility::Visible;
|
*settings_screen_visibility = Visibility::Visible;
|
||||||
settings_screen_style.display = Display::Flex;
|
settings_screen_style.display = Display::Flex;
|
||||||
@ -102,14 +126,14 @@ pub fn handle_settings_button_click(
|
|||||||
SettingsScreenActions::Quit => {
|
SettingsScreenActions::Quit => {
|
||||||
// QUIT GAME
|
// QUIT GAME
|
||||||
exit.send(AppExit);
|
exit.send(AppExit);
|
||||||
},
|
}
|
||||||
SettingsScreenActions::Resume => {
|
SettingsScreenActions::Resume => {
|
||||||
// RESUME GAME
|
// RESUME GAME
|
||||||
settings.settings_menu_shown = false;
|
settings.settings_menu_shown = false;
|
||||||
mouse_buttons.release(MouseButton::Left);
|
mouse_buttons.release(MouseButton::Left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
pub mod game;
|
|
||||||
pub mod editor;
|
pub mod editor;
|
||||||
|
pub mod game;
|
||||||
|
Loading…
Reference in New Issue
Block a user