use bevy::platform::collections::HashMap;
use bevy::prelude::*;
use leafwing_input_manager::plugin::InputManagerSystem;
use leafwing_input_manager::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(InputManagerPlugin::<Slot>::default())
.add_plugins(InputManagerPlugin::<Ability>::default())
.add_systems(Startup, spawn_player)
.add_systems(
PreUpdate,
copy_action_state.after(InputManagerSystem::ManualControl),
)
.add_systems(Update, report_abilities_used)
.run();
}
#[derive(Actionlike, PartialEq, Eq, Clone, Debug, Hash, Copy, Reflect)]
enum Slot {
Primary,
Secondary,
Ability1,
Ability2,
Ability3,
Ability4,
}
impl Slot {
fn variants() -> impl Iterator<Item = Slot> {
use Slot::*;
[Primary, Secondary, Ability1, Ability2, Ability3, Ability4]
.iter()
.copied()
}
}
#[derive(Actionlike, PartialEq, Eq, Hash, Clone, Debug, Copy, Reflect)]
enum Ability {
Slash,
Shoot,
LightningBolt,
Fireball,
Dash,
Heal,
FrozenOrb,
PolymorphSheep,
}
#[derive(Component, Debug, Default, Deref, DerefMut)]
struct AbilitySlotMap {
map: HashMap<Slot, Ability>,
}
#[derive(Component)]
struct Player;
#[derive(Bundle)]
struct PlayerBundle {
player: Player,
slot_input_map: InputMap<Slot>,
slot_action_state: ActionState<Slot>,
ability_action_state: ActionState<Ability>,
ability_slot_map: AbilitySlotMap,
}
fn spawn_player(mut commands: Commands) {
use KeyCode::*;
let mut ability_slot_map = AbilitySlotMap::default();
ability_slot_map.insert(Slot::Primary, Ability::Slash);
ability_slot_map.insert(Slot::Secondary, Ability::Shoot);
ability_slot_map.insert(Slot::Ability1, Ability::FrozenOrb);
ability_slot_map.insert(Slot::Ability3, Ability::Dash);
ability_slot_map.insert(Slot::Ability4, Ability::PolymorphSheep);
commands.spawn(PlayerBundle {
player: Player,
slot_input_map: InputMap::new([
(Slot::Ability1, KeyQ),
(Slot::Ability2, KeyW),
(Slot::Ability3, KeyE),
(Slot::Ability4, KeyR),
])
.with(Slot::Primary, MouseButton::Left)
.with(Slot::Secondary, MouseButton::Right),
slot_action_state: ActionState::default(),
ability_action_state: ActionState::default(),
ability_slot_map,
});
}
fn copy_action_state(
mut query: Query<(
&mut ActionState<Slot>,
&mut ActionState<Ability>,
&AbilitySlotMap,
)>,
) {
for (mut slot_state, mut ability_state, ability_slot_map) in query.iter_mut() {
for slot in Slot::variants() {
if let Some(matching_ability) = ability_slot_map.get(&slot) {
ability_state.set_button_data(
*matching_ability,
slot_state.button_data_mut_or_default(&slot).clone(),
);
}
}
}
}
fn report_abilities_used(query: Query<&ActionState<Ability>>) {
for ability_state in query.iter() {
for ability in ability_state.get_just_pressed() {
dbg!(ability);
}
}
}