Shooting, weapon customization, magazine data in gun not in magazine
This commit is contained in:
parent
312017c771
commit
a447e49036
Binary file not shown.
Binary file not shown.
@ -7,14 +7,14 @@ use bevy_rapier3d::{dynamics::{RigidBody, GravityScale, ExternalImpulse}, geomet
|
|||||||
use crate::{comps::core::{
|
use crate::{comps::core::{
|
||||||
grid::UGrid,
|
grid::UGrid,
|
||||||
items::item::{Item, ItemType, ItemId},
|
items::item::{Item, ItemType, ItemId},
|
||||||
markers::{holdable::HoldableObjectType, interactable::Interactable}, inventory::slot::PlayerInventorySlotType, weapons::{firearm::Firearm, firearm_data::FirearmData}, events::pickup_item::ItemState,
|
markers::{holdable::HoldableObjectType, interactable::Interactable, proxy::weapons::initial_attachments::InitialAttachments}, inventory::slot::PlayerInventorySlotType, weapons::{firearm::Firearm, firearm_data::FirearmData, attachments::weapon_attachment::WeaponAttachment}, events::pickup_item::ItemState,
|
||||||
}, setup::assets::{GltfAssets, GltfAssetType}, utils};
|
}, setup::assets::{GltfAssets, GltfAssetType}, utils};
|
||||||
|
|
||||||
#[derive(Component, Clone)]
|
#[derive(Component, Clone)]
|
||||||
pub struct Ak105GunItem {
|
pub struct Ak105GunItem {
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub state: Mutex<Option<ItemState>>,
|
pub state: Mutex<Option<ItemState>>,
|
||||||
|
pub initial_attachments: Option<InitialAttachments>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item for Ak105GunItem {
|
impl Item for Ak105GunItem {
|
||||||
@ -102,6 +102,9 @@ impl Item for Ak105GunItem {
|
|||||||
Some(ref state) => { commands.entity(firearm_asset_entity).insert(state.clone()); },
|
Some(ref state) => { commands.entity(firearm_asset_entity).insert(state.clone()); },
|
||||||
None => {},
|
None => {},
|
||||||
};
|
};
|
||||||
|
if let Some(initial_attachments) = &self.initial_attachments {
|
||||||
|
commands.entity(firearm_asset_entity).insert(initial_attachments.clone());
|
||||||
|
}
|
||||||
let firearm_size = firearm.get_size();
|
let firearm_size = firearm.get_size();
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comps::core::{
|
comps::core::{
|
||||||
grid::UGrid,
|
grid::UGrid,
|
||||||
markers::{holdable::HoldableObjectType, interactable::Interactable}, inventory::slot::PlayerInventorySlotType, weapons::{firearm_data::FirearmData, firearm::Firearm}, events::pickup_item::ItemState,
|
markers::holdable::HoldableObjectType, inventory::slot::PlayerInventorySlotType, weapons::firearm::Firearm, events::pickup_item::ItemState,
|
||||||
},
|
},
|
||||||
setup::assets::{GltfAssetType, GltfAssets},
|
setup::assets::GltfAssets,
|
||||||
utils,
|
|
||||||
};
|
};
|
||||||
use bevy::{gltf::Gltf, prelude::*};
|
use bevy::{gltf::Gltf, prelude::*};
|
||||||
use bevy_rapier3d::prelude::*;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub enum ItemType {
|
pub enum ItemType {
|
||||||
Holdable(HoldableObjectType),
|
Holdable(HoldableObjectType),
|
||||||
Equippable,
|
Equippable,
|
||||||
|
@ -2,47 +2,49 @@ use bevy::{prelude::*, gltf::Gltf, ecs::system::SystemParam, scene::SceneInstanc
|
|||||||
|
|
||||||
use crate::{comps::core::{weapons::{firearm::Firearm, firearm_state::FirearmState, slot::slot::WeaponSlot, attachment_slot::AttachmentSlot, attachments::weapon_attachment::WeaponAttachment}, events::pickup_item::ItemState, markers::holdable::InPlayerHands, inventory::player_inventory::PlayerInventory, items::item::ItemId}, setup::assets::{GltfAssets, GltfAssetType}};
|
use crate::{comps::core::{weapons::{firearm::Firearm, firearm_state::FirearmState, slot::slot::WeaponSlot, attachment_slot::AttachmentSlot, attachments::weapon_attachment::WeaponAttachment}, events::pickup_item::ItemState, markers::holdable::InPlayerHands, inventory::player_inventory::PlayerInventory, items::item::ItemId}, setup::assets::{GltfAssets, GltfAssetType}};
|
||||||
|
|
||||||
|
use super::initial_attachments::InitialAttachments;
|
||||||
|
|
||||||
#[derive(SystemParam)]
|
#[derive(SystemParam)]
|
||||||
pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> {
|
pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> {
|
||||||
firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, &'static Children), With<SceneInstance>>,
|
firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, Option<&'static InitialAttachments>, &'static Children), With<SceneInstance>>,
|
||||||
firearm_query: Query<'w, 's, (Entity, &'static Firearm, &'static Parent, Option<&'static FirearmState>), Or<(Without<FirearmState>, Changed<FirearmState>)>>,
|
firearm_query: Query<'w, 's, (Entity, &'static Firearm, &'static Parent, Option<&'static mut FirearmState>), Or<(Without<FirearmState>, Changed<FirearmState>)>>,
|
||||||
slots_query: Query<'w, 's, (Entity, &'static WeaponSlot, &'static Parent)>,
|
slots_query: Query<'w, 's, (Entity, &'static WeaponSlot, &'static Parent)>,
|
||||||
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
||||||
in_player_hands_query: Query<'w, 's, &'static ItemId, With<InPlayerHands>>,
|
in_player_hands_query: Query<'w, 's, &'static ItemId, With<InPlayerHands>>,
|
||||||
player_inventories_query: Query<'w, 's, &'static PlayerInventory>
|
player_inventories_query: Query<'w, 's, &'static PlayerInventory>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This query inserts FirearmState into firearms, updates firearm assets that already have a FirearmState,
|
/// This query inserts FirearmState into firearms, updates firearm assets that already have a FirearmState,
|
||||||
/// And Re-inserts FirearmState into spawned Firearms that have a passed in ItemState at the root of the SceneBundle
|
/// And Re-inserts FirearmState into spawned Firearms that have a passed in ItemState at the root of the SceneBundle
|
||||||
pub fn insert_firearm_state_to_firearms(
|
pub fn insert_firearm_state_to_firearms(
|
||||||
// needed for tri meshes
|
// needed for tri meshes
|
||||||
queries: InsertFirearmStateIntoFirearmsParams,
|
mut queries: InsertFirearmStateIntoFirearmsParams,
|
||||||
assets_gltf: Res<GltfAssets>,
|
assets_gltf: Res<GltfAssets>,
|
||||||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for (firearm_scene_entity, item_state_opt, scene_bundle_children) in queries.firearm_scene_bundle.iter() {
|
for (firearm_scene_entity, item_state_opt, initial_attchments_opt, scene_bundle_children) in queries.firearm_scene_bundle.iter() {
|
||||||
for scene_bundle_child in scene_bundle_children.iter() {
|
for scene_bundle_child in scene_bundle_children.iter() {
|
||||||
for (firearm_entity, _, firearm_parent, firearm_state_opt) in queries.firearm_query.iter() {
|
for (firearm_entity, _, firearm_parent, firearm_state_opt) in queries.firearm_query.iter_mut() {
|
||||||
if &firearm_parent.get() == scene_bundle_child {
|
if &firearm_parent.get() == scene_bundle_child {
|
||||||
if let Some(item_state) = item_state_opt {
|
if let Some(item_state) = item_state_opt {
|
||||||
// Firearm State is already created and item is being spawned again into world
|
// Firearm State is already created and item is being spawned again into world
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
if let ItemState::Weapon(firearm_state) = item_state {
|
if let ItemState::Weapon(mut firearm_state) = item_state.clone() {
|
||||||
commands.entity(firearm_scene_entity).remove::<ItemState>();
|
commands.entity(firearm_scene_entity).remove::<ItemState>();
|
||||||
|
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||||
commands
|
commands
|
||||||
.entity(firearm_entity)
|
.entity(firearm_entity)
|
||||||
.insert(firearm_state.clone());
|
.insert(firearm_state);
|
||||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match firearm_state_opt {
|
match firearm_state_opt {
|
||||||
Some(firearm_state) => {
|
Some(mut firearm_state) => {
|
||||||
// Change the Slots
|
// Change the Slots
|
||||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||||
//TODO: Change firearm state inside inventory
|
|
||||||
for in_player_hands_item_id in queries.in_player_hands_query.iter() {
|
for in_player_hands_item_id in queries.in_player_hands_query.iter() {
|
||||||
for player_inventory in queries.player_inventories_query.iter() {
|
for player_inventory in queries.player_inventories_query.iter() {
|
||||||
if let Some(current_item) = player_inventory.get_current_slot_item() {
|
if let Some(current_item) = player_inventory.get_current_slot_item() {
|
||||||
@ -56,6 +58,7 @@ pub fn insert_firearm_state_to_firearms(
|
|||||||
None => {
|
None => {
|
||||||
// Create the firearm_state
|
// Create the firearm_state
|
||||||
let mut firearm_slots = Vec::new();
|
let mut firearm_slots = Vec::new();
|
||||||
|
let magazine_data = None;
|
||||||
for (slot_entity, slot, parent_entity) in queries.slots_query.iter() {
|
for (slot_entity, slot, parent_entity) in queries.slots_query.iter() {
|
||||||
if firearm_entity == parent_entity.get() {
|
if firearm_entity == parent_entity.get() {
|
||||||
let mut attachment = None;
|
let mut attachment = None;
|
||||||
@ -70,7 +73,13 @@ pub fn insert_firearm_state_to_firearms(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let firearm_state = FirearmState::new(firearm_slots);
|
if let Some(initial_attachments) = initial_attchments_opt {
|
||||||
|
for initial_attachment in initial_attachments.attachments.iter() {
|
||||||
|
firearm_slots.iter_mut().for_each(|firearm_slot| if initial_attachment.fits_into_slot(&firearm_slot.slot_type) { firearm_slot.attachment = Some(initial_attachment.clone()) });
|
||||||
|
}
|
||||||
|
commands.entity(firearm_scene_entity).remove::<InitialAttachments>();
|
||||||
|
}
|
||||||
|
let firearm_state = FirearmState::new(firearm_slots, magazine_data);
|
||||||
commands
|
commands
|
||||||
.entity(firearm_entity)
|
.entity(firearm_entity)
|
||||||
.insert(firearm_state.clone());
|
.insert(firearm_state.clone());
|
||||||
@ -85,7 +94,7 @@ pub fn insert_firearm_state_to_firearms(
|
|||||||
fn spawn_attachments_in_firearm(
|
fn spawn_attachments_in_firearm(
|
||||||
commands: &mut Commands,
|
commands: &mut Commands,
|
||||||
firearm_entity: Entity,
|
firearm_entity: Entity,
|
||||||
firearm_state: &FirearmState,
|
firearm_state: &mut FirearmState,
|
||||||
slots_query: &Query<(Entity, &WeaponSlot, &Parent)>,
|
slots_query: &Query<(Entity, &WeaponSlot, &Parent)>,
|
||||||
assets_gltf: &GltfAssets,
|
assets_gltf: &GltfAssets,
|
||||||
loaded_gltf_assets: &Assets<Gltf>,
|
loaded_gltf_assets: &Assets<Gltf>,
|
||||||
@ -112,6 +121,11 @@ fn spawn_attachments_in_firearm(
|
|||||||
commands.entity(slot_entity).add_child(
|
commands.entity(slot_entity).add_child(
|
||||||
scene_bundle
|
scene_bundle
|
||||||
);
|
);
|
||||||
|
if let None = &firearm_state.magazine_data {
|
||||||
|
if let WeaponAttachment::Magazine(magazine) = attachment {
|
||||||
|
firearm_state.magazine_data = Some(magazine.magazine_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
}},
|
}},
|
||||||
None => {},
|
None => {},
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::comps::core::weapons::attachments::weapon_attachment::WeaponAttachment;
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Clone)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct InitialAttachments {
|
||||||
|
pub attachments: Vec<WeaponAttachment>
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
pub mod firearm;
|
pub mod firearm;
|
||||||
|
pub mod initial_attachments;
|
@ -4,12 +4,13 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
use crate::comps::core::{
|
use crate::comps::core::{
|
||||||
items::{guns::ak105::Ak105GunItem, item::{Item, ItemId}},
|
items::{guns::ak105::Ak105GunItem, item::{Item, ItemId}},
|
||||||
spawners::item::ItemSpawnPoint,
|
spawners::item::ItemSpawnPoint, weapons::attachments::{weapon_attachment::WeaponAttachment, compensator::Compensator, foregrip::ForeGrip, magazine::Magazine, stock::Stock}, markers::proxy::weapons::initial_attachments::InitialAttachments,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Ak105SpawnPoint {
|
pub struct Ak105SpawnPoint {
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
|
pub attachments: Vec<WeaponAttachment>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemSpawnPoint for Ak105SpawnPoint {
|
impl ItemSpawnPoint for Ak105SpawnPoint {
|
||||||
@ -18,6 +19,32 @@ impl ItemSpawnPoint for Ak105SpawnPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_item(&self) -> Box<dyn Item> {
|
fn get_item(&self) -> Box<dyn Item> {
|
||||||
Box::new(Ak105GunItem { state: Mutex::new(None), id: ItemId(Uuid::new_v4()) })
|
let initial_attachments = if self.attachments.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(InitialAttachments { attachments: self.attachments.clone() })
|
||||||
|
};
|
||||||
|
Box::new(Ak105GunItem { state: Mutex::new(None), id: ItemId(Uuid::new_v4()), initial_attachments })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
impl Ak105SpawnPoint {
|
||||||
|
pub fn new(transform: Transform) -> Self {
|
||||||
|
Self {
|
||||||
|
transform,
|
||||||
|
attachments: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn new_fully_kitted_default(transform: Transform) -> Self {
|
||||||
|
Self {
|
||||||
|
transform,
|
||||||
|
attachments: Vec::from([
|
||||||
|
WeaponAttachment::Compensator(Compensator::FirstCompensator),
|
||||||
|
WeaponAttachment::ForeGrip(ForeGrip::Pk5),
|
||||||
|
WeaponAttachment::Magazine(Magazine::Ak105),
|
||||||
|
WeaponAttachment::Stock(Stock::MagpullTan),
|
||||||
|
]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use bevy::{reflect::{Reflect, std_traits::ReflectDefault}, ecs::{component::Component, reflect::ReflectComponent}};
|
use bevy::{reflect::{Reflect, std_traits::ReflectDefault}, ecs::{component::Component, reflect::ReflectComponent}};
|
||||||
|
|
||||||
|
use crate::comps::core::weapons::magazine_data::MagazineData;
|
||||||
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Component, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Component, Debug, Default)]
|
||||||
#[reflect(Component, Default)]
|
#[reflect(Component, Default)]
|
||||||
@ -9,7 +11,10 @@ pub enum Magazine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Magazine {
|
impl Magazine {
|
||||||
pub fn capacity(&self) -> u32 {
|
pub fn magazine_data(&self) -> MagazineData {
|
||||||
|
MagazineData { rounds_shot: 0, max_capacity: self.capacity() }
|
||||||
|
}
|
||||||
|
pub fn capacity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Magazine::Ak105 => 30,
|
Magazine::Ak105 => 30,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::comps::core::weapons::{attachment_slot::AttachmentSlot, slot::slot::WeaponSlot};
|
||||||
|
|
||||||
use super::{compensator::Compensator, magazine::Magazine, stock::Stock, foregrip::ForeGrip, optic::Optic};
|
use super::{compensator::Compensator, magazine::Magazine, stock::Stock, foregrip::ForeGrip, optic::Optic};
|
||||||
|
|
||||||
#[derive(Component, PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Debug)]
|
#[derive(Component, PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Debug)]
|
||||||
@ -56,4 +58,13 @@ impl WeaponAttachment {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn fits_into_slot(&self, slot: &WeaponSlot) -> bool {
|
||||||
|
match self {
|
||||||
|
WeaponAttachment::Compensator(_) => slot == &WeaponSlot::CompensatorSlot,
|
||||||
|
WeaponAttachment::Magazine(_) => slot == &WeaponSlot::MagazineSlot,
|
||||||
|
WeaponAttachment::Stock(_) => slot == &WeaponSlot::StockSlot,
|
||||||
|
WeaponAttachment::ForeGrip(_) => slot == &WeaponSlot::ForeGripSlot,
|
||||||
|
WeaponAttachment::Optic(_) => slot == &WeaponSlot::SightPlacementStartSlot || slot == &WeaponSlot::SightPlacementEndSlot,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -41,7 +41,7 @@ impl Firearm {
|
|||||||
},
|
},
|
||||||
|
|
||||||
final_aimed_rotation: Quat::default(),//Quat::from_rotation_x(0.026),
|
final_aimed_rotation: Quat::default(),//Quat::from_rotation_x(0.026),
|
||||||
final_rotation: Quat::default(),
|
rotation_offset: Quat::default(),
|
||||||
final_aimed_position: Vec3 {
|
final_aimed_position: Vec3 {
|
||||||
// x: -0.003,
|
// x: -0.003,
|
||||||
// y: -0.35,
|
// y: -0.35,
|
||||||
@ -50,7 +50,7 @@ impl Firearm {
|
|||||||
y: -0.35,
|
y: -0.35,
|
||||||
z: -1.6,
|
z: -1.6,
|
||||||
},
|
},
|
||||||
final_position: Vec3::ZERO, /*Vec3 {
|
translation_offset: Vec3::ZERO, /*Vec3 {
|
||||||
x: 0.6,
|
x: 0.6,
|
||||||
y: -0.45,
|
y: -0.45,
|
||||||
z: -2.7,
|
z: -2.7,
|
||||||
@ -64,7 +64,8 @@ impl Firearm {
|
|||||||
FirearmData {
|
FirearmData {
|
||||||
caliber: Caliber::Parabellum9mm,
|
caliber: Caliber::Parabellum9mm,
|
||||||
fire_rate: 600.0,
|
fire_rate: 600.0,
|
||||||
rebound_time_seconds: 0.1,
|
aim_time_seconds: 0.1,
|
||||||
|
rebound_time_seconds: 0.5,
|
||||||
recoil_pattern: FirearmSprayPattern {
|
recoil_pattern: FirearmSprayPattern {
|
||||||
vertical: Vec::from([
|
vertical: Vec::from([
|
||||||
1.0, 1.2, 1.3, 1.6, 1.5, 1.7, 1.5, 1.5, 1.5, 2.0, // 10 for now
|
1.0, 1.2, 1.3, 1.6, 1.5, 1.7, 1.5, 1.5, 1.5, 2.0, // 10 for now
|
||||||
@ -75,7 +76,7 @@ impl Firearm {
|
|||||||
},
|
},
|
||||||
|
|
||||||
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
||||||
final_rotation: Quat::default(),
|
rotation_offset: Quat::default(),
|
||||||
final_aimed_position: Vec3 {
|
final_aimed_position: Vec3 {
|
||||||
// x: -0.003,
|
// x: -0.003,
|
||||||
// y: -0.35,
|
// y: -0.35,
|
||||||
@ -84,7 +85,7 @@ impl Firearm {
|
|||||||
y: -0.5,
|
y: -0.5,
|
||||||
z: -1.6,
|
z: -1.6,
|
||||||
},
|
},
|
||||||
final_position: Vec3 {
|
translation_offset: Vec3 {
|
||||||
x: 1.0,
|
x: 1.0,
|
||||||
y: -0.45,
|
y: -0.45,
|
||||||
z: -2.7,
|
z: -2.7,
|
||||||
@ -97,7 +98,8 @@ impl Firearm {
|
|||||||
Firearm::Ak105 => FirearmData {
|
Firearm::Ak105 => FirearmData {
|
||||||
caliber: Caliber::RU545,
|
caliber: Caliber::RU545,
|
||||||
fire_rate: 600.0,
|
fire_rate: 600.0,
|
||||||
rebound_time_seconds: 0.2,
|
aim_time_seconds: 0.25,
|
||||||
|
rebound_time_seconds: 0.6,
|
||||||
asset_path: String::from("weapons/ak105_rifle.glb"),
|
asset_path: String::from("weapons/ak105_rifle.glb"),
|
||||||
recoil_pattern: FirearmSprayPattern {
|
recoil_pattern: FirearmSprayPattern {
|
||||||
vertical: Vec::from([
|
vertical: Vec::from([
|
||||||
@ -108,10 +110,10 @@ impl Firearm {
|
|||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
final_aimed_rotation: Quat::default(),
|
final_aimed_rotation: Quat::default(),
|
||||||
final_rotation: Quat::default(),
|
rotation_offset: Quat::default(),
|
||||||
final_aimed_position: Vec3::ZERO,
|
final_aimed_position: Vec3 { x: 0.016, y: 0.0, z: -0.1 },
|
||||||
final_position: Vec3::ZERO,
|
translation_offset: Vec3 { x: -0.2, y: -0.03, z: 0.0 },
|
||||||
scale_factor: 0.3,
|
scale_factor: 0.2,
|
||||||
firearm_type: FirearmType::Primary,
|
firearm_type: FirearmType::Primary,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,20 @@ pub struct FirearmData {
|
|||||||
pub caliber: Caliber,
|
pub caliber: Caliber,
|
||||||
/// Rounds per minute
|
/// Rounds per minute
|
||||||
pub fire_rate: f32,
|
pub fire_rate: f32,
|
||||||
|
/// Amount of time it takes for the gun to aim in or aim out.
|
||||||
|
pub aim_time_seconds: f32,
|
||||||
/// Amount of seconds it takes for gun to come down from shooting
|
/// Amount of seconds it takes for gun to come down from shooting
|
||||||
/// Also is the time it takes for the gun to aim in or aim out.
|
|
||||||
pub rebound_time_seconds: f32,
|
pub rebound_time_seconds: f32,
|
||||||
pub asset_path: String,
|
pub asset_path: String,
|
||||||
pub recoil_pattern: FirearmSprayPattern,
|
pub recoil_pattern: FirearmSprayPattern,
|
||||||
/// Final rotation of hands when aimed in
|
/// Final rotation of hands when aimed in
|
||||||
pub final_aimed_rotation: Quat,
|
pub final_aimed_rotation: Quat,
|
||||||
/// Final rotation of hands when not aimed in
|
/// Final rotation of hands when not aimed in
|
||||||
pub final_rotation: Quat,
|
pub rotation_offset: Quat,
|
||||||
/// Final position of hands when aimed in
|
/// Final position of hands when aimed in
|
||||||
pub final_aimed_position: Vec3,
|
pub final_aimed_position: Vec3,
|
||||||
/// Final position of hands when not aimed in
|
/// Final position of hands when not aimed in
|
||||||
pub final_position: Vec3,
|
pub translation_offset: Vec3,
|
||||||
pub scale_factor: f32,
|
pub scale_factor: f32,
|
||||||
pub firearm_type: FirearmType,
|
pub firearm_type: FirearmType,
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use super::{attachment_slot::AttachmentSlot, slot::slot::WeaponSlot};
|
use super::{attachment_slot::AttachmentSlot, slot::slot::WeaponSlot, magazine_data::MagazineData};
|
||||||
|
|
||||||
#[derive(Component, Reflect, PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
|
#[derive(Component, Reflect, PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
|
||||||
pub struct FirearmState {
|
pub struct FirearmState {
|
||||||
pub attachment_slots: Vec<AttachmentSlot>,
|
pub attachment_slots: Vec<AttachmentSlot>,
|
||||||
|
pub magazine_data: Option<MagazineData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FirearmState {
|
impl FirearmState {
|
||||||
pub fn new(attachment_slots: Vec<AttachmentSlot>) -> Self {
|
pub fn new(attachment_slots: Vec<AttachmentSlot>, magazine_data: Option<MagazineData>) -> Self {
|
||||||
Self { attachment_slots }
|
Self { attachment_slots, magazine_data: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ pub fn switch_camera(
|
|||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
) {
|
) {
|
||||||
if keyboard_input.just_pressed(KeyCode::Key0) {
|
if keyboard_input.just_pressed(KeyCode::Key0) {
|
||||||
|
return;
|
||||||
for mut main_cam in main_camera_query.iter_mut() {
|
for mut main_cam in main_camera_query.iter_mut() {
|
||||||
main_cam.is_active = !main_cam.is_active;
|
main_cam.is_active = !main_cam.is_active;
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ use crate::{
|
|||||||
holdable::InPlayerHands,
|
holdable::InPlayerHands,
|
||||||
interactable::Interactable,
|
interactable::Interactable,
|
||||||
player::Player, proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::rapier::LinkToPlayer},
|
player::Player, proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::rapier::LinkToPlayer},
|
||||||
}, weapons::{firearm::Firearm, firearm_state::FirearmState},
|
}, weapons::{firearm::Firearm, firearm_state::FirearmState, parts::firing_point::FiringPoint},
|
||||||
},
|
},
|
||||||
logic::core::guns::{player_firing::PlayerFiringInfo},
|
logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet},
|
||||||
setup::{
|
setup::{
|
||||||
equipment::{Equipment, EquipmentChangeEvent},
|
equipment::{Equipment, EquipmentChangeEvent},
|
||||||
load_state::GameLoadState, assets::GltfAssets, //animations::AllAnimations,
|
load_state::GameLoadState, assets::GltfAssets, //animations::AllAnimations,
|
||||||
@ -21,8 +21,11 @@ use crate::{
|
|||||||
utils::{rad_deg::radians_from_degrees, hierarchy::find_child_in_parent_children},
|
utils::{rad_deg::radians_from_degrees, hierarchy::find_child_in_parent_children},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::player_settings::PlayerSettings;
|
||||||
|
|
||||||
#[derive(SystemParam)]
|
#[derive(SystemParam)]
|
||||||
pub struct CaptureHandUsageResourcesParams<'w> {
|
pub struct CaptureHandUsageResourcesParams<'w> {
|
||||||
|
player_settings: Res<'w, PlayerSettings>,
|
||||||
mouse_buttons: Res<'w, Input<MouseButton>>,
|
mouse_buttons: Res<'w, Input<MouseButton>>,
|
||||||
keyboard_input: Res<'w, Input<KeyCode>>,
|
keyboard_input: Res<'w, Input<KeyCode>>,
|
||||||
game_load_state: Res<'w, GameLoadState>,
|
game_load_state: Res<'w, GameLoadState>,
|
||||||
@ -36,37 +39,32 @@ pub struct CaptureHandUsageResourcesParams<'w> {
|
|||||||
loaded_gltf_assets: Res<'w, Assets<Gltf>>,
|
loaded_gltf_assets: Res<'w, Assets<Gltf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(SystemParam)]
|
||||||
|
pub struct CaptureHandUsageQueryParams<'w, 's> {
|
||||||
|
hand_query: Query<'w, 's, (&'static mut Transform, Entity), (With<InPlayerHandsParent>, Without<Player>)>,
|
||||||
|
in_hand_query: Query<'w, 's, (&'static Parent, &'static mut Transform), (With<InPlayerHands>, Without<InPlayerHandsParent>, Without<PlayerInventory>)>,
|
||||||
|
firearms_query: Query<'w, 's, (Entity, &'static GlobalTransform, &'static Firearm, &'static mut FirearmState),>,
|
||||||
|
firing_point_query: Query<'w, 's, (&'static GlobalTransform, &'static Parent), With<FiringPoint>>,
|
||||||
|
player_query: Query<'w, 's, (&'static Player, &'static mut PlayerInventory, Entity, &'static Transform, &'static mut PlayerFiringInfo), Without<InPlayerHands>>,
|
||||||
|
children: Query<'w, 's, &'static Children>,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
pub fn capture_hand_usage(
|
pub fn capture_hand_usage(
|
||||||
mut resources: CaptureHandUsageResourcesParams,
|
mut resources: CaptureHandUsageResourcesParams,
|
||||||
|
mut queries: CaptureHandUsageQueryParams,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|
||||||
mut hand_query: Query<(&mut Transform, Entity), (With<InPlayerHandsParent>, Without<Player>)>,
|
|
||||||
mut firearms_query: Query<
|
|
||||||
(
|
|
||||||
Entity,
|
|
||||||
&Firearm,
|
|
||||||
&FirearmState,
|
|
||||||
&GlobalTransform,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
mut player_query: Query<(&Player, &mut PlayerInventory, Entity, &Transform, &mut PlayerFiringInfo)>,
|
|
||||||
|
|
||||||
children: Query<&Children>,
|
|
||||||
|
|
||||||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||||
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
||||||
) {
|
) {
|
||||||
if !resources.game_load_state.player_loaded {
|
if !resources.game_load_state.player_loaded {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if player_query.iter().len() == 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equipping stuff
|
// Equipping stuff
|
||||||
|
|
||||||
for (player, mut player_inventory, player_entity, player_transform, mut player_firing_info) in player_query.iter_mut() {
|
for (player, mut player_inventory, player_entity, player_transform, mut player_firing_info) in queries.player_query.iter_mut() {
|
||||||
// Equipping gun
|
// Equipping gun
|
||||||
// Validate player has primary item, and secondary item in inventory
|
// Validate player has primary item, and secondary item in inventory
|
||||||
if !resources.game_ui_state.any_window() && !player_firing_info.is_reloading {
|
if !resources.game_ui_state.any_window() && !player_firing_info.is_reloading {
|
||||||
@ -102,9 +100,9 @@ pub fn capture_hand_usage(
|
|||||||
} else if resources.keyboard_input.just_pressed(KeyCode::G) {
|
} else if resources.keyboard_input.just_pressed(KeyCode::G) {
|
||||||
match player_inventory.current_slot {
|
match player_inventory.current_slot {
|
||||||
Some(current_slot) => {
|
Some(current_slot) => {
|
||||||
for (_, in_player_hands_entity) in hand_query.iter() {
|
for (_, in_player_hands_entity) in queries.hand_query.iter() {
|
||||||
for (firearm_entity, _, firearm_state, _) in firearms_query.iter() {
|
for (firearm_entity, _, _, firearm_state) in queries.firearms_query.iter() {
|
||||||
if find_child_in_parent_children(&mut commands, in_player_hands_entity, firearm_entity, &children) {
|
if find_child_in_parent_children(&mut commands, in_player_hands_entity, firearm_entity, &queries.children) {
|
||||||
player_inventory::drop_slot_in_game_world(&mut commands, player_transform, &mut inventory_changed_events, &mut player_inventory, &resources.assets_gltf, &resources.loaded_gltf_assets, current_slot, Some(ItemState::Weapon(firearm_state.clone())));
|
player_inventory::drop_slot_in_game_world(&mut commands, player_transform, &mut inventory_changed_events, &mut player_inventory, &resources.assets_gltf, &resources.loaded_gltf_assets, current_slot, Some(ItemState::Weapon(firearm_state.clone())));
|
||||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing, None));
|
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing, None));
|
||||||
player_inventory.current_slot = None;
|
player_inventory.current_slot = None;
|
||||||
@ -118,176 +116,149 @@ pub fn capture_hand_usage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Firearm stuff
|
// Firearm stuff
|
||||||
if let Equipment::Firearm(_f, _) = player.0.equipment.clone() {
|
if let Equipment::Firearm(_, _) = player.0.equipment.clone() {
|
||||||
player_firing_info
|
player_firing_info
|
||||||
.full_auto_timer
|
.full_auto_timer
|
||||||
.tick(resources.time.delta());
|
.tick(resources.time.delta());
|
||||||
|
|
||||||
for (_f, firearm_transform, _, _) in
|
for (firearm_entity, firearm_transform, firearm, mut firearm_state) in
|
||||||
firearms_query.iter_mut()
|
queries.firearms_query.iter_mut()
|
||||||
{
|
{
|
||||||
for mut hand_transform in hand_query.iter_mut() {
|
for (mut hand_transform, hand_entity) in queries.hand_query.iter_mut() {
|
||||||
if player_firing_info.is_reloading {
|
if !find_child_in_parent_children(&mut commands, hand_entity, firearm_entity, &queries.children) {
|
||||||
/* TODO:
|
continue;
|
||||||
for (animation_player_entity, animation_player) in &mut animation_players {
|
}
|
||||||
//children.get_component(entity)
|
for (in_hand_parent, mut in_hand_transform) in queries.in_hand_query.iter_mut() {
|
||||||
// Only reload if this animation_player_entity is a child of the firearm_entity
|
if in_hand_parent.get() == hand_entity {
|
||||||
if utils::hierarchy::find_child_in_parent_children(
|
if player_firing_info.is_reloading {
|
||||||
&mut commands,
|
// TODO: Here you should keep track of reload animation & time, then set player_firing_info.is_reloading = false
|
||||||
firearm_entity,
|
} else {
|
||||||
animation_player_entity,
|
// Player is not currently reloading
|
||||||
&children,
|
// TODO: Add item check (make sure he has extra mags)
|
||||||
) {
|
if resources.keyboard_input.just_pressed(KeyCode::R)
|
||||||
if let Some(firearm_animations) = resources
|
&& !resources.game_ui_state.any_window()
|
||||||
.all_animations
|
|
||||||
.firearm_animations
|
|
||||||
.iter()
|
|
||||||
.find(|animation| &animation.firearm == &player_firearm)
|
|
||||||
{
|
{
|
||||||
if let Some(animation_clip) = resources
|
if let Some(magazine_data) = &mut firearm_state.magazine_data {
|
||||||
.animation_clips
|
magazine_data.rounds_shot = 0;
|
||||||
.get(&firearm_animations.reload_magazine)
|
}
|
||||||
{
|
// TODO: start reloading
|
||||||
if animation_player.elapsed() >= animation_clip.duration() {
|
// TODO: Drop magazine in game world
|
||||||
magazine_data.rounds_shot = 0;
|
|
||||||
player_firing_info.is_reloading = false;
|
// Set is_reloading = true
|
||||||
|
}
|
||||||
|
// AIMING IN/OUT
|
||||||
|
let firearm_data = firearm.firearm_data();
|
||||||
|
|
||||||
|
let lerp_time = if player_firing_info.current_round_index > 0 { firearm_data.rebound_time_seconds } else {
|
||||||
|
if resources.time.elapsed_seconds() - player_firing_info.last_shot_timestamp > firearm_data.rebound_time_seconds * 1.5 {
|
||||||
|
firearm_data.aim_time_seconds
|
||||||
|
} else {
|
||||||
|
firearm_data.rebound_time_seconds
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if resources.mouse_buttons.pressed(MouseButton::Right)
|
||||||
|
&& !resources.game_ui_state.any_window()
|
||||||
|
{
|
||||||
|
let rotation_lerp_quat = in_hand_transform.rotation.lerp(
|
||||||
|
firearm_data.final_aimed_rotation + resources.player_settings.rot_aimed_offset,
|
||||||
|
(resources.time.delta_seconds()
|
||||||
|
/ lerp_time)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
let position_lerp_vec3 = in_hand_transform.translation.lerp(
|
||||||
|
firearm_data.final_aimed_position + resources.player_settings.pos_aimed_offset,
|
||||||
|
(resources.time.delta_seconds()
|
||||||
|
/ lerp_time)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
in_hand_transform.rotation = rotation_lerp_quat;
|
||||||
|
in_hand_transform.translation = position_lerp_vec3;
|
||||||
|
} else {
|
||||||
|
in_hand_transform.rotation = in_hand_transform.rotation.lerp(
|
||||||
|
firearm_data.rotation_offset + resources.player_settings.rot_offset,
|
||||||
|
(resources.time.delta_seconds()
|
||||||
|
/ lerp_time)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
in_hand_transform.translation = in_hand_transform.translation.lerp(
|
||||||
|
firearm_data.translation_offset + resources.player_settings.pos_offset,
|
||||||
|
(resources.time.delta_seconds()
|
||||||
|
/ lerp_time)
|
||||||
|
.clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHOOTING & RECOIL
|
||||||
|
if resources.mouse_buttons.pressed(MouseButton::Left)
|
||||||
|
&& !resources.game_ui_state.any_window()
|
||||||
|
{
|
||||||
|
if let Some(magazine_data) = &mut firearm_state.magazine_data {
|
||||||
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
|
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
||||||
|
// Get recoil numbers from patterns
|
||||||
|
let vertical_recoil_number: f32 = match firearm_data.recoil_pattern.vertical.get(player_firing_info.current_round_index) {
|
||||||
|
Some(vert_recoil_number) => *vert_recoil_number,
|
||||||
|
None => {
|
||||||
|
*firearm_data.recoil_pattern.vertical.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let horizontal_recoil_number: f32 = match firearm_data.recoil_pattern.horizontal.get(player_firing_info.current_round_index) {
|
||||||
|
Some(horizontal_recoil_number) => *horizontal_recoil_number,
|
||||||
|
None => {
|
||||||
|
*firearm_data.recoil_pattern.horizontal.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (firing_point_transform, firing_point_parent) in queries.firing_point_query.iter() {
|
||||||
|
if firing_point_parent.get() == firearm_entity {
|
||||||
|
//let firearm_transform = firearm_transform.clone();
|
||||||
|
let firing_point = firing_point_transform.translation();
|
||||||
|
let forward = firing_point_transform.forward() ;
|
||||||
|
let up = firing_point_transform.up();
|
||||||
|
shoot_bullet(
|
||||||
|
&mut commands,
|
||||||
|
&mut resources.meshes,
|
||||||
|
&mut resources.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 =
|
||||||
|
resources.time.elapsed_seconds();
|
||||||
|
player_firing_info.full_auto_timer.reset();
|
||||||
|
magazine_data.rounds_shot += 1;
|
||||||
|
|
||||||
|
// Apply recoil
|
||||||
|
in_hand_transform.rotate_x(radians_from_degrees(
|
||||||
|
//TODO: Recoil modifier firearm_data.vertical_recoil_modifier
|
||||||
|
-1.0 * 2.0
|
||||||
|
* vertical_recoil_number,
|
||||||
|
));
|
||||||
|
in_hand_transform.rotate_y(radians_from_degrees(
|
||||||
|
//TODO: Recoil modifier firearm_data.horizontal_recoil_modifier
|
||||||
|
1.0 * 0.5
|
||||||
|
* horizontal_recoil_number,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//TODO: play magazine empty sound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
}*/
|
player_firing_info.current_round_index = 0;
|
||||||
} else {
|
|
||||||
// Player is not in a reload animation
|
|
||||||
if resources.keyboard_input.just_pressed(KeyCode::R)
|
|
||||||
&& !resources.game_ui_state.any_window()
|
|
||||||
{}
|
|
||||||
/*
|
|
||||||
// Start reload animation
|
|
||||||
for (animation_player_entity, mut animation_player) in
|
|
||||||
&mut animation_players
|
|
||||||
{
|
|
||||||
// Only reload if this animation_player_entity is a child of the firearm_entity
|
|
||||||
if utils::hierarchy::find_child_in_parent_children(
|
|
||||||
&mut commands,
|
|
||||||
firearm_entity,
|
|
||||||
animation_player_entity,
|
|
||||||
&children,
|
|
||||||
) {
|
|
||||||
if let Some(firearm_animations) = resources
|
|
||||||
.all_animations
|
|
||||||
.firearm_animations
|
|
||||||
.iter()
|
|
||||||
.find(|animation| &animation.firearm == &player_firearm)
|
|
||||||
{
|
|
||||||
animation_player
|
|
||||||
.start(firearm_animations.reload_magazine.clone_weak());
|
|
||||||
player_firing_info.is_reloading = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
// Set is_reloading = true
|
|
||||||
// At the end of reload animation, set magazine data to capacity = 0
|
|
||||||
}
|
|
||||||
// AIMING IN/OUT
|
|
||||||
/*
|
|
||||||
if resources.mouse_buttons.pressed(MouseButton::Right)
|
|
||||||
&& !resources.game_ui_state.any_window()
|
|
||||||
{
|
|
||||||
let rotation_lerp_quat = hand_transform.rotation.lerp(
|
|
||||||
firearm_data.final_aimed_rotation,
|
|
||||||
(resources.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,
|
|
||||||
(resources.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,
|
|
||||||
(resources.time.delta_seconds()
|
|
||||||
/ firearm_data.rebound_time_seconds)
|
|
||||||
.clamp(0.0, 1.0),
|
|
||||||
);
|
|
||||||
hand_transform.translation = hand_transform.translation.lerp(
|
|
||||||
firearm_data.final_position,
|
|
||||||
(resources.time.delta_seconds()
|
|
||||||
/ firearm_data.rebound_time_seconds)
|
|
||||||
.clamp(0.0, 1.0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHOOTING & RECOIL
|
|
||||||
if resources.mouse_buttons.pressed(MouseButton::Left)
|
|
||||||
&& !resources.game_ui_state.any_window()
|
|
||||||
{
|
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
|
||||||
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
|
||||||
// Get recoil numbers from patterns
|
|
||||||
let vertical_recoil_number: f32 = match firearm_data.recoil_pattern.vertical.get(player_firing_info.current_round_index) {
|
|
||||||
Some(vert_recoil_number) => *vert_recoil_number,
|
|
||||||
None => {
|
|
||||||
*firearm_data.recoil_pattern.vertical.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let horizontal_recoil_number: f32 = match firearm_data.recoil_pattern.horizontal.get(player_firing_info.current_round_index) {
|
|
||||||
Some(horizontal_recoil_number) => *horizontal_recoil_number,
|
|
||||||
None => {
|
|
||||||
*firearm_data.recoil_pattern.horizontal.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let firearm_transform = firearm_transform.clone();
|
|
||||||
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 resources.meshes,
|
|
||||||
&mut resources.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 =
|
|
||||||
resources.time.elapsed_seconds();
|
|
||||||
player_firing_info.full_auto_timer.reset();
|
|
||||||
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,
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
//TODO: play magazine empty sound
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
|
||||||
player_firing_info.current_round_index = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,4 +6,5 @@ pub mod player_movement;
|
|||||||
pub mod player_values_state;
|
pub mod player_values_state;
|
||||||
pub mod player_vertical_sync;
|
pub mod player_vertical_sync;
|
||||||
pub mod animate_player;
|
pub mod animate_player;
|
||||||
pub mod camera_switching;
|
pub mod camera_switching;
|
||||||
|
pub mod player_settings;
|
32
src/logic/core/player/player_settings.rs
Normal file
32
src/logic/core/player/player_settings.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Resource, Reflect)]
|
||||||
|
#[reflect(Resource)]
|
||||||
|
pub struct PlayerSettings {
|
||||||
|
/// X Value of hand when something is equipped.
|
||||||
|
/// Applied to the object inside the hand (InPlayerHands)
|
||||||
|
//pub gun_offset: f32,
|
||||||
|
pub fov: f32,
|
||||||
|
|
||||||
|
/// Debug thing for me
|
||||||
|
pub pos_aimed_offset: Vec3,
|
||||||
|
pub pos_offset: Vec3,
|
||||||
|
|
||||||
|
pub rot_aimed_offset: Quat,
|
||||||
|
pub rot_offset: Quat,
|
||||||
|
|
||||||
|
pub third_person_toggle: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PlayerSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
fov: 0.0,
|
||||||
|
pos_aimed_offset: Vec3::ZERO,
|
||||||
|
pos_offset: Vec3::ZERO,
|
||||||
|
rot_aimed_offset: Quat::default(),
|
||||||
|
rot_offset: Quat::default(),
|
||||||
|
third_person_toggle: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -30,13 +30,13 @@ pub fn set_spawn_points(mut commands: Commands) {
|
|||||||
transform
|
transform
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
commands.spawn(Ak105SpawnPoint {
|
|
||||||
transform: {
|
commands.spawn(Ak105SpawnPoint ::new_fully_kitted_default({
|
||||||
let mut transform = Transform::from_xyz(18.0, 10.0, 18.0);
|
let mut transform = Transform::from_xyz(18.0, 10.0, 18.0);
|
||||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||||
transform
|
transform
|
||||||
},
|
}));
|
||||||
});
|
|
||||||
commands.spawn(Glock17SpawnPoint {
|
commands.spawn(Glock17SpawnPoint {
|
||||||
transform: {
|
transform: {
|
||||||
let mut transform = Transform::from_xyz(20.0, 10.0, 20.0);
|
let mut transform = Transform::from_xyz(20.0, 10.0, 20.0);
|
||||||
|
@ -26,7 +26,7 @@ pub fn editor_controls() -> EditorControls {
|
|||||||
editor_controls.insert(
|
editor_controls.insert(
|
||||||
controls::Action::PlayPauseEditor,
|
controls::Action::PlayPauseEditor,
|
||||||
controls::Binding {
|
controls::Binding {
|
||||||
input: controls::UserInput::Single(controls::Button::Keyboard(KeyCode::Back)),
|
input: controls::UserInput::Single(controls::Button::Keyboard(KeyCode::Grave)),
|
||||||
conditions: vec![controls::BindingCondition::ListeningForText(false)],
|
conditions: vec![controls::BindingCondition::ListeningForText(false)],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
player::{
|
player::{
|
||||||
camera_player_sync::MouseMovementSettings,
|
camera_player_sync::MouseMovementSettings,
|
||||||
player_movement::{PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput},
|
player_movement::{PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput},
|
||||||
player_values_state::PlayerValuesState,
|
player_values_state::PlayerValuesState, player_settings::PlayerSettings,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scenes::scene1::skybox::Cubemap,
|
scenes::scene1::skybox::Cubemap,
|
||||||
@ -34,7 +34,8 @@ pub struct MainEditorUiPlugin;
|
|||||||
|
|
||||||
impl Plugin for MainEditorUiPlugin {
|
impl Plugin for MainEditorUiPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.register_type::<PlayerFiringInfo>()
|
app
|
||||||
|
.register_type::<PlayerFiringInfo>()
|
||||||
.register_type::<PlayerValuesState>()
|
.register_type::<PlayerValuesState>()
|
||||||
.register_type::<FirearmData>()
|
.register_type::<FirearmData>()
|
||||||
.register_type::<MagazineData>()
|
.register_type::<MagazineData>()
|
||||||
@ -52,6 +53,7 @@ impl Plugin for MainEditorUiPlugin {
|
|||||||
.register_type::<PlayerMovementInput>()
|
.register_type::<PlayerMovementInput>()
|
||||||
.register_type::<Cubemap>()
|
.register_type::<Cubemap>()
|
||||||
.register_type::<FirearmState>()
|
.register_type::<FirearmState>()
|
||||||
|
.register_type::<PlayerSettings>()
|
||||||
//.register_type::<AllAnimations>()
|
//.register_type::<AllAnimations>()
|
||||||
//.register_type::<FirearmAnimations>()
|
//.register_type::<FirearmAnimations>()
|
||||||
.register_type::<GltfAssetType>()
|
.register_type::<GltfAssetType>()
|
||||||
@ -61,6 +63,7 @@ impl Plugin for MainEditorUiPlugin {
|
|||||||
.add_plugins(EguiPlugin)
|
.add_plugins(EguiPlugin)
|
||||||
.add_plugins(EditorPlugin::default())
|
.add_plugins(EditorPlugin::default())
|
||||||
.insert_resource(editor_controls())
|
.insert_resource(editor_controls())
|
||||||
|
.insert_resource(PlayerSettings::default())
|
||||||
.add_systems(PostStartup, set_cam3d_controls);
|
.add_systems(PostStartup, set_cam3d_controls);
|
||||||
//.add_plugins(ResourceInspectorPlugin::<MouseMovementSettings>::default());
|
//.add_plugins(ResourceInspectorPlugin::<MouseMovementSettings>::default());
|
||||||
//.add_plugins(bevy_inspector_egui::DefaultInspectorConfigPlugin) // adds default options and `InspectorEguiImpl`s
|
//.add_plugins(bevy_inspector_egui::DefaultInspectorConfigPlugin) // adds default options and `InspectorEguiImpl`s
|
||||||
|
@ -6,6 +6,7 @@ pub struct SettingsMenuPlugin;
|
|||||||
|
|
||||||
impl Plugin for SettingsMenuPlugin {
|
impl Plugin for SettingsMenuPlugin {
|
||||||
fn build(&self, app: &mut bevy::prelude::App) {
|
fn build(&self, app: &mut bevy::prelude::App) {
|
||||||
|
|
||||||
app.add_systems(Startup, menu::setup_settings_screen);
|
app.add_systems(Startup, menu::setup_settings_screen);
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
Update,
|
Update,
|
||||||
|
Loading…
Reference in New Issue
Block a user