use super::*;
pub use stage::*;
mod stage;
pub use states::*;
mod states;
#[derive(Clone, HasSchema, Default)]
pub struct PlayerState {
pub current: Ustr,
pub age: u64,
pub last: Ustr,
}
impl PlayerState {
pub fn add_player_state_transition_system<Args>(
session: &mut Session,
system: impl IntoSystem<Args, (), (), Sys = StaticSystem<(), ()>>,
) {
session.stages.add_system_to_stage(PlayerStateStage, system);
}
pub fn add_player_state_update_system<Args>(
session: &mut Session,
system: impl IntoSystem<Args, (), (), Sys = StaticSystem<(), ()>>,
) {
session
.stages
.add_system_to_stage(CoreStage::PreUpdate, system);
}
}
pub fn plugin(session: &mut Session) {
session
.stages
.insert_stage_before(CoreStage::PreUpdate, PlayerStateStageImpl::new());
session
.stages
.add_system_to_stage(CoreStage::Last, update_player_state_age);
crouch::install(session);
dead::install(session);
default::install(session);
drive_jellyfish::install(session);
idle::install(session);
incapacitated::install(session);
ragdoll::install(session);
midair::install(session);
walk::install(session);
}
fn update_player_state_age(entities: Res<Entities>, mut player_states: CompMut<PlayerState>) {
for (_ent, state) in entities.iter_with(&mut player_states) {
state.age = state.age.saturating_add(1);
}
}
fn use_drop_or_grab_items_system(id: Ustr) -> StaticSystem<(), ()> {
(move |entities: Res<Entities>,
player_inputs: Res<MatchInputs>,
player_indexes: Comp<PlayerIdx>,
player_states: Comp<PlayerState>,
assets: Res<AssetServer>,
items: Comp<Item>,
collision_world: CollisionWorld,
mut inventories: CompMut<Inventory>,
mut audio_center: ResMut<AudioCenter>,
mut commands: Commands| {
let held_items = entities
.iter_with(&inventories)
.filter_map(|(_ent, inventory)| inventory.0)
.collect::<Vec<_>>();
for (player_ent, (player_state, player_idx, inventory)) in
entities.iter_with((&player_states, &player_indexes, &mut inventories))
{
if player_state.current != id {
continue;
}
let meta_handle = player_inputs.players[player_idx.0 as usize].selected_player;
let meta = assets.get(meta_handle);
let control = &player_inputs.players[player_idx.0 as usize].control;
if control.grab_just_pressed {
if inventory.is_none() {
let colliders = collision_world
.actor_collisions(player_ent)
.into_iter()
.filter(|ent| items.contains(*ent))
.filter(|ent| !held_items.contains(ent))
.collect::<Vec<_>>();
if let Some(item) = colliders.first() {
commands.add(PlayerCommand::set_inventory(player_ent, Some(*item)));
audio_center.play_sound(meta.sounds.grab, meta.sounds.grab_volume);
}
} else {
commands.add(PlayerCommand::set_inventory(player_ent, None));
audio_center.play_sound(meta.sounds.drop, meta.sounds.drop_volume);
}
}
if control.shoot_pressed && inventory.is_some() {
commands.add(PlayerCommand::use_item(player_ent));
}
}
})
.system()
}