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::{
|
||||
grid::UGrid,
|
||||
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};
|
||||
|
||||
#[derive(Component, Clone)]
|
||||
pub struct Ak105GunItem {
|
||||
pub id: ItemId,
|
||||
pub state: Mutex<Option<ItemState>>,
|
||||
|
||||
pub initial_attachments: Option<InitialAttachments>,
|
||||
}
|
||||
|
||||
impl Item for Ak105GunItem {
|
||||
|
@ -102,6 +102,9 @@ impl Item for Ak105GunItem {
|
|||
Some(ref state) => { commands.entity(firearm_asset_entity).insert(state.clone()); },
|
||||
None => {},
|
||||
};
|
||||
if let Some(initial_attachments) = &self.initial_attachments {
|
||||
commands.entity(firearm_asset_entity).insert(initial_attachments.clone());
|
||||
}
|
||||
let firearm_size = firearm.get_size();
|
||||
commands
|
||||
.spawn((
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
use crate::{
|
||||
comps::core::{
|
||||
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},
|
||||
utils,
|
||||
setup::assets::GltfAssets,
|
||||
};
|
||||
use bevy::{gltf::Gltf, prelude::*};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[allow(unused)]
|
||||
pub enum ItemType {
|
||||
Holdable(HoldableObjectType),
|
||||
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 super::initial_attachments::InitialAttachments;
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> {
|
||||
firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, &'static Children), With<SceneInstance>>,
|
||||
firearm_query: Query<'w, 's, (Entity, &'static Firearm, &'static Parent, Option<&'static FirearmState>), Or<(Without<FirearmState>, Changed<FirearmState>)>>,
|
||||
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 mut FirearmState>), Or<(Without<FirearmState>, Changed<FirearmState>)>>,
|
||||
slots_query: Query<'w, 's, (Entity, &'static WeaponSlot, &'static Parent)>,
|
||||
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
||||
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,
|
||||
/// 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(
|
||||
// needed for tri meshes
|
||||
queries: InsertFirearmStateIntoFirearmsParams,
|
||||
mut queries: InsertFirearmStateIntoFirearmsParams,
|
||||
assets_gltf: Res<GltfAssets>,
|
||||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||
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 (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 let Some(item_state) = item_state_opt {
|
||||
// Firearm State is already created and item is being spawned again into world
|
||||
#[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>();
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
commands
|
||||
.entity(firearm_entity)
|
||||
.insert(firearm_state.clone());
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
.insert(firearm_state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match firearm_state_opt {
|
||||
Some(firearm_state) => {
|
||||
Some(mut firearm_state) => {
|
||||
// Change the Slots
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
//TODO: Change firearm state inside inventory
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
for in_player_hands_item_id in queries.in_player_hands_query.iter() {
|
||||
for player_inventory in queries.player_inventories_query.iter() {
|
||||
if let Some(current_item) = player_inventory.get_current_slot_item() {
|
||||
|
@ -56,6 +58,7 @@ pub fn insert_firearm_state_to_firearms(
|
|||
None => {
|
||||
// Create the firearm_state
|
||||
let mut firearm_slots = Vec::new();
|
||||
let magazine_data = None;
|
||||
for (slot_entity, slot, parent_entity) in queries.slots_query.iter() {
|
||||
if firearm_entity == parent_entity.get() {
|
||||
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
|
||||
.entity(firearm_entity)
|
||||
.insert(firearm_state.clone());
|
||||
|
@ -85,7 +94,7 @@ pub fn insert_firearm_state_to_firearms(
|
|||
fn spawn_attachments_in_firearm(
|
||||
commands: &mut Commands,
|
||||
firearm_entity: Entity,
|
||||
firearm_state: &FirearmState,
|
||||
firearm_state: &mut FirearmState,
|
||||
slots_query: &Query<(Entity, &WeaponSlot, &Parent)>,
|
||||
assets_gltf: &GltfAssets,
|
||||
loaded_gltf_assets: &Assets<Gltf>,
|
||||
|
@ -112,6 +121,11 @@ fn spawn_attachments_in_firearm(
|
|||
commands.entity(slot_entity).add_child(
|
||||
scene_bundle
|
||||
);
|
||||
if let None = &firearm_state.magazine_data {
|
||||
if let WeaponAttachment::Magazine(magazine) = attachment {
|
||||
firearm_state.magazine_data = Some(magazine.magazine_data());
|
||||
}
|
||||
}
|
||||
}},
|
||||
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::{
|
||||
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)]
|
||||
pub struct Ak105SpawnPoint {
|
||||
pub transform: Transform,
|
||||
pub attachments: Vec<WeaponAttachment>
|
||||
}
|
||||
|
||||
impl ItemSpawnPoint for Ak105SpawnPoint {
|
||||
|
@ -18,6 +19,32 @@ impl ItemSpawnPoint for Ak105SpawnPoint {
|
|||
}
|
||||
|
||||
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 crate::comps::core::weapons::magazine_data::MagazineData;
|
||||
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Component, Debug, Default)]
|
||||
#[reflect(Component, Default)]
|
||||
|
@ -9,7 +11,10 @@ pub enum 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 {
|
||||
Magazine::Ak105 => 30,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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};
|
||||
|
||||
#[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_rotation: Quat::default(),
|
||||
rotation_offset: Quat::default(),
|
||||
final_aimed_position: Vec3 {
|
||||
// x: -0.003,
|
||||
// y: -0.35,
|
||||
|
@ -50,7 +50,7 @@ impl Firearm {
|
|||
y: -0.35,
|
||||
z: -1.6,
|
||||
},
|
||||
final_position: Vec3::ZERO, /*Vec3 {
|
||||
translation_offset: Vec3::ZERO, /*Vec3 {
|
||||
x: 0.6,
|
||||
y: -0.45,
|
||||
z: -2.7,
|
||||
|
@ -64,7 +64,8 @@ impl Firearm {
|
|||
FirearmData {
|
||||
caliber: Caliber::Parabellum9mm,
|
||||
fire_rate: 600.0,
|
||||
rebound_time_seconds: 0.1,
|
||||
aim_time_seconds: 0.1,
|
||||
rebound_time_seconds: 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
|
||||
|
@ -75,7 +76,7 @@ impl Firearm {
|
|||
},
|
||||
|
||||
final_aimed_rotation: Quat::from_rotation_x(0.026),
|
||||
final_rotation: Quat::default(),
|
||||
rotation_offset: Quat::default(),
|
||||
final_aimed_position: Vec3 {
|
||||
// x: -0.003,
|
||||
// y: -0.35,
|
||||
|
@ -84,7 +85,7 @@ impl Firearm {
|
|||
y: -0.5,
|
||||
z: -1.6,
|
||||
},
|
||||
final_position: Vec3 {
|
||||
translation_offset: Vec3 {
|
||||
x: 1.0,
|
||||
y: -0.45,
|
||||
z: -2.7,
|
||||
|
@ -97,7 +98,8 @@ impl Firearm {
|
|||
Firearm::Ak105 => FirearmData {
|
||||
caliber: Caliber::RU545,
|
||||
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"),
|
||||
recoil_pattern: FirearmSprayPattern {
|
||||
vertical: Vec::from([
|
||||
|
@ -108,10 +110,10 @@ impl Firearm {
|
|||
]),
|
||||
},
|
||||
final_aimed_rotation: Quat::default(),
|
||||
final_rotation: Quat::default(),
|
||||
final_aimed_position: Vec3::ZERO,
|
||||
final_position: Vec3::ZERO,
|
||||
scale_factor: 0.3,
|
||||
rotation_offset: Quat::default(),
|
||||
final_aimed_position: Vec3 { x: 0.016, y: 0.0, z: -0.1 },
|
||||
translation_offset: Vec3 { x: -0.2, y: -0.03, z: 0.0 },
|
||||
scale_factor: 0.2,
|
||||
firearm_type: FirearmType::Primary,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,19 +9,20 @@ pub struct FirearmData {
|
|||
pub caliber: Caliber,
|
||||
/// Rounds per minute
|
||||
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
|
||||
/// Also is the time it takes for the gun to aim in or aim out.
|
||||
pub rebound_time_seconds: f32,
|
||||
pub asset_path: String,
|
||||
pub recoil_pattern: FirearmSprayPattern,
|
||||
/// Final rotation of hands when aimed in
|
||||
pub final_aimed_rotation: Quat,
|
||||
/// Final rotation of hands when not aimed in
|
||||
pub final_rotation: Quat,
|
||||
pub rotation_offset: Quat,
|
||||
/// Final position of hands when aimed in
|
||||
pub final_aimed_position: Vec3,
|
||||
/// Final position of hands when not aimed in
|
||||
pub final_position: Vec3,
|
||||
pub translation_offset: Vec3,
|
||||
pub scale_factor: f32,
|
||||
pub firearm_type: FirearmType,
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
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)]
|
||||
pub struct FirearmState {
|
||||
pub attachment_slots: Vec<AttachmentSlot>,
|
||||
pub magazine_data: Option<MagazineData>,
|
||||
}
|
||||
|
||||
impl FirearmState {
|
||||
pub fn new(attachment_slots: Vec<AttachmentSlot>) -> Self {
|
||||
Self { attachment_slots }
|
||||
pub fn new(attachment_slots: Vec<AttachmentSlot>, magazine_data: Option<MagazineData>) -> Self {
|
||||
Self { attachment_slots, magazine_data: None }
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ pub fn switch_camera(
|
|||
keyboard_input: Res<Input<KeyCode>>,
|
||||
) {
|
||||
if keyboard_input.just_pressed(KeyCode::Key0) {
|
||||
return;
|
||||
for mut main_cam in main_camera_query.iter_mut() {
|
||||
main_cam.is_active = !main_cam.is_active;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ use crate::{
|
|||
holdable::InPlayerHands,
|
||||
interactable::Interactable,
|
||||
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::{
|
||||
equipment::{Equipment, EquipmentChangeEvent},
|
||||
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},
|
||||
};
|
||||
|
||||
use super::player_settings::PlayerSettings;
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct CaptureHandUsageResourcesParams<'w> {
|
||||
player_settings: Res<'w, PlayerSettings>,
|
||||
mouse_buttons: Res<'w, Input<MouseButton>>,
|
||||
keyboard_input: Res<'w, Input<KeyCode>>,
|
||||
game_load_state: Res<'w, GameLoadState>,
|
||||
|
@ -36,37 +39,32 @@ pub struct CaptureHandUsageResourcesParams<'w> {
|
|||
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)]
|
||||
pub fn capture_hand_usage(
|
||||
mut resources: CaptureHandUsageResourcesParams,
|
||||
mut queries: CaptureHandUsageQueryParams,
|
||||
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 inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
||||
) {
|
||||
if !resources.game_load_state.player_loaded {
|
||||
return;
|
||||
}
|
||||
if player_query.iter().len() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
// Validate player has primary item, and secondary item in inventory
|
||||
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) {
|
||||
match player_inventory.current_slot {
|
||||
Some(current_slot) => {
|
||||
for (_, in_player_hands_entity) in hand_query.iter() {
|
||||
for (firearm_entity, _, firearm_state, _) in firearms_query.iter() {
|
||||
if find_child_in_parent_children(&mut commands, in_player_hands_entity, firearm_entity, &children) {
|
||||
for (_, in_player_hands_entity) in queries.hand_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, &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())));
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing, None));
|
||||
player_inventory.current_slot = None;
|
||||
|
@ -118,176 +116,149 @@ pub fn capture_hand_usage(
|
|||
}
|
||||
|
||||
// Firearm stuff
|
||||
if let Equipment::Firearm(_f, _) = player.0.equipment.clone() {
|
||||
if let Equipment::Firearm(_, _) = player.0.equipment.clone() {
|
||||
player_firing_info
|
||||
.full_auto_timer
|
||||
.tick(resources.time.delta());
|
||||
|
||||
for (_f, firearm_transform, _, _) in
|
||||
firearms_query.iter_mut()
|
||||
for (firearm_entity, firearm_transform, firearm, mut firearm_state) in
|
||||
queries.firearms_query.iter_mut()
|
||||
{
|
||||
for mut hand_transform in hand_query.iter_mut() {
|
||||
if player_firing_info.is_reloading {
|
||||
/* TODO:
|
||||
for (animation_player_entity, animation_player) in &mut animation_players {
|
||||
//children.get_component(entity)
|
||||
// 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)
|
||||
for (mut hand_transform, hand_entity) in queries.hand_query.iter_mut() {
|
||||
if !find_child_in_parent_children(&mut commands, hand_entity, firearm_entity, &queries.children) {
|
||||
continue;
|
||||
}
|
||||
for (in_hand_parent, mut in_hand_transform) in queries.in_hand_query.iter_mut() {
|
||||
if in_hand_parent.get() == hand_entity {
|
||||
if player_firing_info.is_reloading {
|
||||
// TODO: Here you should keep track of reload animation & time, then set player_firing_info.is_reloading = false
|
||||
} else {
|
||||
// Player is not currently reloading
|
||||
// TODO: Add item check (make sure he has extra mags)
|
||||
if resources.keyboard_input.just_pressed(KeyCode::R)
|
||||
&& !resources.game_ui_state.any_window()
|
||||
{
|
||||
if let Some(animation_clip) = resources
|
||||
.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;
|
||||
if let Some(magazine_data) = &mut firearm_state.magazine_data {
|
||||
magazine_data.rounds_shot = 0;
|
||||
}
|
||||
// TODO: start reloading
|
||||
// TODO: Drop magazine in game world
|
||||
|
||||
// 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 {
|
||||
// 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;
|
||||
} else {
|
||||
if player_firing_info.full_auto_timer.finished() {
|
||||
player_firing_info.current_round_index = 0;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
// 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_vertical_sync;
|
||||
pub mod animate_player;
|
||||
pub mod camera_switching;
|
||||
pub mod camera_switching;
|
||||
pub mod player_settings;
|
|
@ -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
|
||||
},
|
||||
});
|
||||
commands.spawn(Ak105SpawnPoint {
|
||||
transform: {
|
||||
let mut transform = Transform::from_xyz(18.0, 10.0, 18.0);
|
||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||
transform
|
||||
},
|
||||
});
|
||||
|
||||
commands.spawn(Ak105SpawnPoint ::new_fully_kitted_default({
|
||||
let mut transform = Transform::from_xyz(18.0, 10.0, 18.0);
|
||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||
transform
|
||||
}));
|
||||
|
||||
commands.spawn(Glock17SpawnPoint {
|
||||
transform: {
|
||||
let mut transform = Transform::from_xyz(20.0, 10.0, 20.0);
|
||||
|
|
|
@ -26,7 +26,7 @@ pub fn editor_controls() -> EditorControls {
|
|||
editor_controls.insert(
|
||||
controls::Action::PlayPauseEditor,
|
||||
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)],
|
||||
},
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
player::{
|
||||
camera_player_sync::MouseMovementSettings,
|
||||
player_movement::{PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput},
|
||||
player_values_state::PlayerValuesState,
|
||||
player_values_state::PlayerValuesState, player_settings::PlayerSettings,
|
||||
},
|
||||
},
|
||||
scenes::scene1::skybox::Cubemap,
|
||||
|
@ -34,7 +34,8 @@ pub struct MainEditorUiPlugin;
|
|||
|
||||
impl Plugin for MainEditorUiPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.register_type::<PlayerFiringInfo>()
|
||||
app
|
||||
.register_type::<PlayerFiringInfo>()
|
||||
.register_type::<PlayerValuesState>()
|
||||
.register_type::<FirearmData>()
|
||||
.register_type::<MagazineData>()
|
||||
|
@ -52,6 +53,7 @@ impl Plugin for MainEditorUiPlugin {
|
|||
.register_type::<PlayerMovementInput>()
|
||||
.register_type::<Cubemap>()
|
||||
.register_type::<FirearmState>()
|
||||
.register_type::<PlayerSettings>()
|
||||
//.register_type::<AllAnimations>()
|
||||
//.register_type::<FirearmAnimations>()
|
||||
.register_type::<GltfAssetType>()
|
||||
|
@ -61,6 +63,7 @@ impl Plugin for MainEditorUiPlugin {
|
|||
.add_plugins(EguiPlugin)
|
||||
.add_plugins(EditorPlugin::default())
|
||||
.insert_resource(editor_controls())
|
||||
.insert_resource(PlayerSettings::default())
|
||||
.add_systems(PostStartup, set_cam3d_controls);
|
||||
//.add_plugins(ResourceInspectorPlugin::<MouseMovementSettings>::default());
|
||||
//.add_plugins(bevy_inspector_egui::DefaultInspectorConfigPlugin) // adds default options and `InspectorEguiImpl`s
|
||||
|
|
|
@ -6,6 +6,7 @@ pub struct SettingsMenuPlugin;
|
|||
|
||||
impl Plugin for SettingsMenuPlugin {
|
||||
fn build(&self, app: &mut bevy::prelude::App) {
|
||||
|
||||
app.add_systems(Startup, menu::setup_settings_screen);
|
||||
app.add_systems(
|
||||
Update,
|
||||
|
|
Loading…
Reference in New Issue