Bevy 0.17 Migration Final PR (#76)
* Get bevy 0.17 compiling and running (#72) * get bevy 0.17 compiling and running * try to fix CI breaking from const assertion for client/server features * fix `bin` -> `lib` for `shared` in CI * typo * fix some collider issues (#73) * Physics/controller improvements (#74) * trying to fix physics prediction * fixed prediction desync * substantial controller improvements * Finish off main bevy 0.17 migration (#75) * fix lookdir issues - airplane moving backwards - player model facing backwards - camera was technically backwards the whole time, and player models were facing the right way; camera is now facing forwards - firing without a target now respects lookdir * fix aim targeting * migrate to bevy_trenchbroom 0.10 crates release * fixed colliders not being adjusted out of worldspace * predict platforms to stop constant rollbacks while riding them * fix key/head drop visuals not working * Fix key/head drop random initial force * fixed static head drops duplicating * fix platform velocity inheritance * fix thrown projectiles not autorotating * fix inconsistent explosion animations * update avian3d to 0.4.1 * fix controller snapping to fixed angle upon switching heads * clean up commented code * fix broken physics positions * Clean comments, fix warnings (#77) * clean comments, fix warnings * fix missing import * steamworks 162 libs * fix mouselook --------- Co-authored-by: extrawurst <mail@rusticorn.com>
This commit is contained in:
@@ -5,9 +5,8 @@ use crate::{
|
||||
utils::sprite_3d_animation::AnimationTimer,
|
||||
};
|
||||
use avian3d::prelude::*;
|
||||
use bevy::{pbr::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
|
||||
use std::f32::consts::PI;
|
||||
use bevy::{light::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::Sprite3d;
|
||||
|
||||
#[derive(Component)]
|
||||
struct ArrowProjectile {
|
||||
@@ -27,18 +26,18 @@ pub fn plugin(app: &mut App) {
|
||||
global_observer!(app, on_trigger_arrow);
|
||||
}
|
||||
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) {
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, asset_server: Res<AssetServer>) {
|
||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(256), 7, 6, None, None);
|
||||
let texture_atlas_layout = sprite_params.atlas_layouts.add(layout);
|
||||
let layout = asset_server.add(layout);
|
||||
|
||||
commands.insert_resource(ShotAssets {
|
||||
image: assets.impact_atlas.clone(),
|
||||
layout: texture_atlas_layout,
|
||||
layout,
|
||||
});
|
||||
}
|
||||
|
||||
fn on_trigger_arrow(
|
||||
trigger: Trigger<TriggerArrow>,
|
||||
trigger: On<TriggerArrow>,
|
||||
mut commands: Commands,
|
||||
query_transform: Query<&Transform>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
@@ -55,7 +54,7 @@ fn on_trigger_arrow(
|
||||
.looking_at(t.translation, Vec3::Y)
|
||||
.rotation
|
||||
} else {
|
||||
state.rot.mul_quat(Quat::from_rotation_y(PI))
|
||||
state.rot()
|
||||
};
|
||||
|
||||
let mut transform = Transform::from_translation(state.pos).with_rotation(rotation);
|
||||
@@ -74,7 +73,6 @@ fn update(
|
||||
query: Query<(Entity, &Transform, &ArrowProjectile)>,
|
||||
spatial_query: SpatialQuery,
|
||||
assets: Res<ShotAssets>,
|
||||
mut sprite_params: Sprite3dParams,
|
||||
) {
|
||||
for (e, t, arrow) in query.iter() {
|
||||
let filter = SpatialQueryFilter::from_mask(LayerMask(
|
||||
@@ -89,26 +87,27 @@ fn update(
|
||||
&ShapeCastConfig::from_max_distance(150.),
|
||||
&filter,
|
||||
) {
|
||||
cmds.entity(first_hit.entity).trigger(Hit {
|
||||
cmds.trigger(Hit {
|
||||
damage: arrow.damage,
|
||||
entity: first_hit.entity,
|
||||
});
|
||||
|
||||
cmds.spawn(
|
||||
Sprite3dBuilder {
|
||||
image: assets.image.clone(),
|
||||
cmds.spawn((
|
||||
Sprite3d {
|
||||
pixels_per_metre: 128.,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
unlit: true,
|
||||
..default()
|
||||
}
|
||||
.bundle_with_atlas(
|
||||
&mut sprite_params,
|
||||
TextureAtlas {
|
||||
},
|
||||
Sprite {
|
||||
image: assets.image.clone(),
|
||||
texture_atlas: Some(TextureAtlas {
|
||||
layout: assets.layout.clone(),
|
||||
index: 0,
|
||||
},
|
||||
),
|
||||
)
|
||||
}),
|
||||
..default()
|
||||
},
|
||||
))
|
||||
.insert((
|
||||
Billboard::All,
|
||||
Transform::from_translation(first_hit.point1),
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn plugin(app: &mut App) {
|
||||
}
|
||||
|
||||
fn on_trigger_missile(
|
||||
trigger: Trigger<TriggerCurver>,
|
||||
trigger: On<TriggerCurver>,
|
||||
mut commands: Commands,
|
||||
query_transform: Query<&Transform>,
|
||||
time: Res<Time>,
|
||||
@@ -52,7 +52,7 @@ fn on_trigger_missile(
|
||||
.looking_at(t.translation, Vec3::Y)
|
||||
.rotation
|
||||
} else {
|
||||
state.rot.mul_quat(Quat::from_rotation_y(PI))
|
||||
state.rot()
|
||||
};
|
||||
|
||||
let head = heads_db.head_stats(state.head);
|
||||
@@ -88,11 +88,16 @@ fn on_trigger_missile(
|
||||
|
||||
fn enemy_hit(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<&CurverProjectile>,
|
||||
query_npc: Query<&EnemySpawn>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
@@ -108,7 +113,9 @@ fn enemy_hit(
|
||||
|
||||
if let Ok(projectile) = projectile {
|
||||
let damage = projectile.damage;
|
||||
commands.entity(enemy_entity).trigger(Hit { damage });
|
||||
commands
|
||||
.entity(enemy_entity)
|
||||
.trigger(|entity| Hit { entity, damage });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,11 +139,16 @@ fn timeout(mut commands: Commands, query: Query<(Entity, &CurverProjectile)>, ti
|
||||
|
||||
fn shot_collision(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<&Transform, With<CurverProjectile>>,
|
||||
sensors: Query<(), With<Sensor>>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,8 @@ use crate::{
|
||||
tb_entities::EnemySpawn, utils::sprite_3d_animation::AnimationTimer,
|
||||
};
|
||||
use avian3d::prelude::*;
|
||||
use bevy::{pbr::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
|
||||
use std::f32::consts::PI;
|
||||
use bevy::{light::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::Sprite3d;
|
||||
|
||||
#[derive(Component)]
|
||||
struct GunProjectile {
|
||||
@@ -37,9 +36,9 @@ pub fn plugin(app: &mut App) {
|
||||
global_observer!(app, on_trigger_gun);
|
||||
}
|
||||
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) {
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, asset_server: Res<AssetServer>) {
|
||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(256), 7, 6, None, None);
|
||||
let texture_atlas_layout = sprite_params.atlas_layouts.add(layout);
|
||||
let texture_atlas_layout = asset_server.add(layout);
|
||||
|
||||
commands.insert_resource(ShotAssets {
|
||||
image: assets.impact_atlas.clone(),
|
||||
@@ -49,12 +48,17 @@ fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Spr
|
||||
|
||||
fn enemy_hit(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<&GunProjectile>,
|
||||
query_npc: Query<&EnemySpawn>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
@@ -70,13 +74,16 @@ fn enemy_hit(
|
||||
|
||||
if let Ok(head) = projectile.map(|p| p.owner_head) {
|
||||
let damage = heads_db.head_stats(head).damage;
|
||||
commands.entity(enemy_entity).trigger(Hit { damage });
|
||||
commands.trigger(Hit {
|
||||
damage,
|
||||
entity: enemy_entity,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_trigger_gun(
|
||||
trigger: Trigger<TriggerGun>,
|
||||
trigger: On<TriggerGun>,
|
||||
mut commands: Commands,
|
||||
query_transform: Query<&Transform>,
|
||||
time: Res<Time>,
|
||||
@@ -94,7 +101,7 @@ fn on_trigger_gun(
|
||||
.looking_at(t.translation, Vec3::Y)
|
||||
.rotation
|
||||
} else {
|
||||
state.rot.mul_quat(Quat::from_rotation_y(PI))
|
||||
state.rot()
|
||||
};
|
||||
|
||||
let mut transform = Transform::from_translation(state.pos).with_rotation(rotation);
|
||||
@@ -149,13 +156,17 @@ fn timeout(mut commands: Commands, query: Query<(Entity, &GunProjectile)>, time:
|
||||
|
||||
fn shot_collision(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<(&GunProjectile, &Transform)>,
|
||||
sensors: Query<(), With<Sensor>>,
|
||||
assets: Res<ShotAssets>,
|
||||
mut sprite_params: Sprite3dParams,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
@@ -180,16 +191,19 @@ fn shot_collision(
|
||||
};
|
||||
|
||||
commands
|
||||
.spawn(
|
||||
Sprite3dBuilder {
|
||||
image: assets.image.clone(),
|
||||
.spawn((
|
||||
Sprite3d {
|
||||
pixels_per_metre: 128.,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
unlit: true,
|
||||
..default()
|
||||
}
|
||||
.bundle_with_atlas(&mut sprite_params, texture_atlas),
|
||||
)
|
||||
},
|
||||
Sprite {
|
||||
image: assets.image.clone(),
|
||||
texture_atlas: Some(texture_atlas),
|
||||
..default()
|
||||
},
|
||||
))
|
||||
.insert((
|
||||
Billboard::All,
|
||||
Transform::from_translation(shot_pos),
|
||||
|
||||
@@ -8,8 +8,14 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Component, Serialize, Deserialize, PartialEq)]
|
||||
pub struct Healing;
|
||||
|
||||
#[derive(Clone, Event, Debug, Serialize, Deserialize)]
|
||||
pub enum HealingStateChanged {
|
||||
#[derive(Clone, EntityEvent, Debug, Serialize, Deserialize)]
|
||||
pub struct HealingStateChanged {
|
||||
pub entity: Entity,
|
||||
pub state: HealingState,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum HealingState {
|
||||
Started,
|
||||
Stopped,
|
||||
}
|
||||
@@ -21,24 +27,24 @@ pub fn plugin(app: &mut App) {
|
||||
}
|
||||
|
||||
fn on_heal_start_stop(
|
||||
trigger: Trigger<HealingStateChanged>,
|
||||
trigger: On<HealingStateChanged>,
|
||||
mut cmds: Commands,
|
||||
query: Query<&Healing>,
|
||||
) {
|
||||
if matches!(trigger.event(), HealingStateChanged::Started) {
|
||||
if query.contains(trigger.target()) {
|
||||
if matches!(trigger.event().state, HealingState::Started) {
|
||||
if query.contains(trigger.event().entity) {
|
||||
// already healing, just ignore
|
||||
return;
|
||||
}
|
||||
|
||||
cmds.entity(trigger.target()).insert(Healing);
|
||||
cmds.entity(trigger.event().entity).insert(Healing);
|
||||
} else {
|
||||
if !query.contains(trigger.target()) {
|
||||
if !query.contains(trigger.event().entity) {
|
||||
// Not healing, just ignore
|
||||
return;
|
||||
}
|
||||
|
||||
cmds.entity(trigger.target()).remove::<Healing>();
|
||||
cmds.entity(trigger.event().entity).remove::<Healing>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn plugin(app: &mut App) {
|
||||
}
|
||||
|
||||
fn on_trigger_missile(
|
||||
trigger: Trigger<TriggerMissile>,
|
||||
trigger: On<TriggerMissile>,
|
||||
mut commands: Commands,
|
||||
query_transform: Query<&Transform>,
|
||||
time: Res<Time>,
|
||||
@@ -53,7 +53,7 @@ fn on_trigger_missile(
|
||||
.looking_at(t.translation, Vec3::Y)
|
||||
.rotation
|
||||
} else {
|
||||
state.rot.mul_quat(Quat::from_rotation_y(PI))
|
||||
state.rot()
|
||||
};
|
||||
|
||||
let head = heads_db.head_stats(state.head);
|
||||
@@ -122,11 +122,16 @@ fn timeout(mut commands: Commands, query: Query<(Entity, &MissileProjectile)>, t
|
||||
|
||||
fn shot_collision(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<(&MissileProjectile, &Transform)>,
|
||||
sensors: Query<(), With<Sensor>>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -14,17 +14,12 @@ use crate::{
|
||||
};
|
||||
#[cfg(feature = "server")]
|
||||
use crate::{
|
||||
aim::AimTarget,
|
||||
character::CharacterHierarchy,
|
||||
control::ControlState,
|
||||
head::ActiveHead,
|
||||
heads::ActiveHeads,
|
||||
heads_database::HeadsDatabase,
|
||||
player::{Player, PlayerBodyMesh},
|
||||
aim::AimTarget, character::CharacterHierarchy, control::ControlState, head::ActiveHead,
|
||||
heads::ActiveHeads, heads_database::HeadsDatabase, player::Player,
|
||||
utils::explosions::Explosion,
|
||||
};
|
||||
use bevy::{pbr::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
|
||||
use bevy::{light::NotShadowCaster, prelude::*};
|
||||
use bevy_sprite3d::Sprite3d;
|
||||
pub use healing::Healing;
|
||||
#[cfg(feature = "server")]
|
||||
use healing::HealingStateChanged;
|
||||
@@ -51,7 +46,6 @@ pub enum HeadAbility {
|
||||
pub struct TriggerData {
|
||||
target: Option<Entity>,
|
||||
dir: Dir3,
|
||||
rot: Quat,
|
||||
pos: Vec3,
|
||||
target_layer: GameLayer,
|
||||
head: usize,
|
||||
@@ -61,7 +55,6 @@ impl TriggerData {
|
||||
pub fn new(
|
||||
target: Option<Entity>,
|
||||
dir: Dir3,
|
||||
rot: Quat,
|
||||
pos: Vec3,
|
||||
target_layer: GameLayer,
|
||||
head: usize,
|
||||
@@ -69,12 +62,17 @@ impl TriggerData {
|
||||
Self {
|
||||
target,
|
||||
dir,
|
||||
rot,
|
||||
pos,
|
||||
target_layer,
|
||||
head,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rot(&self) -> Quat {
|
||||
// as it turns out, `glam` comes with some `looking_to` functions for left and right handed coordinate systems, but it seems like they're wrong?
|
||||
// at the very least they give some very odd results and the cross multiplications inside all look backwards compared to what bevy transforms do.
|
||||
Transform::default().looking_to(self.dir, Vec3::Y).rotation
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Event, Reflect)]
|
||||
@@ -205,8 +203,7 @@ fn on_trigger_state(
|
||||
fn update(
|
||||
mut res: ResMut<TriggerStateRes>,
|
||||
mut commands: Commands,
|
||||
player_rot: Query<&Transform, With<PlayerBodyMesh>>,
|
||||
player_query: Query<(Entity, &AimTarget), With<Player>>,
|
||||
player_query: Query<(Entity, &AimTarget, &ActionState<ControlState>), With<Player>>,
|
||||
mut active_heads: Single<&mut ActiveHeads, With<Player>>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
time: Res<Time>,
|
||||
@@ -222,7 +219,7 @@ fn update(
|
||||
return;
|
||||
}
|
||||
|
||||
let Some((player, target)) = player_query.iter().next() else {
|
||||
let Some((player, target, actions)) = player_query.iter().next() else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -233,10 +230,6 @@ fn update(
|
||||
return;
|
||||
};
|
||||
|
||||
let Some((rot, dir)) = player_rot.iter().next().map(|t| (t.rotation, t.forward())) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let head = heads_db.head_stats(state.head);
|
||||
|
||||
if matches!(head.ability, HeadAbility::None | HeadAbility::Medic) {
|
||||
@@ -248,8 +241,7 @@ fn update(
|
||||
res.next_trigger_timestamp = time.elapsed_secs() + (1. / head.aps);
|
||||
|
||||
let trigger_state = TriggerData {
|
||||
dir,
|
||||
rot,
|
||||
dir: actions.look_dir,
|
||||
pos: projectile_origin,
|
||||
target: target.0,
|
||||
target_layer: GameLayer::Npc,
|
||||
@@ -287,10 +279,17 @@ fn update_heal_ability(
|
||||
return;
|
||||
}
|
||||
|
||||
use crate::abilities::healing::HealingState;
|
||||
if res.active {
|
||||
commands.trigger_targets(HealingStateChanged::Started, player);
|
||||
commands.trigger(HealingStateChanged {
|
||||
state: HealingState::Started,
|
||||
entity: player,
|
||||
});
|
||||
} else {
|
||||
commands.trigger_targets(HealingStateChanged::Stopped, player);
|
||||
commands.trigger(HealingStateChanged {
|
||||
state: HealingState::Stopped,
|
||||
entity: player,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,9 +300,9 @@ struct ShotAssets {
|
||||
layout: Handle<TextureAtlasLayout>,
|
||||
}
|
||||
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) {
|
||||
fn setup(mut commands: Commands, assets: Res<GameAssets>, asset_server: Res<AssetServer>) {
|
||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(256), 7, 6, None, None);
|
||||
let texture_atlas_layout = sprite_params.atlas_layouts.add(layout);
|
||||
let texture_atlas_layout = asset_server.add(layout);
|
||||
|
||||
commands.insert_resource(ShotAssets {
|
||||
image: assets.impact_atlas.clone(),
|
||||
@@ -319,27 +318,26 @@ pub struct BuildExplosionSprite {
|
||||
}
|
||||
|
||||
fn build_explosion_sprite(
|
||||
trigger: Trigger<BuildExplosionSprite>,
|
||||
trigger: On<BuildExplosionSprite>,
|
||||
mut commands: Commands,
|
||||
assets: Res<ShotAssets>,
|
||||
mut sprite_params: Sprite3dParams,
|
||||
) {
|
||||
commands.spawn((
|
||||
Transform::from_translation(trigger.event().pos),
|
||||
Sprite3dBuilder {
|
||||
image: assets.image.clone(),
|
||||
Sprite3d {
|
||||
pixels_per_metre: trigger.event().pixels_per_meter,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
unlit: true,
|
||||
..default()
|
||||
}
|
||||
.bundle_with_atlas(
|
||||
&mut sprite_params,
|
||||
TextureAtlas {
|
||||
},
|
||||
Sprite {
|
||||
image: assets.image.clone(),
|
||||
texture_atlas: Some(TextureAtlas {
|
||||
layout: assets.layout.clone(),
|
||||
index: 0,
|
||||
},
|
||||
),
|
||||
}),
|
||||
..default()
|
||||
},
|
||||
Billboard::All,
|
||||
NotShadowCaster,
|
||||
AnimationTimer::new(Timer::from_seconds(
|
||||
|
||||
@@ -12,7 +12,6 @@ use bevy_ballistic::launch_velocity;
|
||||
#[cfg(feature = "server")]
|
||||
use lightyear::prelude::{NetworkTarget, Replicate};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
#[derive(Component, Serialize, Deserialize, PartialEq)]
|
||||
pub struct ThrownProjectile {
|
||||
@@ -30,7 +29,7 @@ pub fn plugin(app: &mut App) {
|
||||
}
|
||||
|
||||
fn on_trigger_thrown(
|
||||
trigger: Trigger<TriggerThrow>,
|
||||
trigger: On<TriggerThrow>,
|
||||
mut commands: Commands,
|
||||
query_transform: Query<&Transform>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
@@ -50,8 +49,7 @@ fn on_trigger_thrown(
|
||||
.map(|(low, _)| low)
|
||||
.unwrap()
|
||||
} else {
|
||||
state.rot.mul_quat(Quat::from_rotation_y(-PI / 2.))
|
||||
* (Vec3::new(2., 1., 0.).normalize() * SPEED)
|
||||
((state.dir.as_vec3() * 2.0) + Vec3::Y).normalize() * SPEED
|
||||
};
|
||||
|
||||
let head = heads_db.head_stats(state.head);
|
||||
@@ -89,11 +87,16 @@ fn on_trigger_thrown(
|
||||
|
||||
fn shot_collision(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
mut collision_message_reader: MessageReader<CollisionStart>,
|
||||
query_shot: Query<(&ThrownProjectile, &Transform)>,
|
||||
sensors: Query<(), With<Sensor>>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
for CollisionStart {
|
||||
collider1: e1,
|
||||
collider2: e2,
|
||||
..
|
||||
} in collision_message_reader.read()
|
||||
{
|
||||
if !query_shot.contains(*e1) && !query_shot.contains(*e2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user