Fireball constants
This commit is contained in:
parent
2640bea49e
commit
93b270c5f3
83
src/main.rs
83
src/main.rs
@ -53,6 +53,8 @@ const LIGHTNING_DAMAGE: i32 = 40;
|
|||||||
const LIGHTNING_RANGE: i32 = 5;
|
const LIGHTNING_RANGE: i32 = 5;
|
||||||
const CONFUSE_RANGE: i32 = 8;
|
const CONFUSE_RANGE: i32 = 8;
|
||||||
const CONFUSE_NUM_TURNS: i32 = 10;
|
const CONFUSE_NUM_TURNS: i32 = 10;
|
||||||
|
const FIREBALL_RADIUS: i32 = 3;
|
||||||
|
const FIREBALL_DAMAGE: i32 = 12;
|
||||||
|
|
||||||
struct Tcod {
|
struct Tcod {
|
||||||
root: Root,
|
root: Root,
|
||||||
@ -164,6 +166,11 @@ impl Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the distance to some coordinates
|
||||||
|
pub fn distance(&self, x: i32, y: i32) -> f32 {
|
||||||
|
(((x - self.x).pow(2) + (y - self.y).pow(2)) as f32).sqrt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@ -918,6 +925,44 @@ fn cast_confuse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cast_fireball(
|
||||||
|
_inventory_id: usize,
|
||||||
|
tcod: &mut Tcod,
|
||||||
|
game: &mut Game,
|
||||||
|
objects: &mut [Object],
|
||||||
|
) -> UseResult {
|
||||||
|
// Ask the player for a target tile to throw a fireball at
|
||||||
|
game.messages.add(
|
||||||
|
"Left-click a target tile for the fireball, or right-click to cancel.",
|
||||||
|
LIGHT_CYAN,
|
||||||
|
);
|
||||||
|
let (x, y) = match target_tile(tcod, game, objects, None) {
|
||||||
|
Some(tile_pos) => tile_pos,
|
||||||
|
None => return UseResult::Canceled,
|
||||||
|
};
|
||||||
|
game.messages.add(
|
||||||
|
format!(
|
||||||
|
"The fireball explodes, burning everything within {} tiles!",
|
||||||
|
FIREBALL_RADIUS
|
||||||
|
),
|
||||||
|
ORANGE,
|
||||||
|
);
|
||||||
|
|
||||||
|
for obj in objects {
|
||||||
|
if obj.distance(x, y) <= FIREBALL_RADIUS as f32 && obj.fighter.is_some() {
|
||||||
|
game.messages.add(
|
||||||
|
format!(
|
||||||
|
"The {} gets burned for {} hit points.",
|
||||||
|
obj.name, FIREBALL_DAMAGE
|
||||||
|
),
|
||||||
|
ORANGE,
|
||||||
|
);
|
||||||
|
obj.take_damage(FIREBALL_DAMAGE, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UseResult::UsedUp
|
||||||
|
}
|
||||||
|
|
||||||
// Find closest enemy, up to a maximum range, and in the player's FOV
|
// Find closest enemy, up to a maximum range, and in the player's FOV
|
||||||
fn closest_monster(tcod: &Tcod, objects: &[Object], max_range: i32) -> Option<usize> {
|
fn closest_monster(tcod: &Tcod, objects: &[Object], max_range: i32) -> Option<usize> {
|
||||||
let mut closest_enemy = None;
|
let mut closest_enemy = None;
|
||||||
@ -942,6 +987,44 @@ fn closest_monster(tcod: &Tcod, objects: &[Object], max_range: i32) -> Option<us
|
|||||||
closest_enemy
|
closest_enemy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the position of a tile left-clicked in player's FOV (optionally in a
|
||||||
|
// range), or (None, None) if right-clicked.
|
||||||
|
fn target_tile(
|
||||||
|
tcod: &mut Tcod,
|
||||||
|
game: &mut Game,
|
||||||
|
objects: &[Object],
|
||||||
|
max_range: Option<f32>,
|
||||||
|
) -> Option<(i32, i32)> {
|
||||||
|
use tcod::input::KeyCode::Escape;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Render the screen. This erases the inventory and shows the names of
|
||||||
|
// objects under the mouse.
|
||||||
|
tcod.root.flush();
|
||||||
|
let event = input::check_for_event(input::KEY_PRESS | input::MOUSE).map(|e| e.1);
|
||||||
|
match event {
|
||||||
|
Some(Event::Mouse(m)) => tcod.mouse = m,
|
||||||
|
Some(Event::Key(k)) => tcod.key = k,
|
||||||
|
None => tcod.key = Default::default(),
|
||||||
|
}
|
||||||
|
render_all(tcod, game, objects, false);
|
||||||
|
|
||||||
|
let (x, y) = (tcod.mouse.cx as i32, tcod.mouse.cy as i32);
|
||||||
|
|
||||||
|
// Accept the target if the player clicked in FOV, and in case a range
|
||||||
|
// is specified, if it's in that range
|
||||||
|
let in_fov = (x < MAP_WIDTH) && (y < MAP_HEIGHT) && tcod.fov.is_in_fov(x, y);
|
||||||
|
let in_range = max_range.map_or(true, |range| objects[PLAYER].distance(x, y) <= range);
|
||||||
|
if tcod.mouse.lbutton_pressed && in_fov && in_range {
|
||||||
|
return Some((x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
if tcod.mouse.rbutton_pressed || tcod.key.code == Escape {
|
||||||
|
return None; // Cancel if the player right-clicked or pressed escape.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn render_all(tcod: &mut Tcod, game: &mut Game, objects: &[Object], fov_recompute: bool) {
|
fn render_all(tcod: &mut Tcod, game: &mut Game, objects: &[Object], fov_recompute: bool) {
|
||||||
if fov_recompute {
|
if fov_recompute {
|
||||||
let player = &objects[PLAYER];
|
let player = &objects[PLAYER];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user