rust-sokoban/src/systems/event_system.rs

74 lines
2.6 KiB
Rust

use specs::{Entities, Join, ReadStorage, System, Write};
use std::collections::HashMap;
use crate::{
audio::AudioStore,
components::*,
events::{BoxPlacedOnSpot, EntityMoved, Event},
resources::EventQueue,
};
pub struct EventSystem {}
impl<'a> System<'a> for EventSystem {
// Data
type SystemData = (
Write<'a, EventQueue>,
Write<'a, AudioStore>,
Entities<'a>,
ReadStorage<'a, Box>,
ReadStorage<'a, BoxSpot>,
ReadStorage<'a, Position>,
);
fn run(&mut self, data: Self::SystemData) {
let (mut event_queue, mut audio_store, entities, boxes, box_spots, positions) = data;
let mut new_events = Vec::new();
for event in event_queue.events.drain(..) {
println!("New event: {:?}", event);
match event {
Event::PlayerHistObstacle => {
// play sound here
audio_store.play_sound(&"wall".to_string());
}
Event::EntityMoved(EntityMoved { id }) => {
// An entity was just moved, check if it was a box and fire
// more events if it's been moved on a spot.
if let Some(the_box) = boxes.get(entities.entity(id)) {
let box_spots_with_positions: HashMap<(u8, u8), &BoxSpot> = (&box_spots, &positions)
.join()
.map(|t| ((t.1.x, t.1.y), t.0))
.collect();
if let Some(box_position) = positions.get(entities.entity(id)) {
// Check if there is a spot on this position, and if there
// is, if it's the correct or incorrect type
if let Some(box_spot) = box_spots_with_positions.get(&(box_position.x, box_position.y)) {
new_events.push(Event::BoxPlacedOnSpot(BoxPlacedOnSpot {
is_correct_spot: (box_spot.color == the_box.color),
}));
}
}
}
}
Event::BoxPlacedOnSpot(BoxPlacedOnSpot { is_correct_spot }) => {
// play sound here
let sound = if is_correct_spot {
"correct"
} else {
"incorrect"
};
audio_store.play_sound(&sound.to_string())
}
}
}
event_queue.events.append(&mut new_events);
}
}