Skip to content
This repository has been archived by the owner on Sep 19, 2022. It is now read-only.

Commit

Permalink
Merge pull request #49 from Winsalot/micro_input_m1
Browse files Browse the repository at this point in the history
Micro Input Milestone 1 implementation
  • Loading branch information
AnneKitsune authored Apr 13, 2021
2 parents c3f5180 + 26be725 commit 9af271f
Show file tree
Hide file tree
Showing 27 changed files with 801 additions and 12 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
/target
/dev_notes.txt
/target
11 changes: 9 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ console_error_panic_hook = { version = "0.1.6", optional = true }
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8.14"
rand = "0.7.3"
oorandom = "11.1.3" # Just read the description at https://crates.io/crates/oorandom to see why I prefer to use this one
lazy_static = "1.4.0"
27 changes: 23 additions & 4 deletions assets/keymap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,35 @@
104: MenuWest
106: MenuSouth
107: MenuNorth
49:
113:
Teleport: 1
50:
119:
Teleport: 2
51:
101:
Teleport: 3
108: MenuEast
113: MenuCancel
13: MenuSelect
115: SpeedToggle
120: SpeedToggle
105: GameModeToggle
# 77: MMove
109: MMove
97: AMove
# 72: HoldPos
104: HoldPos
# 83: StopOrder
115: StopOrder
27: ResetInputState
49:
AutoSelect: 0
50:
AutoSelect: 1
51:
AutoSelect: 2
52:
AutoSelect: 3
53:
AutoSelect: 4
72: CameraWest
74: CameraSouth
75: CameraNorth
Expand Down
8 changes: 8 additions & 0 deletions assets/stat_defs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,11 @@ defs:
min_value: 0.0
max_value: 20.0
icon_path: ~
AggroRange:
key: AggroRange
name: aggrorange
friendly_name: Aggro
default_value: 7.0
min_value: 1.0
max_value: ~
icon_path: ~
16 changes: 16 additions & 0 deletions src/components.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::*;
pub use std::collections::VecDeque;

/// Tags this entity as a `Tower`.
pub struct Tower;
Expand All @@ -20,6 +21,7 @@ pub enum Companion {
/// A elephant companion
Elephant(Entity),
}

/// Tags a tower projectile.
pub struct TowerProjectile;
/// Tags a core.
Expand Down Expand Up @@ -80,6 +82,20 @@ pub struct LineOfSight {
pub range: i32,
}

/// Order queue component for micro-control (and maybe bots)
pub struct OrderQueue {
/// List of orders for a unit.
pub orders: VecDeque<UnitOrder>,
}

impl OrderQueue {
/// Better to wrap a component creation in a function
pub fn new(orders: Vec<UnitOrder>) -> Self {
OrderQueue {
orders: VecDeque::from(orders),
}
}
}
/// Items available to buy
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct ShelfItem(pub Items, pub i32);
24 changes: 23 additions & 1 deletion src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@ pub enum InputEvent {
MenuCancel,
SpeedToggle,
ZoomToggle,
GameModeToggle,
CameraNorth,
CameraSouth,
CameraEast,
CameraWest,
Teleport(u8),

/// Auto control group:
AutoSelect(u8),

/// Key to reset input state to default (default key Esc)
ResetInputState,
/// Key (default M) responsibe for M-move order was pressed
MMove,
/// A move order. (Defaut key A)
AMove,
/// Key (default M) responsibe for HoldPosition order was pressed
HoldPos,
/// Clear unit's order Queue. Default key S
StopOrder,
}

/// Events generated by the game's runtime.
Expand Down Expand Up @@ -46,12 +61,19 @@ pub enum GameEvent {
}

