use shrev::{EventChannel, ReaderId}; use space_crush_common::{ components::{Fleet, FleetOwned, Orbit, Player, Position, Ship, ShipType}, continue_if_none, misc::WorldHelper, }; use specs::{prelude::*, Entity, ReadStorage, System, World, WriteStorage}; use crate::{ misc::MouseEvent, resources::{Camera, Config, GameState, InputState}, Error, }; pub struct FleetControl { mouse_event_id: ReaderId, target_fleet: Option, } #[derive(SystemData)] pub struct FleetControlData<'a> { game_state: WriteExpect<'a, GameState>, mouse_events: ReadExpect<'a, EventChannel>, input_state: ReadExpect<'a, InputState>, camera: ReadExpect<'a, Camera>, config: ReadExpect<'a, Config>, ships: ReadStorage<'a, Ship>, fleet_owned: WriteStorage<'a, FleetOwned>, positions: ReadStorage<'a, Position>, players: ReadStorage<'a, Player>, orbits: ReadStorage<'a, Orbit>, fleets: ReadStorage<'a, Fleet>, } impl FleetControl { pub fn new(world: &mut World) -> Result { let mouse_event_id = world.register_event_reader::()?; let target_fleet = None; Ok(Self { mouse_event_id, target_fleet, }) } } impl<'a> System<'a> for FleetControl { type SystemData = FleetControlData<'a>; fn run(&mut self, data: Self::SystemData) { let FleetControlData { mut game_state, mouse_events, input_state, camera, config, ships, mut fleet_owned, positions, players, orbits, fleets, } = data; let events = mouse_events.read(&mut self.mouse_event_id); for event in events { match event { MouseEvent::ButtonDown(button) if button == &config.input.fleet_move_button => { let pos = camera.view_to_world(input_state.mouse_pos); for (position, orbit) in (&positions, &orbits).join() { let r = orbit.max() * orbit.max(); if (position.pos() - pos).length_sqr() <= r { let player_id = game_state.player_id; let player = continue_if_none!(players.get(player_id)); let fleet_id = continue_if_none!(orbit.fleets().get(player.index())); let fleet_id = *continue_if_none!(fleet_id); self.target_fleet = Some(fleet_id); break; } } } #[allow(unused_variables)] // TODO MouseEvent::ButtonUp(button) if button == &config.input.fleet_move_button => { let selection = game_state.selection.take(); let target_fleet = continue_if_none!(self.target_fleet.take()); let mut selection = continue_if_none!(selection); let fleet = continue_if_none!(fleets.get(selection.fleet)); for (ship, fleet_owned, _) in (&ships, &mut fleet_owned, fleet.owned()).join() { match ship.type_() { ShipType::Fighter if selection.count.fighter > 0 => { // TODO fleet_owned.set_owner(target_fleet); selection.count.fighter -= 1; } ShipType::Bomber if selection.count.bomber > 0 => { // TODO fleet_owned.set_owner(target_fleet); selection.count.bomber -= 1; } ShipType::Transporter if selection.count.transporter > 0 => { // TODO fleet_owned.set_owner(target_fleet); selection.count.transporter -= 1; } _ => (), } } } MouseEvent::Move(_, _) => { self.target_fleet = None; } _ => (), } } } }