From 2887bb9736aa00b08eb6967fe0a66ba4ea24b499 Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Tue, 15 Aug 2023 21:18:28 +0100 Subject: [PATCH] prevents energy from ticking up whilst AI is culled --- raws/mobs.json | 6 ++--- src/ai/default_move_system.rs | 49 ++++++++++++++++++++++++++++++----- src/ai/energy_system.rs | 2 +- src/components.rs | 1 + src/main.rs | 2 +- src/raws/rawmaster.rs | 4 +++ 6 files changed, 53 insertions(+), 11 deletions(-) diff --git a/raws/mobs.json b/raws/mobs.json index 1e403c8..987cd85 100644 --- a/raws/mobs.json +++ b/raws/mobs.json @@ -11,7 +11,7 @@ "id": "npc_townsperson", "name": "townsperson", "renderable": { "glyph": "@", "fg": "#9fa86c", "bg": "#000000", "order": 1 }, - "flags": ["NEUTRAL"], + "flags": ["NEUTRAL", "RANDOM_PATH"], "vision_range": 4, "quips": ["Hello!", "Good morning.", ""] }, @@ -60,7 +60,7 @@ "id": "npc_guard", "name": "smalltown guard", "renderable": { "glyph": "@", "fg": "#034efc", "bg": "#000000", "order": 1 }, - "flags": ["NEUTRAL"], + "flags": ["NEUTRAL", "RANDOM_PATH"], "level": 2, "vision_range": 4, "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }], @@ -71,7 +71,7 @@ "id": "rat", "name": "rat", "renderable": { "glyph": "r", "fg": "#aa6000", "bg": "#000000", "order": 1 }, - "flags": ["MONSTER"], + "flags": [], "bac": 6, "vision_range": 8, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }], diff --git a/src/ai/default_move_system.rs b/src/ai/default_move_system.rs index c277d2b..4100834 100644 --- a/src/ai/default_move_system.rs +++ b/src/ai/default_move_system.rs @@ -1,4 +1,4 @@ -use crate::{EntityMoved, Map, MoveMode, Movement, Position, TakingTurn, Telepath, Viewshed}; +use crate::{tile_walkable, EntityMoved, Map, MoveMode, Movement, Position, TakingTurn, Telepath, Viewshed}; use specs::prelude::*; // Rolling a 1d8+x to decide where to move, where x are the number @@ -10,7 +10,7 @@ pub struct DefaultAI {} impl<'a> System<'a> for DefaultAI { type SystemData = ( WriteStorage<'a, TakingTurn>, - ReadStorage<'a, MoveMode>, + WriteStorage<'a, MoveMode>, WriteStorage<'a, Position>, WriteExpect<'a, Map>, WriteStorage<'a, Viewshed>, @@ -23,7 +23,7 @@ impl<'a> System<'a> for DefaultAI { fn run(&mut self, data: Self::SystemData) { let ( mut turns, - move_mode, + mut move_mode, mut positions, mut map, mut viewsheds, @@ -33,11 +33,11 @@ impl<'a> System<'a> for DefaultAI { entities, ) = data; let mut turn_done: Vec = Vec::new(); - for (entity, _turn, mut pos, move_mode, mut viewshed) in - (&entities, &turns, &mut positions, &move_mode, &mut viewsheds).join() + for (entity, _turn, mut pos, mut move_mode, mut viewshed) in + (&entities, &turns, &mut positions, &mut move_mode, &mut viewsheds).join() { turn_done.push(entity); - match move_mode.mode { + match &mut move_mode.mode { Movement::Static => {} Movement::Random => { let mut x = pos.x; @@ -83,6 +83,43 @@ impl<'a> System<'a> for DefaultAI { } } } + Movement::RandomWaypoint { path } => { + if let Some(path) = path { + // We have a path - follow it + let mut idx = map.xy_idx(pos.x, pos.y); + if path.len() > 1 { + if !map.blocked[path[1] as usize] { + map.blocked[idx] = false; + pos.x = path[1] as i32 % map.width; + pos.y = path[1] as i32 / map.width; + entity_moved.insert(entity, EntityMoved {}).expect("Unable to insert EntityMoved"); + idx = map.xy_idx(pos.x, pos.y); + map.blocked[idx] = true; + viewshed.dirty = true; + if let Some(is_telepath) = telepaths.get_mut(entity) { + is_telepath.dirty = true; + } + path.remove(0); + } + } else { + move_mode.mode = Movement::RandomWaypoint { path: None }; + } + } else { + let target_x = rng.roll_dice(1, map.width - 2); + let target_y = rng.roll_dice(1, map.height - 2); + let idx = map.xy_idx(target_x, target_y); + if tile_walkable(map.tiles[idx]) { + let path = rltk::a_star_search( + map.xy_idx(pos.x, pos.y) as i32, + map.xy_idx(target_x, target_y) as i32, + &mut *map, + ); + if path.success && path.steps.len() > 1 { + move_mode.mode = Movement::RandomWaypoint { path: Some(path.steps) }; + } + } + } + } } } for done in turn_done.iter() { diff --git a/src/ai/energy_system.rs b/src/ai/energy_system.rs index 13a5ad9..b4ee5c2 100644 --- a/src/ai/energy_system.rs +++ b/src/ai/energy_system.rs @@ -90,6 +90,7 @@ impl<'a> System<'a> for EnergySystem { // by TURN_COST. If the current entity is the player, await input. if energy.current >= TURN_COST { let mut my_turn = true; + energy.current -= TURN_COST; if entity == *player { *runstate = RunState::AwaitingInput; } else { @@ -100,7 +101,6 @@ impl<'a> System<'a> for EnergySystem { } if my_turn { turns.insert(entity, TakingTurn {}).expect("Unable to insert turn."); - energy.current -= TURN_COST; if LOG_TICKS { let name = if let Some(name) = names.get(entity) { &name.name } else { "Unknown entity" }; console::log(format!( diff --git a/src/components.rs b/src/components.rs index e83168b..6681bf9 100644 --- a/src/components.rs +++ b/src/components.rs @@ -55,6 +55,7 @@ pub struct Faction { pub enum Movement { Static, Random, + RandomWaypoint { path: Option> }, } #[derive(Component, Debug, Serialize, Deserialize, Clone)] diff --git a/src/main.rs b/src/main.rs index 7e572e4..f13c472 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ extern crate lazy_static; //Consts pub const SHOW_MAPGEN: bool = false; pub const LOG_SPAWNING: bool = true; -pub const LOG_TICKS: bool = false; +pub const LOG_TICKS: bool = true; #[derive(PartialEq, Copy, Clone)] pub enum RunState { diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index 123cd01..2918979 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -301,6 +301,10 @@ pub fn spawn_named_mob( eb = eb.with(MoveMode { mode: Movement::Static }); has_move_mode = true; } + "RANDOM_PATH" => { + eb = eb.with(MoveMode { mode: Movement::RandomWaypoint { path: None } }); + has_move_mode = true; + } "MINDLESS" => { eb = eb.with(Faction { name: "mindless".to_string() }); has_faction = true;