Interactable hud bug fixes
This commit is contained in:
parent
bc90efbbc4
commit
8afa56d306
@ -1,9 +1,15 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{logic::core::player::{player_movement::{
|
||||
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
|
||||
}, player_values_state::PlayerValuesState}, ui::game::settings::SettingsScreenUIConfiguration};
|
||||
use crate::{
|
||||
logic::core::player::{
|
||||
player_movement::{
|
||||
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
|
||||
},
|
||||
player_values_state::PlayerValuesState,
|
||||
},
|
||||
ui::game::settings::SettingsScreenUIConfiguration,
|
||||
};
|
||||
|
||||
use super::markers::player::Player;
|
||||
|
||||
@ -23,7 +29,7 @@ pub fn capture_input(
|
||||
>,
|
||||
time: Res<Time>,
|
||||
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.
|
||||
if keyboard_input.any_pressed([
|
||||
@ -51,9 +57,19 @@ pub fn capture_input(
|
||||
sprint: keyboard_input.pressed(KeyCode::ShiftLeft),
|
||||
};
|
||||
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 {
|
||||
move_player(player_movement_input, player_query, time, player_values_state);
|
||||
move_player(
|
||||
player_movement_input,
|
||||
player_query,
|
||||
time,
|
||||
player_values_state,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ use bevy::prelude::*;
|
||||
use crate::comps::core::inventory::any_inventory::AnyInventory;
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct LootContainerEvent(pub AnyInventory);
|
||||
pub struct LootContainerEvent(pub AnyInventory);
|
||||
|
@ -1,2 +1,2 @@
|
||||
pub mod loot_container;
|
||||
pub mod pickup_item;
|
||||
pub mod pickup_item;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct PickupItemEvent();
|
||||
pub struct PickupItemEvent();
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UGrid {
|
||||
pub width: u32,
|
||||
@ -8,7 +7,10 @@ pub struct UGrid {
|
||||
impl UGrid {
|
||||
/// Creates a ugrid with width = size and height = size
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 crate::comps::core::{items::item::Item, grid::UGrid};
|
||||
use crate::comps::core::{grid::UGrid, items::item::Item};
|
||||
|
||||
use super::inventory_item::InventoryItem;
|
||||
|
||||
@ -8,19 +8,18 @@ use super::inventory_item::InventoryItem;
|
||||
#[derive(Clone)]
|
||||
pub struct AnyInventory {
|
||||
size: UGrid,
|
||||
items: Vec<InventoryItem>
|
||||
items: Vec<InventoryItem>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl AnyInventory {
|
||||
pub fn new(size: UGrid) -> Self {
|
||||
Self { size, items: Vec::new() }
|
||||
Self {
|
||||
size,
|
||||
items: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn add_item_at(
|
||||
&mut self,
|
||||
position: UGrid,
|
||||
item: impl Item<Storage = SparseStorage>,
|
||||
) {
|
||||
pub fn add_item_at(&mut self, position: UGrid, item: impl Item<Storage = SparseStorage>) {
|
||||
// Is Item bigger than inventory?
|
||||
// Does position + item size exceed bounds?
|
||||
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);
|
||||
for inventory_item in self.items.iter() {
|
||||
if inventory_item.is_in_range(&spots_to_occupy) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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 mut spots = Vec::new();
|
||||
for pos_width in position.width..end_position.width {
|
||||
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
|
||||
@ -61,4 +66,4 @@ impl AnyInventory {
|
||||
let item_bounds = position + item.inventory_size();
|
||||
!(item_bounds.width > self.size.width || item_bounds.height > self.size.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ use bevy::ecs::component::SparseStorage;
|
||||
|
||||
use crate::comps::core::{grid::UGrid, items::item::Item};
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InventoryItem {
|
||||
item: Arc<dyn Item<Storage = SparseStorage>>,
|
||||
@ -21,21 +20,22 @@ impl InventoryItem {
|
||||
pub fn rotated(&self) -> Option<bool> {
|
||||
self.rotated
|
||||
}
|
||||
pub fn new(
|
||||
item: impl Item<Storage = SparseStorage>,
|
||||
occupied_spots: Vec<UGrid>,
|
||||
) -> Self {
|
||||
pub fn new(item: impl Item<Storage = SparseStorage>, occupied_spots: Vec<UGrid>) -> Self {
|
||||
let size = item.inventory_size();
|
||||
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
|
||||
pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool {
|
||||
for occupied_spot in self.occupied_spots.iter() {
|
||||
if spots_to_occupy.contains(occupied_spot) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use bevy::{prelude::*, ecs::component::SparseStorage};
|
||||
use bevy::{ecs::component::SparseStorage, prelude::*};
|
||||
|
||||
use crate::comps::core::items::item::Item;
|
||||
|
||||
@ -9,4 +9,4 @@ use crate::comps::core::items::item::Item;
|
||||
#[derive(Component, Clone, Default)]
|
||||
pub struct ItemInventory {
|
||||
pub item: Option<Arc<dyn Item<Storage = SparseStorage>>>,
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub mod any_inventory;
|
||||
pub mod inventory_item;
|
||||
pub mod item_inventory;
|
||||
pub mod player_inventory;
|
||||
pub mod player_inventory;
|
||||
|
@ -2,7 +2,7 @@ use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::grid::UGrid;
|
||||
|
||||
use super::{item_inventory::ItemInventory, any_inventory::AnyInventory};
|
||||
use super::{any_inventory::AnyInventory, item_inventory::ItemInventory};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct PlayerInventory {
|
||||
@ -13,6 +13,10 @@ pub struct PlayerInventory {
|
||||
|
||||
impl Default for PlayerInventory {
|
||||
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,16 +1,22 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::grid::UGrid;
|
||||
|
||||
use crate::{
|
||||
comps::core::{
|
||||
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)]
|
||||
pub enum ItemType {
|
||||
Holdable,
|
||||
Holdable(HoldableObjectType),
|
||||
Equippable,
|
||||
Consumable,
|
||||
}
|
||||
|
||||
pub trait Item: Component {
|
||||
pub trait Item: Component {
|
||||
fn get_type(&self) -> ItemType;
|
||||
fn asset_path(&self) -> &str;
|
||||
/// Optional Stackable. If value is Some(x) x is the max quantity per stack
|
||||
@ -18,4 +24,72 @@ pub trait Item: Component {
|
||||
fn inventory_size(&self) -> UGrid;
|
||||
fn inventory_rotatable(&self) -> bool;
|
||||
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 item;
|
||||
pub mod guns;
|
||||
pub mod item;
|
||||
|
@ -1,11 +1,14 @@
|
||||
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;
|
||||
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct BulletMarker {
|
||||
pub caliber: Caliber,
|
||||
pub starting_point: Vec3,
|
||||
pub timer: Timer,
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
@ -46,4 +49,4 @@ pub struct FirearmData {
|
||||
pub struct MagazineData {
|
||||
pub rounds_shot: usize,
|
||||
pub max_capacity: usize,
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::logic::core::guns::firearm::Firearm;
|
||||
|
||||
/// Anything that can go in the player's hands.
|
||||
#[derive(Component, Default, Debug, Reflect)]
|
||||
pub struct HoldableObjectData {
|
||||
@ -11,3 +13,8 @@ pub struct HoldableObjectData {
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct InPlayerHands;
|
||||
|
||||
#[derive(Reflect)]
|
||||
pub enum HoldableObjectType {
|
||||
Firearm(Firearm),
|
||||
}
|
||||
|
@ -20,4 +20,4 @@ impl Display for Interactable {
|
||||
Interactable::Item => write!(f, "Item"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod bullet;
|
||||
pub mod camera;
|
||||
pub mod firearm;
|
||||
pub mod holdable;
|
||||
pub mod player;
|
||||
pub mod interactable;
|
||||
pub mod muzzle_flash;
|
||||
pub mod bullet;
|
||||
pub mod interactable;
|
||||
pub mod player;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use bevy::{prelude::Component, time::Timer};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct MuzzleFlashMarker(pub Timer);
|
||||
pub struct MuzzleFlashMarker(pub Timer);
|
||||
|
@ -10,4 +10,4 @@ pub struct PlayerData {
|
||||
pub struct Player(pub PlayerData);
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct PlayerHand;
|
||||
pub struct PlayerHand;
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub mod controller;
|
||||
pub mod markers;
|
||||
pub mod grid;
|
||||
pub mod events;
|
||||
pub mod grid;
|
||||
pub mod inventory;
|
||||
pub mod items;
|
||||
pub mod items;
|
||||
pub mod markers;
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -49,4 +49,4 @@ impl Caliber {
|
||||
Caliber::Parabellum9mm => 0.05,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
use crate::comps::core::markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker};
|
||||
use bevy::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() {
|
||||
muzzle_flash.0.tick(time.delta());
|
||||
if muzzle_flash.0.finished() {
|
||||
@ -26,28 +30,41 @@ pub fn despawn_stray_bullets(
|
||||
for event in collisions_read.iter() {
|
||||
match event {
|
||||
CollisionEvent::Started(entity_a, entity_b, _) => {
|
||||
if entity_a == entity_b { // Avoid inner collisions
|
||||
if entity_a == entity_b {
|
||||
// Avoid inner collisions
|
||||
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).insert(Sensor);
|
||||
spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
|
||||
}
|
||||
},
|
||||
CollisionEvent::Stopped(entity_a, entity_b, _) => {
|
||||
if entity_a == entity_b { // Avoid inner collisions
|
||||
continue;
|
||||
}
|
||||
if entity_a == &bullet_entity || entity_b == &bullet_entity{
|
||||
commands.entity(bullet_entity).insert(Collider::ball(bullet.caliber.size()));
|
||||
//commands.entity(bullet_entity).remove::<Sensor>();
|
||||
//commands.entity(*entity_b).despawn();
|
||||
spawn_bullet_exit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
|
||||
continue;
|
||||
spawn_bullet_hit_marker(
|
||||
&mut commands,
|
||||
transform.translation,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
);
|
||||
}
|
||||
}
|
||||
//_ => {}
|
||||
CollisionEvent::Stopped(entity_a, entity_b, _) => {
|
||||
if entity_a == entity_b {
|
||||
// Avoid inner collisions
|
||||
continue;
|
||||
}
|
||||
if entity_a == &bullet_entity || entity_b == &bullet_entity {
|
||||
commands
|
||||
.entity(bullet_entity)
|
||||
.insert(Collider::ball(bullet.caliber.size()));
|
||||
//commands.entity(bullet_entity).remove::<Sensor>();
|
||||
//commands.entity(*entity_b).despawn();
|
||||
spawn_bullet_exit_marker(
|
||||
&mut commands,
|
||||
transform.translation,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
} //_ => {}
|
||||
}
|
||||
}
|
||||
if bullet.timer.finished() {
|
||||
@ -65,27 +82,27 @@ fn spawn_bullet_hit_marker(
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands.spawn(
|
||||
(
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere { radius: 0.05, sectors: 36, stacks: 18 }.into()
|
||||
)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::GREEN,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::GREEN,
|
||||
..Default::default()
|
||||
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: Transform::from_translation(at),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
);
|
||||
commands.spawn((MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere {
|
||||
radius: 0.05,
|
||||
sectors: 36,
|
||||
stacks: 18,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::GREEN,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::GREEN,
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: Transform::from_translation(at),
|
||||
..Default::default()
|
||||
},));
|
||||
}
|
||||
|
||||
fn spawn_bullet_exit_marker(
|
||||
@ -94,25 +111,25 @@ fn spawn_bullet_exit_marker(
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands.spawn(
|
||||
(
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere { radius: 0.05, sectors: 36, stacks: 18 }.into()
|
||||
)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::RED,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::RED,
|
||||
..Default::default()
|
||||
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: Transform::from_translation(at),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
commands.spawn((MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere {
|
||||
radius: 0.05,
|
||||
sectors: 36,
|
||||
stacks: 18,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::RED,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::RED,
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: Transform::from_translation(at),
|
||||
..Default::default()
|
||||
},));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct SpawnFirearmEvent();
|
||||
pub struct SpawnFirearmEvent();
|
||||
|
@ -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 super::{caliber::Caliber, spray_pattern::FirearmSprayPattern};
|
||||
@ -27,13 +30,13 @@ impl Firearm {
|
||||
horizontal_recoil_modifier: 0.5,
|
||||
recoil_pattern: FirearmSprayPattern {
|
||||
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([
|
||||
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
|
||||
]),
|
||||
},
|
||||
|
||||
|
||||
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
||||
final_rotation: Quat::default(),
|
||||
final_aimed_position: Vec3 {
|
||||
@ -52,7 +55,7 @@ impl Firearm {
|
||||
scale_factor: 1.0,
|
||||
asset_path: String::from("weapons/m4a1_rifle.glb"),
|
||||
}
|
||||
},
|
||||
}
|
||||
Firearm::Glock17 => {
|
||||
FirearmData {
|
||||
firing_point: FiringPoint {
|
||||
@ -68,13 +71,13 @@ impl Firearm {
|
||||
horizontal_recoil_modifier: 1.0,
|
||||
recoil_pattern: FirearmSprayPattern {
|
||||
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([
|
||||
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
|
||||
]),
|
||||
},
|
||||
|
||||
|
||||
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
||||
final_rotation: Quat::default(),
|
||||
final_aimed_position: Vec3 {
|
||||
@ -93,7 +96,7 @@ impl Firearm {
|
||||
scale_factor: 0.25,
|
||||
asset_path: String::from("weapons/glock_17_pistol.glb"),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn holdable_object_data(&self) -> HoldableObjectData {
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod caliber;
|
||||
pub mod despawn_shots;
|
||||
pub mod equip_firearm;
|
||||
pub mod firearm;
|
||||
pub mod player_firing;
|
||||
pub mod spray_pattern;
|
||||
pub mod equip_firearm;
|
||||
pub mod shoot;
|
||||
pub mod despawn_shots;
|
||||
pub mod spray_pattern;
|
||||
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
||||
use bevy::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;
|
||||
|
||||
@ -14,14 +14,19 @@ pub fn shoot_bullet(
|
||||
firing_point: Transform,
|
||||
forward: Vec3,
|
||||
up: Vec3,
|
||||
caliber: Caliber
|
||||
caliber: Caliber,
|
||||
) {
|
||||
// Spawn muzzle flash LIGHT
|
||||
commands.spawn(
|
||||
(PointLightBundle {
|
||||
commands.spawn((
|
||||
PointLightBundle {
|
||||
point_light: PointLight {
|
||||
//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,
|
||||
range: 50.0,
|
||||
shadows_enabled: true,
|
||||
@ -30,8 +35,9 @@ pub fn shoot_bullet(
|
||||
transform: firing_point,
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
}, MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)))
|
||||
);
|
||||
},
|
||||
MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)),
|
||||
));
|
||||
// Spawn Line
|
||||
/*commands.spawn(
|
||||
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(
|
||||
@ -60,45 +74,56 @@ pub fn spawn_bullet(
|
||||
firing_point: Transform,
|
||||
forward: Vec3,
|
||||
_up: Vec3,
|
||||
caliber: Caliber
|
||||
caliber: Caliber,
|
||||
) {
|
||||
commands.spawn(
|
||||
(
|
||||
Name::new("Bullet"),
|
||||
BulletMarker {
|
||||
caliber: caliber.clone(),
|
||||
starting_point: firing_point.translation,
|
||||
timer: Timer::new(Duration::from_secs_f32(caliber.max_airtime_secs()), TimerMode::Once)
|
||||
commands.spawn((
|
||||
Name::new("Bullet"),
|
||||
BulletMarker {
|
||||
caliber: caliber.clone(),
|
||||
starting_point: firing_point.translation,
|
||||
timer: Timer::new(
|
||||
Duration::from_secs_f32(caliber.max_airtime_secs()),
|
||||
TimerMode::Once,
|
||||
),
|
||||
},
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere {
|
||||
radius: caliber.size(),
|
||||
sectors: 36,
|
||||
stacks: 18,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
meshes.add(
|
||||
shape::UVSphere { radius: caliber.size(), sectors: 36, stacks: 18 }.into()
|
||||
)
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::Rgba {
|
||||
red: 253.,
|
||||
green: 207.,
|
||||
blue: 88.,
|
||||
alpha: 1.0,
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::Rgba { red: 253., green: 207., blue: 88., alpha: 1.0 },
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: firing_point,
|
||||
..Default::default()
|
||||
},
|
||||
RigidBody::Dynamic,
|
||||
GravityScale(4.0),
|
||||
Collider::ball(caliber.size()),
|
||||
Velocity::zero(),
|
||||
Damping {
|
||||
linear_damping: caliber.linear_damping(),
|
||||
angular_damping: caliber.angular_damping(),
|
||||
},
|
||||
ColliderMassProperties::Mass(caliber.mass()),
|
||||
ExternalImpulse {
|
||||
impulse: forward * caliber.impulse(),
|
||||
torque_impulse: Vec3::ZERO,
|
||||
},
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
Ccd::enabled()
|
||||
)
|
||||
);
|
||||
}
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: firing_point,
|
||||
..Default::default()
|
||||
},
|
||||
RigidBody::Dynamic,
|
||||
GravityScale(4.0),
|
||||
Collider::ball(caliber.size()),
|
||||
Velocity::zero(),
|
||||
Damping {
|
||||
linear_damping: caliber.linear_damping(),
|
||||
angular_damping: caliber.angular_damping(),
|
||||
},
|
||||
ColliderMassProperties::Mass(caliber.mass()),
|
||||
ExternalImpulse {
|
||||
impulse: forward * caliber.impulse(),
|
||||
torque_impulse: Vec3::ZERO,
|
||||
},
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
Ccd::enabled(),
|
||||
));
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
use bevy::reflect::Reflect;
|
||||
|
||||
|
||||
|
||||
#[derive(Clone, Reflect)]
|
||||
pub struct FirearmSprayPattern {
|
||||
pub vertical: Vec<f32>,
|
||||
|
@ -1,2 +1,2 @@
|
||||
pub mod guns;
|
||||
pub mod player;
|
||||
pub mod player;
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -3,7 +3,8 @@ use bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode};
|
||||
|
||||
use crate::{
|
||||
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};
|
||||
@ -80,11 +81,13 @@ pub fn follow_cursor_with_camera(
|
||||
) {
|
||||
if let Ok(mut window) = primary_window.get_single_mut() {
|
||||
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;
|
||||
window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place
|
||||
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;
|
||||
window.cursor.grab_mode = CursorGrabMode::None; // Release cursor
|
||||
window.cursor.visible = true; // Show cursor
|
||||
@ -112,14 +115,23 @@ pub fn follow_cursor_with_camera(
|
||||
for motion in motions.read() {
|
||||
let window_scale = window.height().min(window.width());
|
||||
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();
|
||||
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();
|
||||
} else {
|
||||
pitch -=
|
||||
((settings.sensitivity * motion.delta.y as f64 * 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 -= ((settings.sensitivity
|
||||
* motion.delta.y as f64
|
||||
* 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);
|
||||
@ -132,28 +144,53 @@ pub fn follow_cursor_with_camera(
|
||||
let right = Vec3::new(local_z.z, camera_transform.translation.y, -local_z.x);
|
||||
player_transform.rotation = desired_rotation_quat;
|
||||
if keyboard_input.pressed(KeyCode::Q) {
|
||||
let final_quat = Quat::from_axis_angle(Vec3::Z, radians_from_degrees(player_values_state.player_lean_angle));
|
||||
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);
|
||||
let final_quat = Quat::from_axis_angle(
|
||||
Vec3::Z,
|
||||
radians_from_degrees(player_values_state.player_lean_angle),
|
||||
);
|
||||
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) {
|
||||
let final_quat =
|
||||
Quat::from_axis_angle(Vec3::Z, radians_from_degrees(-player_values_state.player_lean_angle));
|
||||
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);
|
||||
let final_quat = Quat::from_axis_angle(
|
||||
Vec3::Z,
|
||||
radians_from_degrees(-player_values_state.player_lean_angle),
|
||||
);
|
||||
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 {
|
||||
camera_transform.rotation = camera_transform
|
||||
.rotation
|
||||
.lerp(Quat::default(), time.delta_seconds() / player_values_state.player_lean_time);
|
||||
camera_transform.rotation = camera_transform.rotation.lerp(
|
||||
Quat::default(),
|
||||
time.delta_seconds() / player_values_state.player_lean_time,
|
||||
);
|
||||
|
||||
camera_transform.translation = camera_transform.translation.lerp(Vec3 {
|
||||
x: 0.0,
|
||||
y: camera_transform.translation.y,
|
||||
z: 0.0,
|
||||
}, time.delta_seconds() / player_values_state.player_lean_time);
|
||||
camera_transform.translation = camera_transform.translation.lerp(
|
||||
Vec3 {
|
||||
x: 0.0,
|
||||
y: camera_transform.translation.y,
|
||||
z: 0.0,
|
||||
},
|
||||
time.delta_seconds() / player_values_state.player_lean_time,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,24 @@ use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{
|
||||
comps::core::{markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}, camera::MainCamera, interactable::Interactable}, events::loot_container::LootContainerEvent},
|
||||
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},
|
||||
comps::core::{
|
||||
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(
|
||||
@ -24,8 +40,7 @@ pub fn capture_hand_usage(
|
||||
animation_clips: Res<Assets<AnimationClip>>,
|
||||
|
||||
game_load_state: Res<GameLoadState>,
|
||||
#[allow(unused)]
|
||||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||
#[allow(unused)] mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
||||
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
@ -40,18 +55,19 @@ pub fn capture_hand_usage(
|
||||
|
||||
// Equipping stuff
|
||||
|
||||
|
||||
// Equipping gun
|
||||
if !settings_screen_config.settings_menu_shown {
|
||||
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) {
|
||||
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) {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing ));
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Firearm stuff
|
||||
if let Equipment::Firearm(player_firearm) = player_query.single().0.equipment.clone() {
|
||||
for mut player_firing_info in player_firing_info_query.iter_mut() {
|
||||
@ -59,11 +75,16 @@ pub fn capture_hand_usage(
|
||||
|
||||
for (firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
||||
for mut hand_transform in hand_query.iter_mut() {
|
||||
|
||||
if player_firing_info.is_reloading {
|
||||
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(animation_clip) = animation_clips.get(&firearm_animations.reload_magazine) {
|
||||
if let Some(firearm_animations) = all_firearm_animations
|
||||
.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() {
|
||||
magazine_data.rounds_shot = 0;
|
||||
player_firing_info.is_reloading = false;
|
||||
@ -71,12 +92,20 @@ pub fn capture_hand_usage(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // Player is not in a reload animation
|
||||
if keyboard_input.just_pressed(KeyCode::R) && !settings_screen_config.settings_menu_shown{
|
||||
} else {
|
||||
// Player is not in a reload animation
|
||||
if keyboard_input.just_pressed(KeyCode::R)
|
||||
&& !settings_screen_config.settings_menu_shown
|
||||
{
|
||||
// Start reload animation
|
||||
for mut animation_player in &mut animation_players {
|
||||
if let Some(firearm_animations) = all_firearm_animations.animations.iter().find(|animation| &animation.firearm == &player_firearm) {
|
||||
animation_player.start(firearm_animations.reload_magazine.clone_weak());
|
||||
if let Some(firearm_animations) = all_firearm_animations
|
||||
.animations
|
||||
.iter()
|
||||
.find(|animation| &animation.firearm == &player_firearm)
|
||||
{
|
||||
animation_player
|
||||
.start(firearm_animations.reload_magazine.clone_weak());
|
||||
player_firing_info.is_reloading = true;
|
||||
}
|
||||
}
|
||||
@ -84,29 +113,38 @@ pub fn capture_hand_usage(
|
||||
// At the end of reload animation, set magazine data to capacity = 0
|
||||
}
|
||||
// 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(
|
||||
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(
|
||||
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.translation = position_lerp_vec3;
|
||||
} else {
|
||||
hand_transform.rotation = hand_transform
|
||||
.rotation
|
||||
.lerp(firearm_data.final_rotation, (time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0));
|
||||
} else {
|
||||
hand_transform.rotation = hand_transform.rotation.lerp(
|
||||
firearm_data.final_rotation,
|
||||
(time.delta_seconds() / firearm_data.rebound_time_seconds)
|
||||
.clamp(0.0, 1.0),
|
||||
);
|
||||
hand_transform.translation = hand_transform.translation.lerp(
|
||||
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
|
||||
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 magazine_data.rounds_shot < magazine_data.max_capacity {
|
||||
// Get recoil numbers from patterns
|
||||
@ -129,10 +167,23 @@ pub fn capture_hand_usage(
|
||||
|
||||
let firearm_transform = firearm_transform.clone();
|
||||
// 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 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
|
||||
player_firing_info.current_round_index += 1;
|
||||
player_firing_info.last_shot_timestamp = time.elapsed_seconds();
|
||||
@ -140,13 +191,17 @@ pub fn capture_hand_usage(
|
||||
magazine_data.rounds_shot += 1;
|
||||
|
||||
// Apply recoil
|
||||
hand_transform
|
||||
.rotate_x(radians_from_degrees(firearm_data.vertical_recoil_modifier * vertical_recoil_number));
|
||||
hand_transform.rotate_y(radians_from_degrees(firearm_data.horizontal_recoil_modifier * horizontal_recoil_number));
|
||||
hand_transform.rotate_x(radians_from_degrees(
|
||||
firearm_data.vertical_recoil_modifier
|
||||
* vertical_recoil_number,
|
||||
));
|
||||
hand_transform.rotate_y(radians_from_degrees(
|
||||
firearm_data.horizontal_recoil_modifier
|
||||
* horizontal_recoil_number,
|
||||
));
|
||||
} else {
|
||||
//TODO: play magazine empty sound
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
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
|
||||
pub fn interact_action(
|
||||
//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>)>,
|
||||
interactables_query: Query<(Entity, &Interactable)>,
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
@ -174,32 +227,47 @@ pub fn interact_action(
|
||||
mut hud_state: ResMut<HudState>,
|
||||
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() {
|
||||
let ray_pos = global_transform.translation();
|
||||
let ray_dir = transform.forward() * 2.0; // TODO: Move this into global Resource state
|
||||
let max_toi = 4.0;
|
||||
let solid = true;
|
||||
|
||||
|
||||
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() {
|
||||
println!(
|
||||
"Hit: {:?} == interactable_entity: {:?} interactable: {}",
|
||||
entity, interactable_entity, interactable
|
||||
);
|
||||
//println!("Collided! {}, {}", entity.index(), interactable.to_string());
|
||||
if interactable_entity == entity {
|
||||
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");
|
||||
match interactable {
|
||||
Interactable::Holdable => todo!(),
|
||||
Interactable::Lootable(any_inventory) => loot_container_event_writer.send(LootContainerEvent(any_inventory.clone())),
|
||||
Interactable::Lootable(any_inventory) => {
|
||||
loot_container_event_writer
|
||||
.send(LootContainerEvent(any_inventory.clone()))
|
||||
}
|
||||
Interactable::Item => todo!(),
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hud_state.interaction_clue_shown = false;
|
||||
}
|
||||
}
|
||||
|
@ -2,5 +2,5 @@ pub mod camera_effects;
|
||||
pub mod camera_player_sync;
|
||||
pub mod hands;
|
||||
pub mod player_movement;
|
||||
pub mod player_values_state;
|
||||
pub mod player_vertical_sync;
|
||||
pub mod player_values_state;
|
@ -109,7 +109,7 @@ pub fn move_player(
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
player_values_state: Res<PlayerValuesState>
|
||||
player_values_state: Res<PlayerValuesState>,
|
||||
) {
|
||||
for (
|
||||
mut player_velocity,
|
||||
@ -151,7 +151,7 @@ pub fn move_player(
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
sprint_multiplier * crouch_multiplier,
|
||||
player_values_state.player_acceleration
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
}
|
||||
if player_movement_input.back {
|
||||
@ -164,7 +164,7 @@ pub fn move_player(
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
crouch_multiplier,
|
||||
player_values_state.player_acceleration
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
}
|
||||
if player_movement_input.right {
|
||||
@ -177,11 +177,13 @@ pub fn move_player(
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
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 {
|
||||
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 {
|
||||
@ -194,17 +196,22 @@ pub fn move_player(
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
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 {
|
||||
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) {
|
||||
player_external_force.impulse = Vec3::new(0.0, player_values_state.player_jump_force, 0.0);
|
||||
if player_movement_input.up
|
||||
&& 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_damping = Damping {
|
||||
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();
|
||||
if positive {
|
||||
player_velocity.linvel.x =
|
||||
player_values_state.max_linear_player_velocity * crouch_multiplier * sprint_multiplier
|
||||
player_velocity.linvel.x = player_values_state.max_linear_player_velocity
|
||||
* crouch_multiplier
|
||||
* sprint_multiplier
|
||||
} 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()
|
||||
@ -228,9 +237,11 @@ pub fn move_player(
|
||||
{
|
||||
let positive = player_velocity.linvel.z.is_sign_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 {
|
||||
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
|
||||
|
@ -1,5 +1,7 @@
|
||||
use bevy::{prelude::{Resource, ReflectResource}, reflect::Reflect};
|
||||
|
||||
use bevy::{
|
||||
prelude::{ReflectResource, Resource},
|
||||
reflect::Reflect,
|
||||
};
|
||||
|
||||
#[derive(Resource, Reflect)]
|
||||
#[reflect(Resource)]
|
||||
@ -7,7 +9,7 @@ pub struct PlayerValuesState {
|
||||
pub max_linear_player_velocity: f32,
|
||||
pub player_acceleration: f32,
|
||||
pub player_jump_force: f32,
|
||||
|
||||
|
||||
pub player_jump_cooldown_s: f64,
|
||||
pub player_sprint_speed_multiplier: f32,
|
||||
pub player_crouch_speed_multiplier: f32,
|
||||
@ -18,10 +20,10 @@ pub struct PlayerValuesState {
|
||||
pub player_camera_height: f32,
|
||||
pub player_crouch_height: f32,
|
||||
pub player_crouch_time_s: f32,
|
||||
|
||||
|
||||
pub player_linear_damping: f32,
|
||||
pub player_linear_damping_while_jumping: f32,
|
||||
|
||||
|
||||
pub player_lean_time: f32,
|
||||
pub player_lean_angle: f32,
|
||||
|
||||
@ -55,4 +57,4 @@ impl Default for PlayerValuesState {
|
||||
player_linear_damping_time_offset_after_jump_in_s: 0.02,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use super::{player_movement::PlayerLinearYState, player_values_state::PlayerValu
|
||||
pub fn sync_player_y_state(
|
||||
mut query: Query<(&Velocity, &mut PlayerLinearYState, &mut Damping), With<Player>>,
|
||||
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 {
|
||||
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();
|
||||
*player_linear_y_state = PlayerLinearYState::Grounded(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 {
|
||||
linear_damping: player_values_state.player_linear_damping,
|
||||
|
@ -2,15 +2,15 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
use scenes::scene1;
|
||||
use ui::{game::plugin::MainGameUIPlugin, editor::plugin::MainEditorUiPlugin};
|
||||
use ui::{editor::plugin::MainEditorUiPlugin, game::plugin::MainGameUIPlugin};
|
||||
|
||||
mod comps;
|
||||
mod constants;
|
||||
mod logic;
|
||||
mod scenes;
|
||||
mod setup;
|
||||
mod utils;
|
||||
mod ui;
|
||||
mod utils;
|
||||
|
||||
fn main() {
|
||||
let mut application = App::new();
|
||||
|
@ -7,11 +7,11 @@ pub fn spawn_ground(
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
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(RigidBody::Fixed)
|
||||
.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 {
|
||||
base_color: Color::WHITE,
|
||||
perceptual_roughness: 1.0,
|
||||
|
@ -2,17 +2,30 @@ use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
comps::core::controller::capture_input,
|
||||
logic::core::{player::{
|
||||
logic::core::{
|
||||
guns::despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets},
|
||||
player::{
|
||||
camera_player_sync::{
|
||||
follow_cursor_with_camera, update_camera_vertical_position, MouseMovementSettings,
|
||||
},
|
||||
hands::{capture_hand_usage, interact_action},
|
||||
player_vertical_sync::sync_player_y_state, 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_values_state::PlayerValuesState,
|
||||
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::{
|
||||
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) {
|
||||
@ -23,7 +36,10 @@ pub fn load_scene(application: &mut App) {
|
||||
// Startup
|
||||
application.add_systems(PreStartup, load_all_assets);
|
||||
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, set_spawn_points);
|
||||
// Update
|
||||
@ -32,7 +48,7 @@ pub fn load_scene(application: &mut App) {
|
||||
application.add_systems(Update, sync_player_y_state);
|
||||
application.add_systems(Update, follow_cursor_with_camera);
|
||||
application.add_systems(Update, load_animations);
|
||||
|
||||
|
||||
application.add_systems(Update, set_skybox_if_loaded);
|
||||
application.add_systems(Update, update_camera_vertical_position);
|
||||
application.add_systems(Update, (capture_hand_usage, interact_action));
|
||||
|
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,16 +1,19 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub fn setup_lighting(mut commands: Commands) {
|
||||
commands.spawn((SpotLightBundle {
|
||||
spot_light: SpotLight {
|
||||
color: Color::WHITE,
|
||||
intensity: 3000.0,
|
||||
range: 500.0,
|
||||
shadows_enabled: true,
|
||||
commands.spawn((
|
||||
SpotLightBundle {
|
||||
spot_light: SpotLight {
|
||||
color: Color::WHITE,
|
||||
intensity: 3000.0,
|
||||
range: 500.0,
|
||||
shadows_enabled: true,
|
||||
..Default::default()
|
||||
},
|
||||
transform: Transform::from_xyz(20.0, 20.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
},
|
||||
transform: Transform::from_xyz(20.0, 20.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
}, Name::new("LightSource")));
|
||||
Name::new("LightSource"),
|
||||
));
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
pub mod init;
|
||||
|
||||
pub mod ground;
|
||||
pub mod items;
|
||||
pub mod lighting;
|
||||
pub mod obstacles;
|
||||
pub mod skybox;
|
||||
pub mod spawn_points;
|
||||
pub mod spawn_points;
|
||||
|
@ -1,7 +1,9 @@
|
||||
use bevy::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(
|
||||
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_5_mesh = shape::Box::new(2.0, 2.0, 2.0).into();
|
||||
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(PbrBundle {
|
||||
mesh: meshes.add(box_1_mesh.into()),
|
||||
@ -29,7 +34,10 @@ pub fn spawn_obstacles(
|
||||
});
|
||||
|
||||
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(PbrBundle {
|
||||
mesh: meshes.add(box_2_mesh.into()),
|
||||
@ -43,7 +51,10 @@ pub fn spawn_obstacles(
|
||||
});
|
||||
|
||||
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(PbrBundle {
|
||||
mesh: meshes.add(box_3_mesh.into()),
|
||||
@ -57,7 +68,10 @@ pub fn spawn_obstacles(
|
||||
});
|
||||
|
||||
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(PbrBundle {
|
||||
mesh: meshes.add(box_4_mesh.into()),
|
||||
@ -69,10 +83,13 @@ pub fn spawn_obstacles(
|
||||
transform: Transform::from_xyz(15.0, 3.5, 15.0),
|
||||
..default()
|
||||
});
|
||||
|
||||
|
||||
// CRATE
|
||||
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(PbrBundle {
|
||||
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),
|
||||
..default()
|
||||
})
|
||||
.insert(
|
||||
Interactable::Lootable(AnyInventory::new(UGrid::new_square(10)))
|
||||
);
|
||||
.insert(Interactable::Lootable(AnyInventory::new(
|
||||
UGrid::new_square(10),
|
||||
)));
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ pub fn set_skybox_if_loaded(
|
||||
mut cubemap: ResMut<Cubemap>,
|
||||
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();
|
||||
// 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() {
|
||||
commands.entity(camera_entity).insert(Skybox(cubemap.image_handle.clone()));
|
||||
commands
|
||||
.entity(camera_entity)
|
||||
.insert(Skybox(cubemap.image_handle.clone()));
|
||||
cubemap.is_loaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,20 @@
|
||||
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) {
|
||||
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;
|
||||
|
||||
@ -14,7 +14,6 @@ pub struct AllFirearmAnimations {
|
||||
pub struct FirearmAnimations {
|
||||
pub firearm: Firearm,
|
||||
pub reload_magazine: Handle<AnimationClip>,
|
||||
|
||||
}
|
||||
|
||||
/// System to load animations once the Gltf file is loaded.
|
||||
@ -31,16 +30,21 @@ pub fn load_animations(
|
||||
if assets_gltf.assets.len() != loaded_gltf_assets.len() {
|
||||
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() {
|
||||
if gltf_asset.asset_type.is_firearm() {
|
||||
if let Some(loaded_gltf) = loaded_gltf_assets.get(&gltf_asset.asset) {
|
||||
// Needs to have all firearm animations
|
||||
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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
commands.insert_resource(all_firearm_animations);
|
||||
game_load_state.animations_loaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
@ -10,18 +13,19 @@ pub enum GltfAssetType {
|
||||
#[allow(unused)]
|
||||
Enemy,
|
||||
}
|
||||
|
||||
#[derive(Resource, Reflect, Default)]
|
||||
#[reflect(Resource)]
|
||||
pub struct GltfAssets {
|
||||
pub assets: Vec<GltfAsset>
|
||||
pub assets: Vec<GltfAsset>,
|
||||
}
|
||||
|
||||
#[derive(Reflect)]
|
||||
pub struct GltfAsset {
|
||||
pub asset_type: GltfAssetType,
|
||||
pub asset: Handle<Gltf>,
|
||||
}
|
||||
|
||||
|
||||
pub fn load_all_assets(
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
@ -32,13 +36,16 @@ pub fn load_all_assets(
|
||||
is_loaded: false,
|
||||
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 glock17_gltf_asset = GltfAsset { asset_type: GltfAssetType::Firearm(Firearm::Glock17), asset: asset_server.load(Firearm::Glock17.firearm_data().asset_path) };
|
||||
let m4a1_gltf_asset = GltfAsset {
|
||||
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 {
|
||||
assets: Vec::from([
|
||||
m4a1_gltf_asset,
|
||||
glock17_gltf_asset
|
||||
])
|
||||
assets: Vec::from([m4a1_gltf_asset, glock17_gltf_asset]),
|
||||
});
|
||||
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.
|
||||
@ -49,7 +56,7 @@ impl GltfAssetType {
|
||||
pub fn is_firearm(&self) -> bool {
|
||||
match self {
|
||||
GltfAssetType::Firearm(_) => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn get_firearm(&self) -> &Firearm {
|
||||
@ -58,4 +65,4 @@ impl GltfAssetType {
|
||||
_ => panic!("Called get_firearm on Non-Firearm GltfAssetType"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
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)]
|
||||
pub struct EquipmentChangeEvent(pub Equipment);
|
||||
@ -29,22 +37,27 @@ pub fn change_equipment(
|
||||
for equipment_change_event in equipment_change_event_reader.read() {
|
||||
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
|
||||
return;
|
||||
} ;
|
||||
};
|
||||
// Primary firearm change
|
||||
if equipment_change_event.0 != player.0.equipment {
|
||||
|
||||
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
|
||||
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
|
||||
player.0.equipment = equipment_change_event.0.clone();
|
||||
println!("Equipment change done");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +69,11 @@ fn spawn_firearm_on_player_hands(
|
||||
loaded_gltf_assets: &Assets<Gltf>,
|
||||
firearm: Firearm,
|
||||
) {
|
||||
if let Some(asset_handle) = assets_gltf.assets.iter().find(|asset| asset.asset_type == GltfAssetType::Firearm(firearm.clone())) {
|
||||
if let Some(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);
|
||||
@ -65,19 +82,27 @@ fn spawn_firearm_on_player_hands(
|
||||
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("Firearm Gltf Asset"))).id();
|
||||
|
||||
let scene = gltf.scenes[0].clone();
|
||||
let firearm_asset_entity = commands
|
||||
.spawn((
|
||||
SceneBundle {
|
||||
scene,
|
||||
visibility: Visibility::Inherited,
|
||||
transform: firearm_transform,
|
||||
..default()
|
||||
},
|
||||
Name::new("Firearm Gltf Asset"),
|
||||
))
|
||||
.id();
|
||||
let firearm_entity = commands
|
||||
.spawn((
|
||||
firearm_data.clone(),
|
||||
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,
|
||||
Name::new("Firearm"),
|
||||
TransformBundle {
|
||||
@ -88,18 +113,19 @@ fn spawn_firearm_on_player_hands(
|
||||
visibility: Visibility::Inherited,
|
||||
..Default::default()
|
||||
},
|
||||
)).push_children(&[firearm_asset_entity])
|
||||
))
|
||||
.push_children(&[firearm_asset_entity])
|
||||
.id();
|
||||
|
||||
commands.entity(player_hands).push_children(&[firearm_entity]);
|
||||
|
||||
|
||||
let time_in_secs_between_each_round =
|
||||
1.0 / firearm_data.fire_rate * 60.0;
|
||||
commands
|
||||
.entity(player_hands)
|
||||
.push_children(&[firearm_entity]);
|
||||
|
||||
let time_in_secs_between_each_round = 1.0 / firearm_data.fire_rate * 60.0;
|
||||
player_firing_info.full_auto_timer = Timer::new(
|
||||
Duration::from_secs_f32(time_in_secs_between_each_round),
|
||||
TimerMode::Once,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,11 @@ use bevy::prelude::*;
|
||||
pub struct GameLoadState {
|
||||
pub assets_loaded: bool,
|
||||
pub animations_loaded: bool,
|
||||
pub player_loaded: bool,
|
||||
pub player_loaded: bool,
|
||||
}
|
||||
|
||||
impl GameLoadState {
|
||||
pub fn is_everything_except_player_loaded(&self) -> bool {
|
||||
self.assets_loaded &&
|
||||
self.animations_loaded
|
||||
self.assets_loaded && self.animations_loaded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub mod assets;
|
||||
pub mod animations;
|
||||
pub mod assets;
|
||||
pub mod equipment;
|
||||
pub mod load_state;
|
||||
pub mod spawn;
|
||||
pub mod spawners;
|
||||
pub mod equipment;
|
@ -1,14 +1,22 @@
|
||||
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.
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct SpawnPoint<T: Bundle> {
|
||||
pub at: Transform,
|
||||
pub what: T
|
||||
pub what: T,
|
||||
}
|
||||
|
||||
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 firearm;
|
@ -4,9 +4,16 @@ use bevy_rapier3d::prelude::*;
|
||||
use crate::{
|
||||
comps::core::markers::{
|
||||
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;
|
||||
@ -28,7 +35,9 @@ pub fn player_spawner(
|
||||
// Spawn hand
|
||||
let player_hand = commands
|
||||
.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 {
|
||||
visibility: Visibility::Inherited,
|
||||
..Default::default()
|
||||
@ -76,7 +85,9 @@ pub fn player_spawner(
|
||||
| LockedAxes::ROTATION_LOCKED_X
|
||||
| LockedAxes::ROTATION_LOCKED_Y,
|
||||
)
|
||||
.insert(ColliderMassProperties::Mass(player_values_state.player_initial_weight))
|
||||
.insert(ColliderMassProperties::Mass(
|
||||
player_values_state.player_initial_weight,
|
||||
))
|
||||
.insert(ExternalImpulse {
|
||||
impulse: Vec3::ZERO,
|
||||
torque_impulse: Vec3::ZERO,
|
||||
@ -94,7 +105,9 @@ pub fn player_spawner(
|
||||
.push_children(&[camera]);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
use bevy::{prelude::*, window::PrimaryWindow};
|
||||
use bevy_editor_pls::{controls::{self, EditorControls}, default_windows::cameras::EditorCamera};
|
||||
use bevy_inspector_egui::{egui, bevy_egui::EguiContext, bevy_inspector};
|
||||
use bevy_editor_pls::{
|
||||
controls::{self, EditorControls},
|
||||
default_windows::cameras::EditorCamera,
|
||||
};
|
||||
use bevy_inspector_egui::{bevy_egui::EguiContext, bevy_inspector, egui};
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn inspector_ui(world: &mut World) {
|
||||
@ -9,10 +12,8 @@ pub fn inspector_ui(world: &mut World) {
|
||||
.single(world)
|
||||
.clone();
|
||||
|
||||
egui::Window::new("World")
|
||||
.show(egui_context.get_mut(), |ui| {
|
||||
egui::ScrollArea::vertical()
|
||||
.show(ui, |ui| {
|
||||
egui::Window::new("World").show(egui_context.get_mut(), |ui| {
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
bevy_inspector::ui_for_world(world, ui);
|
||||
});
|
||||
});
|
||||
@ -33,7 +34,9 @@ pub fn editor_controls() -> EditorControls {
|
||||
}
|
||||
|
||||
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>>,
|
||||
) {
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! Editor UI means everything that won't be in the actual game
|
||||
pub mod plugin;
|
||||
pub mod inspector;
|
||||
pub mod plugin;
|
||||
/*
|
||||
pub mod panels;
|
||||
pub mod state;
|
||||
pub mod camera;
|
||||
*/
|
||||
*/
|
||||
|
@ -2,7 +2,31 @@ use bevy::prelude::*;
|
||||
use bevy_editor_pls::EditorPlugin;
|
||||
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};
|
||||
|
||||
@ -14,34 +38,33 @@ pub struct MainEditorUiPlugin;
|
||||
|
||||
impl Plugin for MainEditorUiPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
.register_type::<PlayerFiringInfo>()
|
||||
.register_type::<PlayerValuesState>()
|
||||
.register_type::<FirearmData>()
|
||||
.register_type::<MagazineData>()
|
||||
.register_type::<HoldableObjectData>()
|
||||
.register_type::<InPlayerHands>()
|
||||
.register_type::<PlayerData>()
|
||||
.register_type::<Player>()
|
||||
.register_type::<PlayerHand>()
|
||||
.register_type::<Caliber>()
|
||||
.register_type::<Firearm>()
|
||||
.register_type::<FirearmSprayPattern>()
|
||||
.register_type::<MouseMovementSettings>()
|
||||
.register_type::<PlayerLinearYState>()
|
||||
.register_type::<PlayerLinearXZState>()
|
||||
.register_type::<PlayerMovementInput>()
|
||||
.register_type::<Cubemap>()
|
||||
.register_type::<AllFirearmAnimations>()
|
||||
.register_type::<FirearmAnimations>()
|
||||
.register_type::<GltfAssetType>()
|
||||
.register_type::<GltfAssets>()
|
||||
.register_type::<Equipment>()
|
||||
.register_type::<GameLoadState>()
|
||||
.add_plugins(EguiPlugin)
|
||||
.add_plugins(EditorPlugin::default())
|
||||
.insert_resource(editor_controls())
|
||||
.add_systems(PostStartup, set_cam3d_controls);
|
||||
app.register_type::<PlayerFiringInfo>()
|
||||
.register_type::<PlayerValuesState>()
|
||||
.register_type::<FirearmData>()
|
||||
.register_type::<MagazineData>()
|
||||
.register_type::<HoldableObjectData>()
|
||||
.register_type::<InPlayerHands>()
|
||||
.register_type::<PlayerData>()
|
||||
.register_type::<Player>()
|
||||
.register_type::<PlayerHand>()
|
||||
.register_type::<Caliber>()
|
||||
.register_type::<Firearm>()
|
||||
.register_type::<FirearmSprayPattern>()
|
||||
.register_type::<MouseMovementSettings>()
|
||||
.register_type::<PlayerLinearYState>()
|
||||
.register_type::<PlayerLinearXZState>()
|
||||
.register_type::<PlayerMovementInput>()
|
||||
.register_type::<Cubemap>()
|
||||
.register_type::<AllFirearmAnimations>()
|
||||
.register_type::<FirearmAnimations>()
|
||||
.register_type::<GltfAssetType>()
|
||||
.register_type::<GltfAssets>()
|
||||
.register_type::<Equipment>()
|
||||
.register_type::<GameLoadState>()
|
||||
.add_plugins(EguiPlugin)
|
||||
.add_plugins(EditorPlugin::default())
|
||||
.insert_resource(editor_controls())
|
||||
.add_systems(PostStartup, set_cam3d_controls);
|
||||
//.add_plugins(ResourceInspectorPlugin::<MouseMovementSettings>::default());
|
||||
//.add_plugins(bevy_inspector_egui::DefaultInspectorConfigPlugin) // adds default options and `InspectorEguiImpl`s
|
||||
//.add_systems(Update, inspector_ui);
|
||||
@ -49,4 +72,4 @@ impl Plugin for MainEditorUiPlugin {
|
||||
//app.add_systems(Update, editor_ui);
|
||||
//app.add_systems(PostUpdate, set_camera_viewport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,24 +9,37 @@ pub struct FpsCounterMarker {
|
||||
}
|
||||
impl FpsCounterMarker {
|
||||
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, ) {
|
||||
commands.spawn((TextBundle {
|
||||
text: Text::from_section("FPS: 0.0", TextStyle {
|
||||
font_size: 18.0, color: Color::GREEN, ..Default::default()
|
||||
}).with_alignment(TextAlignment::Center),
|
||||
style: Style {
|
||||
position_type: PositionType::Absolute,
|
||||
right: Val::Px(10.0),
|
||||
top: Val::Px(30.0),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}, Name::new("Fps Counter")))
|
||||
.insert(FpsCounterMarker::new());
|
||||
pub fn setup_fps_counter(mut commands: Commands) {
|
||||
commands
|
||||
.spawn((
|
||||
TextBundle {
|
||||
text: Text::from_section(
|
||||
"FPS: 0.0",
|
||||
TextStyle {
|
||||
font_size: 18.0,
|
||||
color: Color::GREEN,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_alignment(TextAlignment::Center),
|
||||
style: Style {
|
||||
position_type: PositionType::Absolute,
|
||||
right: Val::Px(10.0),
|
||||
top: Val::Px(30.0),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Fps Counter"),
|
||||
))
|
||||
.insert(FpsCounterMarker::new());
|
||||
}
|
||||
|
||||
pub fn tick_fps_counter(
|
||||
@ -45,4 +58,4 @@ pub fn tick_fps_counter(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ use bevy::prelude::*;
|
||||
#[reflect(Resource)]
|
||||
pub struct HudState {
|
||||
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;
|
||||
|
||||
@ -9,51 +9,51 @@ pub struct InteractClueHudMarker;
|
||||
|
||||
pub fn setup_interact_clue(mut commands: Commands) {
|
||||
commands.spawn((
|
||||
NodeBundle {
|
||||
TextBundle {
|
||||
text: Text::from_section(
|
||||
"Interact",
|
||||
TextStyle {
|
||||
font_size: 12.0,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_alignment(TextAlignment::Center),
|
||||
style: Style {
|
||||
display: Display::Flex,
|
||||
width: Val::Percent(100.0),
|
||||
height: Val::Percent(100.0),
|
||||
justify_content: JustifyContent::Center,
|
||||
align_items: AlignItems::Center,
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Percent(50.0),
|
||||
left: Val::Percent(50.0),
|
||||
..Default::default()
|
||||
},
|
||||
visibility: Visibility::Hidden,
|
||||
background_color: BackgroundColor(Color::NONE),
|
||||
focus_policy: FocusPolicy::Pass,
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
}, Name::new("Interaction Clue Background"),
|
||||
InteractClueHudMarker)
|
||||
).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()
|
||||
}, Name::new("Interaction Clue text"),
|
||||
},
|
||||
Name::new("Interaction Clue text"),
|
||||
InteractClueHudMarker,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update_interact_clue(
|
||||
//mut commands: Commands,
|
||||
interact_clue: Res<HudState>,
|
||||
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() {
|
||||
return;
|
||||
}
|
||||
for mut vis in query.iter_mut() {
|
||||
for (mut vis, mut text) in query.iter_mut() {
|
||||
if settings_screen_config.settings_menu_shown {
|
||||
*vis = Visibility::Hidden;
|
||||
return;
|
||||
}
|
||||
if interact_clue.interaction_clue_shown {
|
||||
*vis = Visibility::Visible;
|
||||
if let Some(section) = text.sections.first_mut() {
|
||||
section.value = interact_clue.interaction_clue_text.clone();
|
||||
}
|
||||
} else {
|
||||
*vis = Visibility::Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
pub mod hud;
|
||||
pub mod interact_clue;
|
||||
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};
|
||||
|
||||
|
||||
pub struct HudOverlayPlugin;
|
||||
|
||||
impl Plugin for HudOverlayPlugin {
|
||||
@ -14,4 +13,4 @@ impl Plugin for HudOverlayPlugin {
|
||||
app.add_systems(Startup, setup_interact_clue);
|
||||
app.add_systems(Update, update_interact_clue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,9 @@ use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::events::loot_container::LootContainerEvent;
|
||||
|
||||
|
||||
/// # Inventory Screen
|
||||
/// Should contain player inventory and if player is looting something as well
|
||||
pub fn setup_inventory_screen(
|
||||
mut commands: Commands,
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
pub fn setup_inventory_screen(mut commands: Commands) {}
|
||||
|
||||
pub fn update_inventory_screen(
|
||||
mut commands: Commands,
|
||||
@ -19,4 +13,4 @@ pub fn update_inventory_screen(
|
||||
for loot_container_event in event_reader.read() {
|
||||
//let a = loot_container_event.0.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
pub mod menu;
|
||||
pub mod plugin;
|
||||
pub mod plugin;
|
||||
|
@ -4,7 +4,6 @@ use crate::comps::core::events::loot_container::LootContainerEvent;
|
||||
|
||||
use super::menu::{setup_inventory_screen, update_inventory_screen};
|
||||
|
||||
|
||||
pub struct InventoryMenuPlugin;
|
||||
|
||||
impl Plugin for InventoryMenuPlugin {
|
||||
@ -13,4 +12,4 @@ impl Plugin for InventoryMenuPlugin {
|
||||
app.add_systems(Startup, setup_inventory_screen);
|
||||
app.add_systems(Update, update_inventory_screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Game UI means all the UI that will be part of the actual game
|
||||
pub mod plugin;
|
||||
pub mod fps_counter;
|
||||
pub mod hud;
|
||||
pub mod inventory;
|
||||
pub mod plugin;
|
||||
pub mod settings;
|
||||
pub mod settings_screen;
|
||||
pub mod inventory;
|
||||
pub mod hud;
|
@ -2,7 +2,9 @@ use bevy::prelude::*;
|
||||
|
||||
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;
|
||||
|
||||
@ -12,15 +14,21 @@ impl Plugin for MainGameUIPlugin {
|
||||
app.add_plugins(inventory::plugin::InventoryMenuPlugin);
|
||||
app.insert_resource(GameConfiguration::default());
|
||||
app.insert_resource(SettingsScreenUIConfiguration::default());
|
||||
app.add_systems(Startup, (
|
||||
settings_screen::setup_settings_screen,
|
||||
fps_counter::setup_fps_counter,
|
||||
inventory::menu::setup_inventory_screen,
|
||||
));
|
||||
app.add_systems(Update, (
|
||||
settings_screen::toggle_settings_screen,
|
||||
settings_screen::handle_settings_button_click,
|
||||
fps_counter::tick_fps_counter,
|
||||
));
|
||||
app.add_systems(
|
||||
Startup,
|
||||
(
|
||||
settings_screen::setup_settings_screen,
|
||||
fps_counter::setup_fps_counter,
|
||||
inventory::menu::setup_inventory_screen,
|
||||
),
|
||||
);
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
settings_screen::toggle_settings_screen,
|
||||
settings_screen::handle_settings_button_click,
|
||||
fps_counter::tick_fps_counter,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ pub struct SettingsScreenUIConfiguration {
|
||||
|
||||
impl Default for SettingsScreenUIConfiguration {
|
||||
fn default() -> Self {
|
||||
Self { settings_menu_shown: false }
|
||||
Self {
|
||||
settings_menu_shown: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,13 +18,12 @@ impl Default for SettingsScreenUIConfiguration {
|
||||
#[reflect(Resource)]
|
||||
pub struct GameConfiguration {
|
||||
pub fps_counter_enabled: bool,
|
||||
|
||||
}
|
||||
|
||||
impl Default for GameConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
Self {
|
||||
fps_counter_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use bevy::{prelude::*, ui::FocusPolicy, app::AppExit};
|
||||
use bevy::{app::AppExit, prelude::*, ui::FocusPolicy};
|
||||
|
||||
use super::settings::SettingsScreenUIConfiguration;
|
||||
|
||||
@ -12,64 +12,86 @@ pub enum SettingsScreenActions {
|
||||
}
|
||||
|
||||
pub fn setup_settings_screen(mut commands: Commands) {
|
||||
commands.spawn((
|
||||
NodeBundle {
|
||||
style: Style {
|
||||
display: Display::Flex,
|
||||
width: Val::Percent(100.0),
|
||||
height: Val::Percent(100.0),
|
||||
justify_content: JustifyContent::Center,
|
||||
align_items: AlignItems::Center,
|
||||
flex_direction: FlexDirection::Column,
|
||||
..Default::default()
|
||||
},
|
||||
visibility: Visibility::Hidden,
|
||||
background_color: BackgroundColor(Color::rgba(0.0, 0.0, 0.0, 0.9)),
|
||||
focus_policy: FocusPolicy::Block,
|
||||
..Default::default()
|
||||
}, Name::new("Settings Menu"))
|
||||
)
|
||||
.insert(SettingsScreenMarker)
|
||||
.with_children(|parent| {
|
||||
// RESUME BUTTON
|
||||
parent.spawn((
|
||||
ButtonBundle {
|
||||
commands
|
||||
.spawn((
|
||||
NodeBundle {
|
||||
style: Style {
|
||||
display: Display::Flex,
|
||||
width: Val::Percent(100.0),
|
||||
height: Val::Percent(100.0),
|
||||
justify_content: JustifyContent::Center,
|
||||
align_items: AlignItems::Center,
|
||||
flex_direction: FlexDirection::Column,
|
||||
..Default::default()
|
||||
},
|
||||
background_color: BackgroundColor(Color::NONE),
|
||||
visibility: Visibility::Hidden,
|
||||
background_color: BackgroundColor(Color::rgba(0.0, 0.0, 0.0, 0.9)),
|
||||
focus_policy: FocusPolicy::Block,
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Resume Button")
|
||||
Name::new("Settings Menu"),
|
||||
))
|
||||
.insert(SettingsScreenActions::Resume)
|
||||
.insert(SettingsScreenMarker)
|
||||
.with_children(|parent| {
|
||||
parent.spawn((TextBundle {
|
||||
text: Text::from_section("Resume", TextStyle { font_size: 32.0, ..Default::default() }),
|
||||
..Default::default()
|
||||
}, Name::new("Resume Button Text")));
|
||||
// RESUME BUTTON
|
||||
parent
|
||||
.spawn((
|
||||
ButtonBundle {
|
||||
style: Style {
|
||||
..Default::default()
|
||||
},
|
||||
background_color: BackgroundColor(Color::NONE),
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Resume Button"),
|
||||
))
|
||||
.insert(SettingsScreenActions::Resume)
|
||||
.with_children(|parent| {
|
||||
parent.spawn((
|
||||
TextBundle {
|
||||
text: Text::from_section(
|
||||
"Resume",
|
||||
TextStyle {
|
||||
font_size: 32.0,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Resume Button Text"),
|
||||
));
|
||||
});
|
||||
// QUIT BUTTON
|
||||
parent
|
||||
.spawn((
|
||||
ButtonBundle {
|
||||
style: Style {
|
||||
..Default::default()
|
||||
},
|
||||
background_color: BackgroundColor(Color::NONE),
|
||||
//focus_policy: FocusPolicy::Block,
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Quit Button"),
|
||||
))
|
||||
.insert(SettingsScreenActions::Quit)
|
||||
.with_children(|parent| {
|
||||
parent.spawn((
|
||||
TextBundle {
|
||||
text: Text::from_section(
|
||||
"Quit",
|
||||
TextStyle {
|
||||
font_size: 32.0,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Quit Button text"),
|
||||
));
|
||||
});
|
||||
// END BUTTONS
|
||||
});
|
||||
// QUIT BUTTON
|
||||
parent.spawn((
|
||||
ButtonBundle {
|
||||
style: Style {
|
||||
..Default::default()
|
||||
},
|
||||
background_color: BackgroundColor(Color::NONE),
|
||||
//focus_policy: FocusPolicy::Block,
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Quit Button")
|
||||
))
|
||||
.insert(SettingsScreenActions::Quit)
|
||||
.with_children(|parent| {
|
||||
parent.spawn((TextBundle {
|
||||
text: Text::from_section("Quit", TextStyle { font_size: 32.0, ..Default::default() }),
|
||||
..Default::default()
|
||||
}, Name::new("Quit Button text")));
|
||||
});
|
||||
// END BUTTONS
|
||||
});
|
||||
}
|
||||
|
||||
pub fn toggle_settings_screen(
|
||||
@ -77,7 +99,9 @@ pub fn toggle_settings_screen(
|
||||
mut settings_screen_query: Query<(&mut Visibility, &mut Style), With<SettingsScreenMarker>>,
|
||||
) {
|
||||
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 {
|
||||
*settings_screen_visibility = Visibility::Visible;
|
||||
settings_screen_style.display = Display::Flex;
|
||||
@ -102,15 +126,15 @@ pub fn handle_settings_button_click(
|
||||
SettingsScreenActions::Quit => {
|
||||
// QUIT GAME
|
||||
exit.send(AppExit);
|
||||
},
|
||||
}
|
||||
SettingsScreenActions::Resume => {
|
||||
// RESUME GAME
|
||||
settings.settings_menu_shown = false;
|
||||
mouse_buttons.release(MouseButton::Left);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
pub mod editor;
|
||||
pub mod game;
|
||||
pub mod editor;
|
Loading…
Reference in New Issue
Block a user