From 4700e0180c341bb3186c76a2c533da33201eedcc Mon Sep 17 00:00:00 2001 From: Dmytro Lysai Date: Thu, 11 Jun 2020 19:53:58 +0300 Subject: [PATCH] [game] Skill use via croshair pick --- src/asset/frame/id/consts.rs | 4 +- src/game/state.rs | 5 ++- src/game/ui/world.rs | 79 ++++++++++++++++++++++++------------ src/ui.rs | 2 + src/ui/command.rs | 1 + 5 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/asset/frame/id/consts.rs b/src/asset/frame/id/consts.rs index 9843043..9fa5d3e 100644 --- a/src/asset/frame/id/consts.rs +++ b/src/asset/frame/id/consts.rs @@ -280,7 +280,7 @@ impl FrameId { pub const SCRSWEST: FrameId = FrameId::Generic(Generic(0x6000_114)); pub const SCRWEST: FrameId = FrameId::Generic(Generic(0x6000_115)); pub const WAIT: FrameId = FrameId::Generic(Generic(0x6000_116)); - pub const CRSSHAIR: FrameId = FrameId::Generic(Generic(0x6000_117)); + pub const CROSSHAIR_ATTACK: FrameId = FrameId::Generic(Generic(0x6000_117)); pub const PLUS: FrameId = FrameId::Generic(Generic(0x6000_118)); pub const DESTROY: FrameId = FrameId::Generic(Generic(0x6000_119)); pub const ACTPICK: FrameId = FrameId::Generic(Generic(0x6000_11a)); @@ -294,7 +294,7 @@ impl FrameId { pub const MVENUM: FrameId = FrameId::Generic(Generic(0x6000_122)); pub const RELOAD: FrameId = FrameId::Generic(Generic(0x6000_123)); pub const USET: FrameId = FrameId::Generic(Generic(0x6000_124)); - pub const CROSSUSE: FrameId = FrameId::Generic(Generic(0x6000_125)); + pub const CROSSHAIR_USE: FrameId = FrameId::Generic(Generic(0x6000_125)); pub const USEON: FrameId = FrameId::Generic(Generic(0x6000_126)); pub const WAIT2: FrameId = FrameId::Generic(Generic(0x6000_127)); pub const FALLTEXT: FrameId = FrameId::Generic(Generic(0x6000_128)); diff --git a/src/game/state.rs b/src/game/state.rs index 5637c44..4f14364 100644 --- a/src/game/state.rs +++ b/src/game/state.rs @@ -1227,6 +1227,9 @@ impl AppState for GameState { None }; self.handle_action(ui, objh, a); + }, + ObjectPickKind::Skill(skill) => { + self.action_use_skill_on(skill, objh); } } } @@ -1341,7 +1344,7 @@ impl AppState for GameState { if let Some(target) = target { self.action_use_skill_on(skill, target); } else { - // TODO + ui.widget_mut::(self.world_view).enter_skill_target_pick_mode(skill); } } } diff --git a/src/game/ui/world.rs b/src/game/ui/world.rs index 1652a9c..9b5ed13 100644 --- a/src/game/ui/world.rs +++ b/src/game/ui/world.rs @@ -1,3 +1,4 @@ +use matches::matches; use std::rc::Rc; use std::cell::RefCell; use std::time::{Duration, Instant}; @@ -21,7 +22,13 @@ use super::action_menu::{Action, Placement}; #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum PickMode { Hex, - Object, + Object(ObjectPickMode), +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum ObjectPickMode { + Action, + Skill(crate::asset::Skill), } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -42,6 +49,7 @@ enum PickState { pub struct WorldView { world: Rc>, pick_mode: PickMode, + saved_pick_mode: Option, hex_cursor: object::Handle, pub hex_cursor_style: HexCursorStyle, pub roof_visible: bool, @@ -59,6 +67,7 @@ impl WorldView { Self { world, pick_mode: PickMode::Hex, + saved_pick_mode: None, hex_cursor, hex_cursor_style: HexCursorStyle::Normal, roof_visible: false, @@ -85,6 +94,11 @@ impl WorldView { } } + pub fn enter_skill_target_pick_mode(&mut self, skill: crate::asset::Skill) { + self.saved_pick_mode = Some(self.pick_mode); + self.pick_mode = PickMode::Object(ObjectPickMode::Skill(skill)); + } + fn insert_hex_cursor(world: &mut World) -> object::Handle { let mut hex_cursor = Object::new(FrameId::MOUSE_HEX_OUTLINE, None, Some(Default::default()), SubObject::None); @@ -125,10 +139,6 @@ impl WorldView { } impl Widget for WorldView { - fn init(&mut self, ctx: Init) { - ctx.base.set_cursor(Some(Cursor::Hidden)); - } - fn handle_event(&mut self, mut ctx: HandleEvent) { match ctx.event { Event::MouseMove { pos } => { @@ -139,15 +149,18 @@ impl Widget for WorldView { ctx.out(UiCommandData::HexPick { action: false, pos }); } } - PickMode::Object => { + PickMode::Object(ObjectPickMode::Action) => { self.pick_state = PickState::Pending { start: ctx.now, pos }; self.default_action_icon = None; } + PickMode::Object(ObjectPickMode::Skill(_)) => {} } self.update_hex_cursor_visibility(None); } Event::MouseDown { pos, button } => { - if button == MouseButton::Left && self.pick_mode == PickMode::Object { + if button == MouseButton::Left && + matches!(self.pick_mode, PickMode::Object(ObjectPickMode::Action)) + { let world = self.world.borrow(); if let Some(obj) = world.pick_object(pos, true) { self.action_menu_state = Some((ctx.now, obj)); @@ -163,13 +176,24 @@ impl Widget for WorldView { let (pos, _) = self.update_hex_cursor_pos(pos); ctx.out(UiCommandData::HexPick { action: true, pos }); } - PickMode::Object => { - let world = self.world.borrow(); - if let Some(obj) = world.pick_object(pos, true) { - ctx.out(UiCommandData::ObjectPick { - kind: ObjectPickKind::DefaultAction, - obj, - }); + PickMode::Object(mode) => { + let picked_obj = self.world.borrow().pick_object(pos, true); + if let Some(obj) = picked_obj { + let kind = match mode { + ObjectPickMode::Action => ObjectPickKind::DefaultAction, + ObjectPickMode::Skill(skill) => { + self.pick_mode = self.saved_pick_mode.take().unwrap(); + ObjectPickKind::Skill(skill) + } + }; + ctx.out(UiCommandData::ObjectPick { kind, obj }); + if self.pick_mode == PickMode::Hex { + self.update_hex_cursor_visibility(None); + let (pos, changed) = self.update_hex_cursor_pos(pos); + if changed { + ctx.out(UiCommandData::HexPick { action: false, pos }); + } + } } } } @@ -177,11 +201,9 @@ impl Widget for WorldView { MouseButton::Right => { self.pick_mode = match self.pick_mode { PickMode::Hex => { - ctx.base.set_cursor(Some(Cursor::ActionArrow)); - PickMode::Object + PickMode::Object(ObjectPickMode::Action) } - PickMode::Object => { - ctx.base.set_cursor(Some(Cursor::Hidden)); + PickMode::Object(_) => { let (pos, changed) = self.update_hex_cursor_pos(pos); if changed { ctx.out(UiCommandData::HexPick { action: false, pos }); @@ -233,14 +255,16 @@ impl Widget for WorldView { } fn sync(&mut self, ctx: Sync) { - if ctx.base.cursor() != Some(Cursor::Hidden) { - ctx.base.set_cursor(Some( - if self.default_action_icon.is_some() { - Placement::new(1, ctx.cursor_pos, ctx.base.rect()).cursor - } else { - Cursor::ActionArrow - })) - } + ctx.base.set_cursor(Some( + if self.default_action_icon.is_some() { + Placement::new(1, ctx.cursor_pos, ctx.base.rect()).cursor + } else { + match self.pick_mode { + PickMode::Hex => Cursor::Hidden, + PickMode::Object(ObjectPickMode::Action) => Cursor::ActionArrow, + PickMode::Object(ObjectPickMode::Skill(_)) => Cursor::CrosshairUse, + } + })); } fn render(&mut self, ctx: Render) { @@ -267,7 +291,7 @@ impl Widget for WorldView { }); } } - PickMode::Object => if let Some(action) = self.default_action_icon { + PickMode::Object(ObjectPickMode::Action) => if let Some(action) = self.default_action_icon { let fid = action.icons().0; let pos = Placement::new(1, ctx.cursor_pos, ctx.base.unwrap().rect()).rect.top_left(); Sprite { @@ -280,6 +304,7 @@ impl Widget for WorldView { effect: None, }.render(ctx.canvas, ctx.frm_db); } + PickMode::Object(ObjectPickMode::Skill(_)) => {} } } } \ No newline at end of file diff --git a/src/ui.rs b/src/ui.rs index 2040e17..3f56191 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -51,6 +51,7 @@ pub enum Cursor { Arrow, ArrowDown, ArrowUp, + CrosshairUse, ScrollNorth, ScrollNorthEast, @@ -81,6 +82,7 @@ impl Cursor { Arrow => FrameId::STDARROW, ArrowDown => FrameId::SDNARROW, ArrowUp => FrameId::SUPARROW, + CrosshairUse => FrameId::CROSSHAIR_USE, ScrollNorth => FrameId::SCRNORTH, ScrollNorthEast => FrameId::SCRNEAST, diff --git a/src/ui/command.rs b/src/ui/command.rs index 2c4d281..ca767d7 100644 --- a/src/ui/command.rs +++ b/src/ui/command.rs @@ -35,6 +35,7 @@ pub enum ObjectPickKind { Hover, DefaultAction, ActionMenu, + Skill(crate::asset::Skill), } #[derive(Clone, Copy, Debug, Eq, PartialEq)]