Jelajahi Sumber

Moved most of main into examples

Instead of shoving live-test code into main.rs, I'll try to place it
more into an example.

I've moved the example of making a TileIndex and displaying some of it's
contents, and now main.rs is back to being empty again. (Which is fine
since the next thing will be to make a ratatui app that can load and
render the tiles, basically a 'Tile Editor' to add/remove and change
tiles in the data/tiles.json file for the game)
Apollo 4 minggu lalu
induk
melakukan
87325965a6
4 mengubah file dengan 112 tambahan dan 62 penghapusan
  1. 96 0
      examples/tiles.rs
  2. 10 10
      src/chunk.rs
  3. 0 52
      src/main.rs
  4. 6 0
      src/tile_index.rs

+ 96 - 0
examples/tiles.rs

@@ -0,0 +1,96 @@
+/* This file is to show and setup a decent population of tiles (possibly to be used in-game)
+
+   This shows:
+   + How to check there are tiles, and if they don't exist, pre-populate some in
+   + Iterate all the tiles and display the juicy inners of each tile
+*/
+
+use std::path::PathBuf;
+
+use anyhow::bail;
+use rmmo::{TileIndex, Tile};
+
+fn main() -> Result<(), anyhow::Error> {
+    match TileIndex::load(PathBuf::from("data/tiles.json")) {
+        Ok(ti) => {
+            println!("Loaded {} tiles:", ti.len());
+            let mut idx = 0;
+            for t in ti {
+                if let Some(desc) = t.description {
+                    println!("{:3}] name=\"{:25}\" \"{:1}\" color=\"{:25}\" description=\"{}\"", idx, t.name, t.symbol, t.color, desc);
+                } else {
+                    println!("{:3}] name=\"{:25}\" \"{:1}\" color=\"{:25}\" description=None", idx, t.name, t.symbol, t.color);
+                }
+                idx += 1;
+            }
+        },
+        Err(err) => {
+            // Covers Windows and Linux "Not Found" error message (If it isn't either of these bail)
+            if err.to_string() != "The system cannot find the file specified. (os error 2)" && err.to_string() != "No such file or directory (os error 2)" {
+                bail!(err);
+            }
+            // Ok must be "Not Found", so let's make a new one
+            let mut ti = TileIndex::new();
+            //ti.define(Tile::new("", "", ""));
+            //ti.define(Tile::with_description("", "", "", ""));
+            ti.define(Tile::with_description("void", "", "", "You can fly over this, or fall into it"));
+            ti.define(Tile::with_description("player", "@", "bright green", "You"));
+            ti.define(Tile::with_description("player-neutral", "@", "bright white", "Another player"));
+            ti.define(Tile::with_description("player-ally", "@", "green", "Another player, an ally"));
+            ti.define(Tile::with_description("player-enemy", "@", "bright red", "Another player, an enemy"));
+            ti.define(Tile::with_description("path-grass", ".", "green", "A grassy path"));
+            ti.define(Tile::with_description("path-stone", ".", "white", "A stoney path"));
+            ti.define(Tile::with_description("water-shallow", "~", "bright cyan", "Shallow Water (Movement 60%, Can swim"));
+            ti.define(Tile::with_description("water-deep", "~", "bright blue", "Deep Water (Can not swim)"));
+            ti.define(Tile::with_description("tree-small", "t", "green", "A small Tree, flammable, produces wood"));
+            ti.define(Tile::with_description("tree-large", "T", "green", "A large Tree, flammable, produces wood"));
+            ti.define(Tile::with_description("crystal-small", "*", "magenta", "A small crystal, probably from killing a monster"));
+            ti.define(Tile::with_description("crystal-large", "*", "bright magenta", "A large crystal, probably from killing a monster"));
+            ti.define(Tile::with_description("gold", "$", "bright yellow", "Some gold coins, useful to buy something"));
+            ti.define(Tile::with_description("gem-red", "*", "red", "A ruby gemstone"));
+            ti.define(Tile::with_description("gem-green", "*", "green", "A emerald gemstone"));
+            ti.define(Tile::with_description("wall-v", "|", "white", "A stone wall"));
+            ti.define(Tile::with_description("wall-h", "-", "white", "A stone wall"));
+            ti.define(Tile::with_description("door-c", "+", "brown", "A wooden door, closed (maybe you should Open it?)"));
+            ti.define(Tile::with_description("door-o", "-", "brown", "A wooden door, opened (you could Close it, or walk thru it)"));
+            ti.define(Tile::with_description("stairs-up", ">", "white", "A staircase leading upward"));
+            ti.define(Tile::with_description("stairs-down", "<", "white", "A staircase leading downward"));
+            ti.define(Tile::with_description("checkpoint", ";", "bright cyan", "A checkpoint (useful for going to the surface, and returning to this level)"));
+            ti.define(Tile::with_description("trap-disabled", "^", "white", "A trap, appears to be disabled or broken"));
+            ti.define(Tile::with_description("trap-arrow", "^", "bright white", "A arrow trap"));
+            ti.define(Tile::with_description("trap-bear", "^", "brown", "A bear trap, can cripple you for some time"));
+            ti.define(Tile::with_description("trap-teleport", "^", "bright cyan", "A teleport trap, teleports you randomly between the upper level, this level or the next deeper level"));
+            ti.define(Tile::with_description("trap-fire", "^", "red", "A fire trap, can ignite you dealing damage over time"));
+            ti.define(Tile::with_description("trap-time", "^", "bright yellow", "A time stop trap, you will be caught in a magical time stop for quite some time"));
+            ti.define(Tile::with_description("trap-sound", "^", "green", "A sound trap, will emit a loud sound (which will attract monsters near by)"));
+            ti.define(Tile::with_description("food-ration", "%", "brown", "A food ration"));
+            ti.define(Tile::with_description("food-apple", "%", "red", "A apple"));
+            ti.define(Tile::with_description("food-egg", "%", "bright white", "A egg"));
+            ti.define(Tile::with_description("food-c-chicken", "%", "bright yellow", "A can of chicken"));
+            ti.define(Tile::with_description("food-c-tuna", "%", "bright cyan", "A can of tuna fish"));
+            ti.define(Tile::with_description("key", "F", "bright white", "A key (used to unlock further dungeon levels)"));
+            ti.define(Tile::with_description("potion-heal", "b", "red", "A potion of healing"));
+            ti.define(Tile::with_description("potion-magic", "b", "cyan", "A potion of mana"));
+            ti.define(Tile::with_description("potion-surface", "b", "bright cyan", "A potion of returning (Drink this to return to the surface)"));
+            ti.define(Tile::with_description("potion-poison", "b", "green", "A potion of poison (Deals some damage over time)"));
+            ti.define(Tile::with_description("potion-suicide", "b", "bright red", "A potion of suicide (Drink this to end it all)"));
+            ti.define(Tile::with_description("monster-rat", "r", "brown", "A rat"));
+            ti.define(Tile::with_description("monster-coyote", "c", "brown", "A coyote"));
+            ti.define(Tile::with_description("monster-minotaur", "M", "brown", "The Minotaur (Level 5 Boss)"));
+            ti.define(Tile::with_description("monster-wolf", "w", "white", "A wolf (Slightly bigger than a coyote, and twice as vicious)"));
+            ti.define(Tile::with_description("monster-slime", "n", "green", "A green slimy ooze"));
+            ti.define(Tile::with_description("monster-goblin", "G", "green", "A goblin"));
+            ti.define(Tile::with_description("monster-troll", "T", "white", "A troll"));
+            ti.define(Tile::with_description("monster-dragon-red", "D", "red", "The Red Dragon (Level 10 Boss)"));
+            ti.define(Tile::with_description("monster-skeleton", "A", "bright white", "A skeleton"));
+            ti.define(Tile::with_description("monster-s-troll", "T", "bright white", "A giant skeleton (Once was a troll)"));
+            ti.define(Tile::with_description("monster-dragon-green", "D", "green", "The Green Dragon (Level 15 Boss)"));
+            ti.define(Tile::with_description("monster-titan", "T", "bright magenta", "A giant Titan"));
+            ti.define(Tile::with_description("monster-mimic-crystal", "*", "cyan", "A Mimic (appearing as some crystal)"));
+
+            ti.save(PathBuf::from("data/tiles.json"))?;
+            println!("Created {} tiles", ti.len());
+        }
+    }
+    Ok(())
+}

