diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 409fb5d..5ddba30 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -921,7 +921,24 @@ pub fn remove_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Opti } } -pub fn ranged_target(gs: &mut State, ctx: &mut Rltk, range: i32, aoe: i32) -> (ItemMenuResult, Option) { +#[derive(PartialEq, Copy, Clone)] +pub enum TargetResult { + Cancel, + NoResponse { + x: i32, + y: i32, + }, + Selected, +} + +pub fn ranged_target( + gs: &mut State, + ctx: &mut Rltk, + x: i32, + y: i32, + range: i32, + aoe: i32 +) -> (TargetResult, Option) { let (min_x, max_x, min_y, max_y, x_offset, y_offset) = camera::get_screen_bounds(&gs.ecs, ctx); let player_entity = gs.ecs.fetch::(); let player_pos = gs.ecs.fetch::(); @@ -952,11 +969,16 @@ pub fn ranged_target(gs: &mut State, ctx: &mut Rltk, range: i32, aoe: i32) -> (I } } } else { - return (ItemMenuResult::Cancel, None); + return (TargetResult::Cancel, None); } // Draw mouse cursor - let mouse_pos = ctx.mouse_pos(); + let mouse_pos = (x, y); + let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = camera::get_screen_bounds(&gs.ecs, ctx); + let (screen_x, screen_y) = (69, 41); + let x = x.clamp(x_offset, x_offset - 1 + (screen_x as i32)); + let y = y.clamp(y_offset, y_offset - 1 + (screen_y as i32)); + let mut mouse_pos_adjusted = mouse_pos; mouse_pos_adjusted.0 += min_x - x_offset; mouse_pos_adjusted.1 += min_y - y_offset; @@ -967,6 +989,7 @@ pub fn ranged_target(gs: &mut State, ctx: &mut Rltk, range: i32, aoe: i32) -> (I valid_target = true; } } + let mut result = (TargetResult::NoResponse { x, y }, None); if valid_target { if aoe > 0 { // We adjust for camera position when getting FOV, but then we need to adjust back @@ -982,17 +1005,37 @@ pub fn ranged_target(gs: &mut State, ctx: &mut Rltk, range: i32, aoe: i32) -> (I } } ctx.set_bg(mouse_pos.0, mouse_pos.1, RGB::named(rltk::CYAN)); - if ctx.left_click { - return (ItemMenuResult::Selected, Some(Point::new(mouse_pos_adjusted.0, mouse_pos_adjusted.1))); - } + result = match ctx.key { + None => result, + Some(key) => + match key { + VirtualKeyCode::Return => { + return (TargetResult::Selected, Some(Point::new(mouse_pos_adjusted.0, mouse_pos_adjusted.1))); + } + _ => result, + } + }; } else { ctx.set_bg(mouse_pos.0, mouse_pos.1, RGB::named(rltk::RED)); - if ctx.left_click { - return (ItemMenuResult::Cancel, None); - } } - (ItemMenuResult::NoResponse, None) + result = match ctx.key { + None => result, + Some(key) => + match key { + VirtualKeyCode::Escape => (TargetResult::Cancel, None), + VirtualKeyCode::Numpad9 => (TargetResult::NoResponse { x: x + 1, y: y - 1 }, None), + VirtualKeyCode::Numpad7 => (TargetResult::NoResponse { x: x - 1, y: y - 1 }, None), + VirtualKeyCode::Numpad6 => (TargetResult::NoResponse { x: x + 1, y }, None), + VirtualKeyCode::Numpad4 => (TargetResult::NoResponse { x: x - 1, y }, None), + VirtualKeyCode::Numpad8 => (TargetResult::NoResponse { x, y: y - 1 }, None), + VirtualKeyCode::Numpad3 => (TargetResult::NoResponse { x: x + 1, y: y + 1 }, None), + VirtualKeyCode::Numpad2 => (TargetResult::NoResponse { x, y: y + 1 }, None), + VirtualKeyCode::Numpad1 => (TargetResult::NoResponse { x: x - 1, y: y + 1 }, None), + _ => result, + } + }; + return result; } #[derive(PartialEq, Copy, Clone)] diff --git a/src/main.rs b/src/main.rs index c98feb9..6c09c58 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,6 +53,8 @@ pub enum RunState { ShowDropItem, ShowRemoveItem, ShowTargeting { + x: i32, + y: i32, range: i32, item: Entity, aoe: i32, @@ -358,14 +360,23 @@ impl GameState for State { if let Some(ranged_item) = ranged_item { let is_aoe = self.ecs.read_storage::(); let aoe_item = is_aoe.get(item_entity); + let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = camera::get_screen_bounds( + &self.ecs, + ctx + ); + let ppos = self.ecs.fetch::(); if let Some(aoe_item) = aoe_item { new_runstate = RunState::ShowTargeting { + x: ppos.x + x_offset - min_x, + y: ppos.y + y_offset - min_y, range: ranged_item.range, item: item_entity, aoe: aoe_item.radius, }; } else { new_runstate = RunState::ShowTargeting { + x: ppos.x + x_offset - min_x, + y: ppos.y + y_offset - min_y, range: ranged_item.range, item: item_entity, aoe: 0, @@ -415,14 +426,16 @@ impl GameState for State { } } } - RunState::ShowTargeting { range, item, aoe } => { - let result = gui::ranged_target(self, ctx, range, aoe); + RunState::ShowTargeting { x, y, range, item, aoe } => { + let result = gui::ranged_target(self, ctx, x, y, range, aoe); match result.0 { - gui::ItemMenuResult::Cancel => { + gui::TargetResult::Cancel => { new_runstate = RunState::AwaitingInput; } - gui::ItemMenuResult::NoResponse => {} - gui::ItemMenuResult::Selected => { + gui::TargetResult::NoResponse { x, y } => { + new_runstate = RunState::ShowTargeting { x, y, range, item, aoe }; + } + gui::TargetResult::Selected => { let mut intent = self.ecs.write_storage::(); intent .insert(*self.ecs.fetch::(), WantsToUseItem { item, target: result.1 })