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 CONFUSE_RANGE: i32 = 8;
|
||||
const CONFUSE_NUM_TURNS: i32 = 10;
|
||||
const FIREBALL_RADIUS: i32 = 3;
|
||||
const FIREBALL_DAMAGE: i32 = 12;
|
||||
|
||||
struct Tcod {
|
||||
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)]
|
||||
@ -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
|
||||
fn closest_monster(tcod: &Tcod, objects: &[Object], max_range: i32) -> Option<usize> {
|
||||
let mut closest_enemy = None;
|
||||
@ -942,6 +987,44 @@ fn closest_monster(tcod: &Tcod, objects: &[Object], max_range: i32) -> Option<us
|
||||
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) {
|
||||
if fov_recompute {
|
||||
let player = &objects[PLAYER];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user