+ 10 - 10
src/chunk.rs

@@ -2,7 +2,7 @@ use std::{cmp::Ordering::Greater, fmt::{Debug, Display}, ops::{Index, IndexMut}}
 use point::Point;
 use serde::{Deserialize, Serialize};
 
-fn p_idx(p: &Point<u32>) -> usize {
+fn point_to_index(p: &Point<u32>) -> usize {
     ((p.y * 32) + p.x) as usize
 }
 
@@ -14,7 +14,7 @@ pub struct Chunk {
 impl Index<Point<u32>> for Chunk {
     type Output = u64;
     fn index(&self, index: Point<u32>) -> &Self::Output {
-        let idx = p_idx(&index);
+        let idx = point_to_index(&index);
         if idx >= 32*32 {
             panic!("index out of bounds");
         }
@@ -24,7 +24,7 @@ impl Index<Point<u32>> for Chunk {
 
 impl IndexMut<Point<u32>> for Chunk {
     fn index_mut(&mut self, index: Point<u32>) -> &mut Self::Output {
-        let idx = p_idx(&index);
+        let idx = point_to_index(&index);
         if idx >= 32*32 {
             panic!("index out of bounds");
         }
@@ -35,7 +35,7 @@ impl IndexMut<Point<u32>> for Chunk {
 impl Index<&Point<u32>> for Chunk {
     type Output = u64;
     fn index(&self, index: &Point<u32>) -> &Self::Output {
-        let idx = p_idx(index);
+        let idx = point_to_index(index);
         if idx >= 32*32 {
             panic!("index out of bounds");
         }
@@ -45,7 +45,7 @@ impl Index<&Point<u32>> for Chunk {
 
 impl IndexMut<&Point<u32>> for Chunk {
     fn index_mut(&mut self, index: &Point<u32>) -> &mut Self::Output {
-        let idx = p_idx(index);
+        let idx = point_to_index(index);
         if idx >= 32*32 {
             panic!("index out of bounds");
         }
@@ -65,21 +65,21 @@ impl Chunk {
         s
     }
     pub fn get(&self, pos: &Point<u32>) -> Option<&u64> {
-        let idx = p_idx(pos);
+        let idx = point_to_index(pos);
         if idx >= 32*32 {
             return None;
         }
         self.tiles.get(idx)
     }
     pub fn get_mut(&mut self, pos: &Point<u32>) -> Option<&mut u64> {
-        let idx = p_idx(pos);
+        let idx = point_to_index(pos);
         if idx >= 32*32 {
             return None;
         }
         self.tiles.get_mut(idx)
     }
     pub fn set(&mut self, pos: &Point<u32>, value: u64) -> bool {
-        let idx = p_idx(pos);
+        let idx = point_to_index(pos);
         if idx >= 32*32 {
             return false;
         }
@@ -89,10 +89,10 @@ impl Chunk {
     pub fn fill(&mut self, pos1: &Point<u32>, pos2: &Point<u32>, value: u64) -> bool {
         let (corn1, corn2) = match pos1.partial_cmp(pos2).unwrap() {
             Greater => {
-                (p_idx(pos2), p_idx(pos1))
+                (point_to_index(pos2), point_to_index(pos1))
             },
             _ => {
-                (p_idx(pos1), p_idx(pos2))
+                (point_to_index(pos1), point_to_index(pos2))
             }
         };
         if corn1 >= 32*32 || corn2 >= 32*32 {

+ 0 - 52
src/main.rs

@@ -6,59 +6,7 @@ mod server;
 use server::AppServer;
 */
 
-use std::path::PathBuf;
-
-use point::Point;
-use rmmo::*;
-
 fn main() -> Result<(), anyhow::Error> {
     println!("Hello, World!");
-    let r = TileIndex::load(PathBuf::from("tiles.json"));
-    match r {
-        Ok(index) => {
-            println!("Located {} tiles", index.len());
-            let mut idx: usize = 0;
-            for t in index.clone() {
-                if let Some(desc) = &t.description {
-                    println!("{:3}] \"{:25}\" = '{:1}' {:25} \"{}\"", idx, t.name, t.symbol, t.color, desc);
-                } else {
-                    println!("{:3}] \"{:25}\" = '{:1}' {:25}", idx, t.name, t.symbol, t.color);
-                }
-                idx += 1;
-            }
-            let mut c = Chunk::new();
-            if let Some(floor) = index.lookup_index("ground-stone") {
-                c.fill(&Point::from((3, 3)), &Point::from((4, 4)), floor);
-            }
-            println!("{}", c);
-        }
-        Err(err) => {
-            if err.to_string() != "The system cannot find the file specified. (os error 2)".to_string() && err.to_string() != "No such file or directory (os error 2)".to_string() {
-                anyhow::bail!(err);
-            }
-            let mut index = TileIndex::new();
-            // index.define(Tile::with_description("", "", "", ""));
-            index.define(Tile::with_description("void", "", "", "You can fly over it, or fall into it"));
-            index.define(Tile::with_description("player", "@", "bright green", "You"));
-            index.define(Tile::with_description("player-neutral", "@", "bright white", "Somebody else"));
-            index.define(Tile::with_description("player-enemy", "@", "bright red", "Somebody else, that's mean"));
-            index.define(Tile::with_description("player-ally", "@", "green", "Somebody else, that's nice"));
-            index.define(Tile::with_description("ground-stone", ".", "white", "A stone path"));
-            index.define(Tile::with_description("ground-grass", ".", "green", "A grassy path"));
-            index.define(Tile::with_description("wall-v-stone", "|", "white", "A stone wall"));
-            index.define(Tile::with_description("wall-h-stone", "-", "white", "A stone wall"));
-            index.define(Tile::with_description("door-c-wood", "+", "brown", "A closed door"));
-            index.define(Tile::with_description("door-o-wood", "-", "brown", "A open door, you can move thru it"));
-            index.define(Tile::with_description("water-shallow", "~", "cyan", "Shallow water, you can wade thru it"));
-            index.define(Tile::with_description("water-deep", "~", "bright blue", "Deep water, you can swim thru it"));
-            index.define(Tile::with_description("gold", "$", "bright yellow", "Gold, a common currency"));
-            index.define(Tile::with_description("gem-blue", "*", "bright cyan", "Sapphire, a rare currency"));
-            index.define(Tile::with_description("gem-red", "*", "red", "Ruby, a rare currency"));
-            index.define(Tile::with_description("gem-green", "*", "bright green", "Emerald, a rare currency"));
-            index.define(Tile::with_description("gem-magenta", "*", "bright magenta", "Amethyst, a rare currency"));
-            index.save(PathBuf::from("tiles.json"))?;
-            println!("Created {} tiles", index.len());
-        }
-    }
     Ok(())
 }

+ 6 - 0
src/tile_index.rs

@@ -20,6 +20,12 @@ impl TileIndex {
     }
     pub fn save(&self, path: PathBuf) -> Result<(), anyhow::Error> {
         let content = serde_json::to_string_pretty(self)?;
+        let p = path.to_string_lossy().to_string();
+        let p = p.strip_suffix(path.file_name().unwrap().to_string_lossy().to_string().as_str()).unwrap();
+        let p  = PathBuf::from(p);
+        if !p.exists() {
+            fs::create_dir_all(p)?;
+        }
         fs::write(path, content)?;
         Ok(())
     }