use crate::app_state::battle::{BattleMovementSet, BattleUpdate};
use crate::core::collision::{BattleBoxBoundary, PhysicsCollider};
use crate::core::mod_system::BehaviorParams;
use crate::core::ui::components::UIBox;
use bevy::prelude::*;
pub(crate) struct BattleCollisionPlugin;
impl Plugin for BattleCollisionPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
constrain_player_to_battle_box_system
.after(BattleMovementSet)
.in_set(BattleUpdate),
);
}
}
#[derive(Component)]
pub struct BattleBox;
#[derive(Component, Debug, Clone)]
pub struct AmBattleBoxBounds {
pub width: f32,
pub height: f32,
pub center_offset: Vec2,
}
pub(crate) fn constrain_player_to_battle_box_system(
mut player_query: Query<
(&mut Transform, &PhysicsCollider),
(With<BehaviorParams>, Without<UIBox>),
>,
ui_battle_box_query: Query<
(&GlobalTransform, &UIBox),
(With<BattleBox>, Without<PhysicsCollider>),
>,
am_battle_box_query: Query<
(&GlobalTransform, &AmBattleBoxBounds),
(With<BattleBox>, Without<UIBox>, Without<PhysicsCollider>),
>,
) {
let boundary = if let Some((box_transform, ui_box)) = ui_battle_box_query.iter().next() {
BattleBoxBoundary::from_ui_box(
ui_box.width(),
ui_box.height(),
box_transform.translation().truncate(),
)
} else if let Some((box_transform, am_bounds)) = am_battle_box_query.iter().next() {
let center_pos = box_transform.translation().truncate() + am_bounds.center_offset;
BattleBoxBoundary::from_ui_box(am_bounds.width, am_bounds.height, center_pos)
} else {
return;
};
for (mut player_transform, physics_collider) in player_query.iter_mut() {
let current_pos = player_transform.translation.truncate();
let constrained_pos = boundary.constrain_with_collider(current_pos, physics_collider);
player_transform.translation.x = constrained_pos.x;
player_transform.translation.y = constrained_pos.y;
}
}