generated from 2ndbeam/bevy-template
- Layout is now defined from bottom left corner - Added rotation to lockpick bundle - Added level TOML structures that match current level
143 lines
4.6 KiB
Rust
143 lines
4.6 KiB
Rust
use bevy::{
|
|
ecs::query::QueryFilter,
|
|
prelude::*,
|
|
};
|
|
|
|
use bevy_rapier2d::prelude::*;
|
|
|
|
use crate::{
|
|
meters,
|
|
item::lockpick::lockpick_bundle,
|
|
player::{
|
|
Player,
|
|
player_bundle,
|
|
},
|
|
};
|
|
|
|
use super::*;
|
|
|
|
fn get_interactive_id<F: QueryFilter>(
|
|
tested_id: Entity,
|
|
interactive_query: Query<(), F>,
|
|
parent_query: Query<&ChildOf, With<Collider>>,
|
|
) -> Option<Entity> {
|
|
if interactive_query.get(tested_id).is_ok() {
|
|
return Some(tested_id);
|
|
}
|
|
let Ok(parent_id) = parent_query.get(tested_id) else {
|
|
return None;
|
|
};
|
|
match interactive_query.get(parent_id.0) {
|
|
Ok(_) => Some(parent_id.0),
|
|
Err(_) => None,
|
|
}
|
|
}
|
|
|
|
pub fn detect_interact_collisions(
|
|
mut commands: Commands,
|
|
mut collision_events: MessageReader<CollisionEvent>,
|
|
player_query: Query<(), With<Player>>,
|
|
interactive_query1: Query<(), (With<InteractiveObject>, Without<MayInteract>)>,
|
|
interactive_query2: Query<(), (With<InteractiveObject>, With<MayInteract>)>,
|
|
parent_query: Query<&ChildOf, With<Collider>>,
|
|
) {
|
|
for collision_event in collision_events.read() {
|
|
match collision_event {
|
|
CollisionEvent::Started(first, second, _) => {
|
|
let Some(interactive_id) = get_interactive_id(*first, interactive_query1, parent_query) else {
|
|
continue;
|
|
};
|
|
if player_query.get(*second).is_err() {
|
|
continue;
|
|
}
|
|
commands.entity(interactive_id).insert(MayInteract);
|
|
},
|
|
CollisionEvent::Stopped(first, second, _) => {
|
|
let Some(interactive_id) = get_interactive_id(*first, interactive_query2, parent_query) else {
|
|
continue;
|
|
};
|
|
if player_query.get(*second).is_err() {
|
|
continue;
|
|
}
|
|
commands.entity(interactive_id).remove::<MayInteract>();
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn lock_door(
|
|
mut commands: Commands,
|
|
query: Query<&ChildOf, Added<lock::Padlock>>,
|
|
) {
|
|
for parent in query {
|
|
commands.entity(parent.0).insert(Locked);
|
|
}
|
|
}
|
|
|
|
pub fn setup_world(
|
|
mut commands: Commands,
|
|
asset_server: Res<AssetServer>,
|
|
) {
|
|
let tiles = [
|
|
( 0, ( 0, 0, 16, 1 )), // 1F floor
|
|
( 0, ( 0, 4, 16, 1 )), // 1F ceiling / 2F floor
|
|
( 0, ( 0, 8, 16, 1 )), // 2F ceiling
|
|
|
|
( 1, ( 0, 1, 1, 3 )), // 1F left wall
|
|
( 1, ( 0, 5, 1, 3 )), // 2F left wall
|
|
( 1, ( 15, 1, 1, 3 )), // 1F right wall
|
|
( 1, ( 15, 5, 1, 3 )), // 2F right wall
|
|
|
|
( 2, ( 4, 3, 1, 1 )), // 1F left door connector
|
|
( 2, ( 4, 7, 1, 1 )), // 2F left door connector
|
|
( 2, ( 11, 3, 1, 1 )), // 1F right door connector
|
|
( 2, ( 11, 7, 1, 1 )), // 2F right door connector
|
|
].into_iter().map(|(id, (x, y, w, h))| {
|
|
(id, URect::from_corners(uvec2(x, y), uvec2(x + w - 1, y + h - 1)))
|
|
}).collect::<Vec<(u16, URect)>>();
|
|
|
|
commands.spawn(tilemap::tilemap_bundle(&asset_server, tiles));
|
|
|
|
commands.spawn(player_bundle(&asset_server, vec2(meters(1.5), meters(1.))));
|
|
|
|
commands.spawn(door::door_bundle(&asset_server, vec2(meters(4.5), meters(1.)), false));
|
|
commands.spawn(door::door_bundle(&asset_server, vec2(meters(4.5), meters(5.)), false))
|
|
.with_child(lock::padlock_bundle(&asset_server, false));
|
|
commands.spawn(door::door_bundle(&asset_server, vec2(meters(11.5), meters(1.)), true))
|
|
.with_child(lock::padlock_bundle(&asset_server, true));
|
|
commands.spawn(door::door_bundle(&asset_server, vec2(meters(11.5), meters(5.)), true));
|
|
|
|
commands.spawn(stairs::stairs_bundle(
|
|
&asset_server,
|
|
vec2(meters(8.), meters(1.)),
|
|
Some(vec2(meters(2.), meters(4.))),
|
|
None,
|
|
));
|
|
commands.spawn(stairs::stairs_bundle(
|
|
&asset_server,
|
|
vec2(meters(8.), meters(5.)),
|
|
None,
|
|
Some(vec2(meters(-2.), meters(-4.))),
|
|
));
|
|
|
|
commands.spawn(container::container_bundle(
|
|
&asset_server,
|
|
vec2(meters(2.), meters(1.)),
|
|
uvec2(1, 1),
|
|
));
|
|
commands.spawn(container::container_bundle(
|
|
&asset_server,
|
|
vec2(meters(14.), meters(1.)),
|
|
uvec2(1, 1),
|
|
));
|
|
commands.spawn(container::container_bundle(
|
|
&asset_server,
|
|
vec2(meters(2.), meters(5.)),
|
|
uvec2(4, 4),
|
|
)).with_child(lockpick_bundle(&asset_server, uvec2(2, 2), false));
|
|
commands.spawn(container::container_bundle(
|
|
&asset_server,
|
|
vec2(meters(14.), meters(5.)),
|
|
uvec2(2, 2),
|
|
)).with_child(lockpick_bundle(&asset_server, UVec2::ZERO, true));
|
|
}
|