use crate::actor::Actor;
use crate::console::Color;
use crate::database::Database;
use crate::error::GameError;
use crate::game_data::GameData;
use crate::item::ItemStash;
use crate::material::MaterialInfo;
use crate::object::Object;
use crate::ui::Draw;
use crate::{GameResult, GAMEDATA};
use std::cell::{Cell, RefCell};
use std::str::FromStr;
use std::sync::Arc;
#[derive(Debug)]
pub struct TileInfo {
pub material: Arc<MaterialInfo>,
pub name: String,
pub c: char,
pub passable: bool,
pub transparent: bool,
pub staircase: Staircase,
}
impl TileInfo {
pub fn new(game_data: &GameData, tile_data: &Database) -> GameResult<TileInfo> {
let _material = tile_data.get_obj("material")?;
let mname = _material.get_str("name")?;
let id = _material.id();
let material = game_data.material_info(id);
let name = tile_data.get_str("name")?;
let c = tile_data.get_char("c")?;
let passable = tile_data.get_bool("passable")?;
let transparent = tile_data.get_bool("transparent")?;
let staircase = Staircase::from_str(&tile_data.get_str("staircase")?)?;
let tile_info = TileInfo {
material,
name,
c,
passable,
transparent,
staircase,
};
Ok(tile_info)
}
pub fn full_name(&self) -> String {
format!("{} {}", self.material.adjective, self.name)
}
}
impl Draw for TileInfo {
fn draw_c(&self) -> char {
self.c
}
fn draw_color(&self) -> Color {
self.material.color
}
}
#[derive(Clone, Debug)]
pub struct Tile {
pub info: Arc<TileInfo>,
pub last_seen: Cell<Option<(char, Color)>>,
pub height: i32,
pub actor: Option<Actor>,
pub object: Option<Object>,
pub item_stash: Option<Box<ItemStash>>,
}
impl Tile {
pub fn new(tile_data: &Database) -> GameResult<Tile> {
let id = tile_data.id();
let info = GAMEDATA.read().unwrap().tile_info(id);
Ok(Tile {
info,
last_seen: Cell::new(None),
height: 0,
actor: None,
object: None,
item_stash: None,
})
}
pub fn set_tile_info(&mut self, tile_data: &Database) -> GameResult<()> {
let id = tile_data.id();
self.info = GAMEDATA.read().unwrap().tile_info(id);
Ok(())
}
}
impl Tile {
pub fn passable(&self) -> bool {
self.info.passable
}
pub fn transparent(&self) -> bool {
self.info.transparent
}
pub fn staircase(&self) -> Staircase {
self.info.staircase
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Staircase {
Up,
Down,
UpDown,
None,
}
impl FromStr for Staircase {
type Err = GameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"up" => Staircase::Up,
"down" => Staircase::Down,
"updown" => Staircase::UpDown,
"none" => Staircase::None,
_ => {
return Err(GameError::ConversionError {
val: s.into(),
msg: "Invalid staircase value",
});
}
})
}
}