mirror of
https://github.com/edg-l/ddnet-map-gen.git
synced 2024-11-09 09:38:22 +00:00
reorganize code, add cli interface
This commit is contained in:
parent
e6a00cda97
commit
8b1143de74
128
Cargo.lock
generated
128
Cargo.lock
generated
|
@ -152,12 +152,42 @@ dependencies = [
|
|||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"strsim 0.8.0",
|
||||
"textwrap 0.11.0",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"os_str_bytes",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.1"
|
||||
|
@ -248,6 +278,7 @@ dependencies = [
|
|||
name = "ddnet-map-gen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 3.1.6",
|
||||
"color-eyre",
|
||||
"eyre",
|
||||
"irrgarten",
|
||||
|
@ -366,6 +397,18 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -400,6 +443,16 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
|
@ -635,6 +688,15 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afbb993947f111397c2bc536944f8dac7f54a4e73383d478efe1990b56404b60"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.2.0"
|
||||
|
@ -671,6 +733,30 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
|
@ -887,6 +973,12 @@ version = "0.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "structview"
|
||||
version = "1.1.0"
|
||||
|
@ -933,6 +1025,15 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
@ -942,6 +1043,12 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
|
@ -1042,7 +1149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "cf21dc5f97009d394d536107e15193b7ce8ee035faa5a907eab8f10c1bb42432"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap",
|
||||
"clap 2.34.0",
|
||||
"flexi_logger",
|
||||
"image",
|
||||
"itertools 0.9.0",
|
||||
|
@ -1096,6 +1203,12 @@ version = "0.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
|
@ -1124,6 +1237,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3.1.6", features = ["cargo", "derive"] }
|
||||
color-eyre = "0.6.1"
|
||||
eyre = "0.6.7"
|
||||
irrgarten = "0.1.1"
|
||||
|
|
28
src/cli.rs
Normal file
28
src/cli.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use crate::generators::{fly::FlyGenerator, maze::MazeGenerator, MapGenerator};
|
||||
use clap::{arg, command, Command};
|
||||
use eyre::Result;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn run_cli() -> Result<()> {
|
||||
let matches = command!()
|
||||
.about("A DDraceNetwork map generator.")
|
||||
.arg_required_else_help(true)
|
||||
.subcommand_required(true)
|
||||
.arg(arg!(<FILE> "The output file").required(true))
|
||||
.subcommand(Command::new("maze").about("Generate a maze-like map."))
|
||||
.subcommand(Command::new("fly").about("Generate a map for fly techniques."))
|
||||
.get_matches();
|
||||
|
||||
let output = matches.value_of("FILE").expect("output is required");
|
||||
let output = Path::new(output);
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
match matches.subcommand() {
|
||||
Some(("maze", _sub_m)) => MazeGenerator::save_file(&mut rng, output)?,
|
||||
Some(("fly", _sub_m)) => FlyGenerator::save_file(&mut rng, output)?,
|
||||
_ => panic!("invalid command"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
98
src/generators/fly.rs
Normal file
98
src/generators/fly.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use super::*;
|
||||
use eyre::Result;
|
||||
use ndarray::Array2;
|
||||
use rand::Rng;
|
||||
|
||||
pub struct FlyGenerator;
|
||||
|
||||
impl MapGenerator for FlyGenerator {
|
||||
fn generate<R: Rng + ?Sized>(rng: &mut R) -> Result<TwMap> {
|
||||
let mut map = create_initial_map()?;
|
||||
|
||||
const HEIGHT: usize = 1000;
|
||||
const WIDTH: usize = 100;
|
||||
|
||||
let mut tiles = Array2::from_shape_simple_fn((HEIGHT, WIDTH), || {
|
||||
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
||||
});
|
||||
let mut front_tiles = Array2::from_shape_simple_fn((HEIGHT, WIDTH), || {
|
||||
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
||||
});
|
||||
|
||||
let mut unhookable_tiles =
|
||||
Array2::from_shape_simple_fn((HEIGHT, WIDTH), || Tile::new(0, TileFlags::empty()));
|
||||
let mut freeze_tiles =
|
||||
Array2::from_shape_simple_fn((HEIGHT, WIDTH), || Tile::new(0, TileFlags::empty()));
|
||||
|
||||
tiles
|
||||
.row_mut(HEIGHT - 2)
|
||||
.iter_mut()
|
||||
.for_each(|tile| tile.id = TILE_UNHOOKABLE);
|
||||
unhookable_tiles
|
||||
.row_mut(HEIGHT - 2)
|
||||
.iter_mut()
|
||||
.for_each(|tile| tile.id = 1);
|
||||
|
||||
tiles[(HEIGHT - 3, WIDTH / 2)].id = TILE_SPAWN;
|
||||
|
||||
for x in 0..WIDTH {
|
||||
front_tiles[(HEIGHT - 6, x)].id = TILE_START;
|
||||
front_tiles[(10, x)].id = TILE_FINISH;
|
||||
}
|
||||
|
||||
let mut center: i64 = WIDTH as i64 / 2;
|
||||
let mut fly_width: i64 = 10;
|
||||
|
||||
for y in (0..=(HEIGHT - 3)).rev() {
|
||||
let direction: i64 = rng.gen_range(-1..=1);
|
||||
let width_change: i64 = rng.gen_range(-1..=1);
|
||||
center += direction;
|
||||
fly_width += width_change;
|
||||
center = center.clamp(fly_width, WIDTH as i64 - fly_width);
|
||||
fly_width = fly_width.clamp(2, 12);
|
||||
|
||||
for x in ((center + fly_width) as usize)..WIDTH {
|
||||
tiles[(y, x)].id = TILE_FREEZE;
|
||||
freeze_tiles[(y, x)].id = 4;
|
||||
}
|
||||
|
||||
for x in 0..=((center - fly_width) as usize) {
|
||||
tiles[(y, x)].id = TILE_FREEZE;
|
||||
freeze_tiles[(y, x)].id = 4;
|
||||
}
|
||||
}
|
||||
|
||||
let game_layer = GameLayer {
|
||||
tiles: CompressedData::Loaded(tiles),
|
||||
};
|
||||
|
||||
let front_layer = FrontLayer {
|
||||
tiles: CompressedData::Loaded(front_tiles),
|
||||
};
|
||||
|
||||
let mut unhook_tiles_layer = TilesLayer::new((HEIGHT, WIDTH));
|
||||
unhook_tiles_layer.image = Some(0);
|
||||
unhook_tiles_layer.tiles = CompressedData::Loaded(unhookable_tiles);
|
||||
|
||||
let mut freeze_tiles_layer = TilesLayer::new((HEIGHT, WIDTH));
|
||||
freeze_tiles_layer.image = Some(1);
|
||||
freeze_tiles_layer.tiles = CompressedData::Loaded(freeze_tiles);
|
||||
freeze_tiles_layer.color = Color {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 200,
|
||||
};
|
||||
|
||||
let mut physics = Group::physics();
|
||||
physics.layers.push(Layer::Game(game_layer));
|
||||
physics.layers.push(Layer::Front(front_layer));
|
||||
physics.layers.push(Layer::Tiles(unhook_tiles_layer));
|
||||
physics.layers.push(Layer::Tiles(freeze_tiles_layer));
|
||||
|
||||
map.groups.push(quads_sky());
|
||||
map.groups.push(physics);
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
}
|
53
src/generators/maze.rs
Normal file
53
src/generators/maze.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use super::*;
|
||||
use eyre::Result;
|
||||
use irrgarten::Maze;
|
||||
use ndarray::Array2;
|
||||
|
||||
pub struct MazeGenerator;
|
||||
|
||||
impl MapGenerator for MazeGenerator {
|
||||
fn generate<R: Rng + ?Sized>(rng: &mut R) -> Result<TwMap> {
|
||||
let mut map = create_initial_map()?;
|
||||
let maze = Maze::new(1001, 1001).unwrap().generate(rng);
|
||||
|
||||
let mut tiles = Array2::from_shape_fn((1001, 1001), |(x, y)| {
|
||||
GameTile::new(maze[x][y], TileFlags::empty())
|
||||
});
|
||||
|
||||
// Put spawn and start tile on top left most tile.
|
||||
let mut added_spawn = false;
|
||||
'outerStart: for y in 0..101 {
|
||||
for x in 0..101 {
|
||||
let tile = &mut tiles[(x, y)];
|
||||
if tile.id == 0 && !added_spawn {
|
||||
*tile = GameTile::new(TILE_SPAWN, TileFlags::empty());
|
||||
added_spawn = true;
|
||||
} else if tile.id == 0 && added_spawn {
|
||||
*tile = GameTile::new(TILE_START, TileFlags::empty());
|
||||
break 'outerStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put finish tile on bottom right most tile.
|
||||
'outerFinish: for y in (0..1001).rev() {
|
||||
for x in (0..1001).rev() {
|
||||
let tile = &mut tiles[(x, y)];
|
||||
if tile.id == 0 {
|
||||
*tile = GameTile::new(TILE_FINISH, TileFlags::empty());
|
||||
break 'outerFinish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let game_layer = GameLayer {
|
||||
tiles: CompressedData::Loaded(tiles),
|
||||
};
|
||||
|
||||
let mut physics = Group::physics();
|
||||
physics.layers.push(Layer::Game(game_layer));
|
||||
map.groups.push(physics);
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
}
|
83
src/generators/mod.rs
Normal file
83
src/generators/mod.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
use std::path::Path;
|
||||
|
||||
use eyre::Result;
|
||||
use rand::Rng;
|
||||
use twmap::*;
|
||||
|
||||
pub mod fly;
|
||||
pub mod maze;
|
||||
|
||||
pub const TILE_EMPTY: u8 = 0;
|
||||
pub const TILE_HOOKABLE: u8 = 1;
|
||||
pub const TILE_UNHOOKABLE: u8 = 3;
|
||||
pub const TILE_FREEZE: u8 = 9;
|
||||
pub const TILE_UNFREEZE: u8 = 1;
|
||||
pub const TILE_START: u8 = 33;
|
||||
pub const TILE_FINISH: u8 = 34;
|
||||
pub const TILE_SPAWN: u8 = 192;
|
||||
|
||||
pub trait MapGenerator {
|
||||
fn generate<R: Rng + ?Sized>(rng: &mut R) -> Result<TwMap>;
|
||||
|
||||
fn save_file<R: Rng + ?Sized>(rng: &mut R, path: &Path) -> Result<()> {
|
||||
let mut map = Self::generate(rng)?;
|
||||
map.save_file(path)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_initial_map() -> Result<TwMap> {
|
||||
let mut map = TwMap::empty(Version::DDNet06);
|
||||
map.info.author = "github.com/edg-l/ddnet-map-gen".to_string();
|
||||
map.info.credits = "github.com/edg-l/ddnet-map-gen".to_string();
|
||||
map.images.push(Image::External(ExternalImage {
|
||||
name: "generic_unhookable".to_string(),
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
}));
|
||||
map.images.push(Image::Embedded(EmbeddedImage::from_file(
|
||||
"mapres/basic_freeze.png",
|
||||
)?));
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
// Creates the sky quad from the editor.
|
||||
pub fn quads_sky() -> Group {
|
||||
let mut quads_group = Group::default();
|
||||
let mut quads_layer = QuadsLayer::default();
|
||||
quads_group.parallax_x = 0;
|
||||
quads_group.parallax_y = 0;
|
||||
|
||||
let mut quad = Quad::new(50 * 2i32.pow(15), 30 * 2i32.pow(15));
|
||||
quad.colors = [
|
||||
Color {
|
||||
r: 94,
|
||||
g: 132,
|
||||
b: 174,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 94,
|
||||
g: 132,
|
||||
b: 174,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 204,
|
||||
g: 232,
|
||||
b: 255,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 204,
|
||||
g: 232,
|
||||
b: 255,
|
||||
a: 255,
|
||||
},
|
||||
];
|
||||
|
||||
quads_layer.quads.push(quad);
|
||||
|
||||
quads_group.layers.push(Layer::Quads(quads_layer));
|
||||
quads_group
|
||||
}
|
219
src/main.rs
219
src/main.rs
|
@ -1,223 +1,10 @@
|
|||
use color_eyre::Result;
|
||||
use irrgarten::Maze;
|
||||
use ndarray::Array2;
|
||||
use rand::Rng;
|
||||
use twmap::*;
|
||||
|
||||
const TILE_EMPTY: u8 = 0;
|
||||
const TILE_HOOKABLE: u8 = 1;
|
||||
const TILE_UNHOOKABLE: u8 = 3;
|
||||
const TILE_FREEZE: u8 = 9;
|
||||
const TILE_UNFREEZE: u8 = 1;
|
||||
const TILE_START: u8 = 33;
|
||||
const TILE_FINISH: u8 = 34;
|
||||
const TILE_SPAWN: u8 = 192;
|
||||
mod cli;
|
||||
pub mod generators;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
color_eyre::install()?;
|
||||
|
||||
gen_flymap()?;
|
||||
|
||||
cli::run_cli()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_initial_map() -> Result<TwMap> {
|
||||
let mut map = TwMap::empty(Version::DDNet06);
|
||||
map.info.author = "Ryozuki's Map Gen".to_string();
|
||||
map.info.credits = "Ryozuki's Map Gen".to_string();
|
||||
map.images.push(Image::External(ExternalImage {
|
||||
name: "generic_unhookable".to_string(),
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
}));
|
||||
map.images.push(Image::Embedded(EmbeddedImage::from_file(
|
||||
"mapres/basic_freeze.png",
|
||||
)?));
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
fn gen_flymap() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let mut map = create_initial_map()?;
|
||||
|
||||
const HEIGHT: usize = 1000;
|
||||
const WIDTH: usize = 100;
|
||||
|
||||
let mut tiles = Array2::from_shape_simple_fn((HEIGHT, WIDTH), || {
|
||||
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
||||
});
|
||||
let mut front_tiles = Array2::from_shape_simple_fn((HEIGHT, WIDTH), || {
|
||||
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
||||
});
|
||||
|
||||
let mut unhookable_tiles =
|
||||
Array2::from_shape_simple_fn((HEIGHT, WIDTH), || Tile::new(0, TileFlags::empty()));
|
||||
let mut freeze_tiles =
|
||||
Array2::from_shape_simple_fn((HEIGHT, WIDTH), || Tile::new(0, TileFlags::empty()));
|
||||
|
||||
tiles
|
||||
.row_mut(HEIGHT - 2)
|
||||
.iter_mut()
|
||||
.for_each(|tile| tile.id = TILE_UNHOOKABLE);
|
||||
unhookable_tiles
|
||||
.row_mut(HEIGHT - 2)
|
||||
.iter_mut()
|
||||
.for_each(|tile| tile.id = 1);
|
||||
|
||||
tiles[(HEIGHT - 3, WIDTH / 2)].id = TILE_SPAWN;
|
||||
|
||||
for x in 0..WIDTH {
|
||||
front_tiles[(HEIGHT - 6, x)].id = TILE_START;
|
||||
front_tiles[(10, x)].id = TILE_FINISH;
|
||||
}
|
||||
|
||||
let mut center: i64 = WIDTH as i64 / 2;
|
||||
let mut fly_width: i64 = 10;
|
||||
|
||||
for y in (0..=(HEIGHT - 3)).rev() {
|
||||
let direction: i64 = rng.gen_range(-1..=1);
|
||||
let width_change: i64 = rng.gen_range(-1..=1);
|
||||
center += direction;
|
||||
fly_width += width_change;
|
||||
center = center.clamp(fly_width, WIDTH as i64 - fly_width);
|
||||
fly_width = fly_width.clamp(2, 12);
|
||||
|
||||
for x in ((center + fly_width) as usize)..WIDTH {
|
||||
tiles[(y, x)].id = TILE_FREEZE;
|
||||
freeze_tiles[(y, x)].id = 4;
|
||||
}
|
||||
|
||||
for x in 0..=((center - fly_width) as usize) {
|
||||
tiles[(y, x)].id = TILE_FREEZE;
|
||||
freeze_tiles[(y, x)].id = 4;
|
||||
}
|
||||
}
|
||||
|
||||
let game_layer = GameLayer {
|
||||
tiles: CompressedData::Loaded(tiles),
|
||||
};
|
||||
|
||||
let front_layer = FrontLayer {
|
||||
tiles: CompressedData::Loaded(front_tiles),
|
||||
};
|
||||
|
||||
let mut unhook_tiles_layer = TilesLayer::new((HEIGHT, WIDTH));
|
||||
unhook_tiles_layer.image = Some(0);
|
||||
unhook_tiles_layer.tiles = CompressedData::Loaded(unhookable_tiles);
|
||||
|
||||
let mut freeze_tiles_layer = TilesLayer::new((HEIGHT, WIDTH));
|
||||
freeze_tiles_layer.image = Some(1);
|
||||
freeze_tiles_layer.tiles = CompressedData::Loaded(freeze_tiles);
|
||||
freeze_tiles_layer.color = Color {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 200,
|
||||
};
|
||||
|
||||
let mut physics = Group::physics();
|
||||
physics.layers.push(Layer::Game(game_layer));
|
||||
physics.layers.push(Layer::Front(front_layer));
|
||||
physics.layers.push(Layer::Tiles(unhook_tiles_layer));
|
||||
physics.layers.push(Layer::Tiles(freeze_tiles_layer));
|
||||
|
||||
map.groups.push(quads_sky());
|
||||
map.groups.push(physics);
|
||||
|
||||
map.save_file("server/maps/generated.map")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn gen_maze() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let mut map = create_initial_map()?;
|
||||
|
||||
let maze = Maze::new(1001, 1001).unwrap().generate(&mut rng);
|
||||
|
||||
let mut tiles = Array2::from_shape_fn((1001, 1001), |(x, y)| {
|
||||
GameTile::new(maze[x][y], TileFlags::empty())
|
||||
});
|
||||
|
||||
// Put spawn and start tile on top left most tile.
|
||||
let mut added_spawn = false;
|
||||
'outerStart: for y in 0..101 {
|
||||
for x in 0..101 {
|
||||
let tile = &mut tiles[(x, y)];
|
||||
if tile.id == 0 && !added_spawn {
|
||||
*tile = GameTile::new(TILE_SPAWN, TileFlags::empty());
|
||||
added_spawn = true;
|
||||
} else if tile.id == 0 && added_spawn {
|
||||
*tile = GameTile::new(TILE_START, TileFlags::empty());
|
||||
break 'outerStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put finish tile on bottom right most tile.
|
||||
'outerFinish: for y in (0..1001).rev() {
|
||||
for x in (0..1001).rev() {
|
||||
let tile = &mut tiles[(x, y)];
|
||||
if tile.id == 0 {
|
||||
*tile = GameTile::new(TILE_FINISH, TileFlags::empty());
|
||||
break 'outerFinish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let game_layer = GameLayer {
|
||||
tiles: CompressedData::Loaded(tiles),
|
||||
};
|
||||
|
||||
let mut physics = Group::physics();
|
||||
physics.layers.push(Layer::Game(game_layer));
|
||||
map.groups.push(physics);
|
||||
|
||||
map.save_file("server/maps/generated.map")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Creates the sky quad from the editor.
|
||||
fn quads_sky() -> Group {
|
||||
let mut quads_group = Group::default();
|
||||
let mut quads_layer = QuadsLayer::default();
|
||||
quads_group.parallax_x = 0;
|
||||
quads_group.parallax_y = 0;
|
||||
|
||||
let mut quad = Quad::new(1600, 800);
|
||||
dbg!(&quad);
|
||||
quad.colors = [
|
||||
Color {
|
||||
r: 94,
|
||||
g: 206,
|
||||
b: 174,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 94,
|
||||
g: 206,
|
||||
b: 174,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 204,
|
||||
g: 232,
|
||||
b: 255,
|
||||
a: 255,
|
||||
},
|
||||
Color {
|
||||
r: 204,
|
||||
g: 232,
|
||||
b: 255,
|
||||
a: 255,
|
||||
},
|
||||
];
|
||||
|
||||
quads_layer.quads.push(quad);
|
||||
|
||||
quads_group.layers.push(Layer::Quads(quads_layer));
|
||||
quads_group
|
||||
}
|
Loading…
Reference in a new issue