|
@@ -1,108 +1,105 @@
|
|
-use std::collections::HashMap;
|
|
|
|
|
|
+use std::{fs, path::PathBuf, iter::Iterator};
|
|
|
|
+
|
|
use serde::{Deserialize, Serialize};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
use crate::Tile;
|
|
use crate::Tile;
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
|
pub struct TileIndex {
|
|
pub struct TileIndex {
|
|
- pub tiles: HashMap<String, Tile>
|
|
|
|
|
|
+ tiles: Vec<Tile>
|
|
}
|
|
}
|
|
|
|
|
|
impl TileIndex {
|
|
impl TileIndex {
|
|
- pub fn has(&self, name: &str) -> bool {
|
|
|
|
- self.tiles.contains_key(&name.to_string())
|
|
|
|
|
|
+ pub fn new() -> Self {
|
|
|
|
+ Self { tiles: Vec::new() }
|
|
}
|
|
}
|
|
- pub fn get_index(&self, name: &str) -> Option<usize> {
|
|
|
|
- if !self.tiles.contains_key(&name.to_string()) {
|
|
|
|
- return None;
|
|
|
|
- }
|
|
|
|
- let mut index: usize = 0;
|
|
|
|
- for (k, _v) in self.tiles.iter() {
|
|
|
|
- if k == &name.to_string() {
|
|
|
|
- return Some(index);
|
|
|
|
- }
|
|
|
|
- index += 1;
|
|
|
|
- }
|
|
|
|
- None
|
|
|
|
|
|
+ pub fn load(path: PathBuf) -> Result<Self, anyhow::Error> {
|
|
|
|
+ let content = fs::read_to_string(path)?;
|
|
|
|
+ let index = serde_json::from_str::<TileIndex>(&content)?;
|
|
|
|
+ Ok(index)
|
|
}
|
|
}
|
|
- pub fn has_index(&self, index: usize) -> bool {
|
|
|
|
- if self.tiles.len() < index {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
|
|
+ pub fn save(&self, path: PathBuf) -> Result<(), anyhow::Error> {
|
|
|
|
+ let content = serde_json::to_string_pretty(self)?;
|
|
|
|
+ fs::write(path, content)?;
|
|
|
|
+ Ok(())
|
|
|
|
+ }
|
|
|
|
+ pub fn len(&self) -> usize {
|
|
|
|
+ self.tiles.len()
|
|
|
|
+ }
|
|
|
|
+ pub fn lookup_index(&self, name: &str) -> Option<usize> {
|
|
let mut idx: usize = 0;
|
|
let mut idx: usize = 0;
|
|
- for (_k, _v) in self.tiles.iter() {
|
|
|
|
- if idx == index {
|
|
|
|
- return true;
|
|
|
|
|
|
+ for t in self.tiles.iter() {
|
|
|
|
+ if t.name == name.to_string() {
|
|
|
|
+ return Some(idx);
|
|
}
|
|
}
|
|
idx += 1;
|
|
idx += 1;
|
|
}
|
|
}
|
|
- false
|
|
|
|
|
|
+ None
|
|
}
|
|
}
|
|
- pub fn set_index(&mut self, index: usize, t: Tile) {
|
|
|
|
- if self.tiles.len() < index {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- let mut idx: usize = 0;
|
|
|
|
- for (k, _v) in self.tiles.iter() {
|
|
|
|
- if idx == index {
|
|
|
|
- self.tiles.insert(k.clone(), t);
|
|
|
|
- return;
|
|
|
|
|
|
+ pub fn get_name(&self, name: &str) -> Option<&Tile> {
|
|
|
|
+ for t in self.tiles.iter() {
|
|
|
|
+ if t.name == name.to_string() {
|
|
|
|
+ return Some(t);
|
|
}
|
|
}
|
|
- idx += 1;
|
|
|
|
}
|
|
}
|
|
|
|
+ None
|
|
}
|
|
}
|
|
- pub fn get(&self, name: &str) -> Option<&Tile> {
|
|
|
|
- if !self.tiles.contains_key(&name.to_string()) {
|
|
|
|
|
|
+ pub fn get_index(&self, index: usize) -> Option<&Tile> {
|
|
|
|
+ if index >= self.tiles.len() {
|
|
return None;
|
|
return None;
|
|
}
|
|
}
|
|
- self.tiles.get(&name.to_string())
|
|
|
|
|
|
+ Some(&self.tiles[index])
|
|
}
|
|
}
|
|
- pub fn get_mut(&mut self, name: &str) -> Option<&mut Tile> {
|
|
|
|
- if !self.tiles.contains_key(&name.to_string()) {
|
|
|
|
- return None;
|
|
|
|
|
|
+ pub fn set(&mut self, t: Tile) -> usize {
|
|
|
|
+ if let Some(idx) = self.lookup_index(&t.name) {
|
|
|
|
+ self.tiles[idx] = t;
|
|
|
|
+ return idx;
|
|
}
|
|
}
|
|
- self.tiles.get_mut(&name.to_string())
|
|
|
|
|
|
+ self.tiles.push(t);
|
|
|
|
+ self.tiles.len()
|
|
}
|
|
}
|
|
- pub fn set(&mut self, name: &str, t: Tile) {
|
|
|
|
- self.tiles.insert(name.to_string(), t);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn new() -> Self {
|
|
|
|
- let mut s: Self = Self { tiles: HashMap::with_capacity(24) };
|
|
|
|
- // s.set("", Tile::with_description("", "", ""));
|
|
|
|
- // s.set("", Tile::new("", ""));
|
|
|
|
- s.set("void", Tile::with_description("", "", "You can fly over the void, or fall into it"));
|
|
|
|
- s.set("player", Tile::with_description("@", "lime", "You"));
|
|
|
|
- s.set("player-ally", Tile::with_description("@", "green", "Another Player, an ally to you"));
|
|
|
|
- s.set("player-neutral", Tile::with_description("@", "silver", "Another Player, neutral to you"));
|
|
|
|
- s.set("player-enemy", Tile::with_description("@", "red", "Another Player, an enemy to you"));
|
|
|
|
- s.set("ground-stone", Tile::with_description(".", "gray", "A stone path, you can walk over it"));
|
|
|
|
- s.set("ground-grass", Tile::with_description(".", "green", "A grassy path, you can walk over it"));
|
|
|
|
- s.set("ground-sand", Tile::with_description(".", "yellow", "A sandy path, you can walk over it"));
|
|
|
|
- s.set("wall-v-stone", Tile::with_description("|", "gray", "A stone wall"));
|
|
|
|
- s.set("wall-h-stone", Tile::with_description("-", "gray", "A stone wall"));
|
|
|
|
- s.set("wall-v-wood", Tile::with_description("|", "brown", "A wooden wall, flammable"));
|
|
|
|
- s.set("wall-h-wood", Tile::with_description("-", "brown", "A wooden wall, flammable"));
|
|
|
|
- s.set("door-wood-closed", Tile::with_description("x", "brown", "A wooden door, flammable"));
|
|
|
|
- s.set("door-wood-open", Tile::with_description("+", "brown", "A wooden door, flammable, you can walk thru it"));
|
|
|
|
- s.set("door-stone-closed", Tile::with_description("x", "gray", "A stone door"));
|
|
|
|
- s.set("door-stone-open", Tile::with_description("+", "gray", "A stone door, you can walk thru it"));
|
|
|
|
- s.set("door-golden-closed", Tile::with_description("x", "gold", "A golden door, find a gold key to open"));
|
|
|
|
- s.set("door-golden-open", Tile::with_description("+", "gold", "A golden door, you can walk thru it"));
|
|
|
|
- s.set("gold", Tile::with_description("$", "yellow", "Gold, a common currency"));
|
|
|
|
- s.set("gem-blue", Tile::with_description("*", "cyan", "Sapphire, a rare currency"));
|
|
|
|
- s.set("gem-red", Tile::with_description("*", "bright red", "Ruby, a rare currency"));
|
|
|
|
- s.set("gem-green", Tile::with_description("*", "green", "Emerald, a rare currency"));
|
|
|
|
- s.set("gem-purple", Tile::with_description("*", "magenta", "Amethyst, a rare currency"));
|
|
|
|
- s.set("gem-white", Tile::with_description("*", "bright white", "Quartz, a rare currency"));
|
|
|
|
- s
|
|
|
|
|
|
+ pub fn define(&mut self, t: Tile) -> bool {
|
|
|
|
+ if let Some(_idx) = self.lookup_index(&t.name) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ self.tiles.push(t);
|
|
|
|
+ true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Default for TileIndex {
|
|
impl Default for TileIndex {
|
|
fn default() -> Self {
|
|
fn default() -> Self {
|
|
- let mut s = Self { tiles: HashMap::with_capacity(1) };
|
|
|
|
- s.set("void", Tile::with_description("", "", "You can fly over the void, or fall into it"));
|
|
|
|
- s
|
|
|
|
|
|
+ Self::new()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+pub struct TileIndexIter {
|
|
|
|
+ tile_index: TileIndex,
|
|
|
|
+ index: usize,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl TileIndexIter {
|
|
|
|
+ pub fn new(index: TileIndex) -> Self {
|
|
|
|
+ Self { tile_index: index, index: 0 }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl Iterator for TileIndexIter {
|
|
|
|
+ type Item = Tile;
|
|
|
|
+ fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
+ self.index += 1;
|
|
|
|
+ if let Some(t) = self.tile_index.get_index(self.index-1) {
|
|
|
|
+ Some(t.clone())
|
|
|
|
+ } else {
|
|
|
|
+ None
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl IntoIterator for TileIndex {
|
|
|
|
+ type IntoIter = TileIndexIter;
|
|
|
|
+ type Item = Tile;
|
|
|
|
+ fn into_iter(self) -> Self::IntoIter {
|
|
|
|
+ TileIndexIter::new(self)
|
|
}
|
|
}
|
|
}
|
|
}
|