/// Events generated by mouse interaction.
#[derive(PartialEq, Copy, Clone, Debug)]
#[derive(PartialEq, Clone, Debug)]
pub enum MouseEvent {
/// A selectable entity was selected.
EntitySelected(Entity),
/// A clicable entity was clicked anywhere in the game.
EntityClicked(Entity),
/// A hoverable entity was hovered anywhere in the game.
EntityHovered(Entity),
/// A point on a map was clicked. Contains all entity ID's on that point.
PositionClicked {
/// Position of the click
pos: Point,
/// Does that position contain entity (or is it an empty point)
entities: Option<Vec<Entity>>,
},
}
1 change: 1 addition & 0 deletions src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub enum Stats {
Health,
Defense,
Attack,
AggroRange,
Mana,
AttackSpeed,
EnemiesAround,
Expand Down
16 changes: 16 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ mod render_map;
mod resources;
mod states;
mod systems;
mod unit_orders;
mod utils;
pub use self::components::*;
pub use self::events::*;
Expand All @@ -76,6 +77,7 @@ pub use self::render_map::*;
pub use self::resources::*;
pub use self::states::*;
pub use self::systems::*;
pub use self::unit_orders::*;
pub use self::utils::*;

// Bridge between bracket-lib and minigene
Expand Down Expand Up @@ -133,13 +135,22 @@ fn main() -> BError {
combine_collision_system,
input_driver::<InputEvent>,
update_mouse_events_system,
order_generation_system,
unit_selection_system,
control_group_system,
update_input_state_system, // should run before all other input systems
update_collision_resource_system,
handle_action_points_system,
creep_spawner_system,
idle_order_system,
mmove_order_system,
amove_order_system,
holdpos_order_system,
simple_destination_system,
ai_pathing_system,
movement_system,
toggle_game_speed_system,
toggle_game_mode_system,
win_condition_system,
//leader1_simple_movement_system, // TODO re-enable & rewrite like simple_destination_system
//leader2_simple_movement_system, // TODO re-enable & rewrite like simple_destination_system
Expand Down Expand Up @@ -181,6 +192,7 @@ fn main() -> BError {
spawn_creep_system,
spawn_leader_system,
game_stats_updater_system,
order_completion_check_system,
event_retrigger_system::<InputEvent, MoveCameraEvent>,
move_camera_system,
);
Expand Down Expand Up @@ -219,6 +231,10 @@ fn main() -> BError {
world.initialize::<Components<Core>>();
world.initialize::<Viewshed>();
world.initialize::<TeamLeaders>();
world.initialize::<GameMode>();
world.initialize::<SelectedUnits>();
world.initialize::<InputState>();
world.initialize::<RandomNG>();

*world.get_mut::<Option<CollisionResource>>().unwrap() = Some(CollisionResource::new(
CollisionMap::new(MAP_SIZE_X, MAP_SIZE_Y),
Expand Down
36 changes: 33 additions & 3 deletions src/render_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,41 @@ pub fn render_ui(world: &mut World, ctx: &mut BTerm) {
let hm = world.get::<HashMap<char, InputEvent>>().unwrap();
let mut keybinds = hm.iter().collect::<Vec<_>>();
keybinds.sort_by(|t1, t2| format!("{:?}", t1.1).cmp(&format!("{:?}", t2.1)));
let mut offset = 0;
for (idx, (k, v)) in keybinds.iter().enumerate() {
match v {
InputEvent::AutoSelect(..) => {
offset += 1;
continue;
}
_ => {}
}
if **k as u32 == 13 {
ctx.print(PLAY_WIDTH + 1, 18 + idx, format!("Enter:{:?}", v));
ctx.print(PLAY_WIDTH + 1, 18 + idx - offset, format!("Enter:{:?}", v));
} else if **k as u32 == 27 {
ctx.print(PLAY_WIDTH + 1, 18 + idx, format!("Esc:{:?}", v));
ctx.print(PLAY_WIDTH + 1, 18 + idx - offset, format!("Esc:{:?}", v));
} else {
ctx.print(PLAY_WIDTH + 1, 18 + idx, format!("{}:{:?}", k, v));
ctx.print(PLAY_WIDTH + 1, 18 + idx - offset, format!("{}:{:?}", k, v));
}
}

let selected_units = world.get::<SelectedUnits>().unwrap();
ctx.print(PLAY_WIDTH + 1, SCREEN_HEIGHT - 9, "Selected Units");
ctx.print(
PLAY_WIDTH + 1,
SCREEN_HEIGHT - 8,
format!("{:.2}", selected_units.units.len()),
);

let input_state = world.get::<InputState>().unwrap();
let is_txt = match *input_state {
InputState::Default => "Default",
InputState::MMove => "Move",
InputState::AMove => "Attack",
};
ctx.print(PLAY_WIDTH + 1, SCREEN_HEIGHT - 11, "InputState: ");
ctx.print(PLAY_WIDTH + 1, SCREEN_HEIGHT - 10, format!("{:.2}", is_txt));

let game_stats = world.get::<GameStats>().unwrap();
ctx.print(PLAY_WIDTH + 1, SCREEN_HEIGHT - 7, "Total Damage");
ctx.print(
Expand All @@ -110,3 +135,8 @@ pub fn render_ui(world: &mut World, ctx: &mut BTerm) {
);
}
}
/// Renders a cursor at mouse position
pub fn render_cursor(world: &mut World, ctx: &mut BTerm) {
let mouse = world.get::<Mouse>().unwrap();
ctx.print(mouse.pos.0, mouse.pos.1, format!(">"));
}
62 changes: 62 additions & 0 deletions src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,66 @@ pub struct Mouse {
pub pos: (i32, i32),
/// The left button was clicked
pub left_click: bool,
// /// The right button was clicked
// pub right_click: bool,
}

/// Current game mode. Used to disable/enable specific systems
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum GameMode {
/// Default game mode
Shotcaller,
/// Game mode where player directly controls individual units (aka. traditional RTS controls).
MircoInput,
}

impl Default for GameMode {
fn default() -> Self {
GameMode::Shotcaller
}
}

/// State of UI for micro-input
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum InputState {
/// Default state
Default,
/// State when next input is to be considered M-Move target
MMove,
/// State when next input is to be considered A-Move target
AMove,
}

impl Default for InputState {
fn default() -> Self {
InputState::Default
}
}

/// Stores units that were selected by the player
#[derive(Clone, Debug, new)]
pub struct SelectedUnits {
/// Vector of all selected Entities
pub units: Vec<Entity>,
}

impl Default for SelectedUnits {
fn default() -> Self {
SelectedUnits { units: vec![] }
}
}

/// Random number generator to be used in this game
#[derive(Clone, Debug, new)]
pub struct RandomNG {
/// rng
pub rng: oorandom::Rand32,
}

impl Default for RandomNG {
fn default() -> Self {
RandomNG {
rng: oorandom::Rand32::new(1),
}
}
}
4 changes: 4 additions & 0 deletions src/states/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ impl minigene::State for DefaultState {
}
ctx.set_active_console(0);
render_ui(world, ctx);
// TODO: Mouse cursor should be on top of all other sprites
render_cursor(world, ctx);
}

// Update mouse info
{
if let Ok(mut m) = world.get_mut::<Mouse>() {
m.pos = ctx.mouse_pos();
m.left_click = ctx.left_click;
// TODO: there is no variable ctx.right_click. Use rltk::Input::is_mouse_button_pressed(2)
//m.right_click = ctx.right_click;
}
}

Expand Down
Loading

0 comments on commit 9af271f

Please sign in to comment.