mirror of
https://github.com/edg-l/ddnet-map-gen.git
synced 2024-11-09 09:38:22 +00:00
add fly options
This commit is contained in:
parent
ba7382e410
commit
cd1714dac3
BIN
generated.png
Normal file
BIN
generated.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
36
src/cli.rs
36
src/cli.rs
|
@ -32,18 +32,33 @@ struct Cli {
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Generate a map for fly techniques.
|
/// Generate a map for fly techniques.
|
||||||
Fly,
|
Fly {
|
||||||
|
#[arg(long, default_value_t = 3)]
|
||||||
|
max_fly_width: u16,
|
||||||
|
/// The output map file.
|
||||||
|
#[arg(long, default_value_t = 12)]
|
||||||
|
min_fly_width: u16,
|
||||||
|
},
|
||||||
/// Generate a maze-like map.
|
/// Generate a maze-like map.
|
||||||
Maze,
|
Maze,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Commands {
|
impl Commands {
|
||||||
pub fn print(&self) {
|
pub fn print(&self) {
|
||||||
let name = match self {
|
print!("Selected generator: ");
|
||||||
Self::Fly => "Fly",
|
let data = match self {
|
||||||
Self::Maze => "Maze",
|
Self::Fly {
|
||||||
|
max_fly_width,
|
||||||
|
min_fly_width,
|
||||||
|
} => format!(
|
||||||
|
"{}, parameters: max_fly_width={}, min_fly_width={}",
|
||||||
|
"Fly".purple().bold(),
|
||||||
|
max_fly_width.purple(),
|
||||||
|
min_fly_width.purple()
|
||||||
|
),
|
||||||
|
Self::Maze => format!("{}", "Maze".purple().bold()),
|
||||||
};
|
};
|
||||||
println!("Selected map generator: {}", name.purple().bold());
|
println!("{data}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +85,15 @@ pub fn run_cli() -> Result<()> {
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Maze => {
|
Commands::Maze => {
|
||||||
MazeGenerator::save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
|
MazeGenerator.save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
|
||||||
}
|
}
|
||||||
Commands::Fly => {
|
Commands::Fly {
|
||||||
FlyGenerator::save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
|
max_fly_width,
|
||||||
|
min_fly_width,
|
||||||
|
} => FlyGenerator {
|
||||||
|
max_fly_width,
|
||||||
|
min_fly_width,
|
||||||
}
|
}
|
||||||
|
.save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,16 @@ use super::*;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use ndarray::Array2;
|
use ndarray::Array2;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use rand_distr::{Uniform, Distribution};
|
||||||
|
|
||||||
pub struct FlyGenerator;
|
pub struct FlyGenerator {
|
||||||
|
pub max_fly_width: u16,
|
||||||
|
pub min_fly_width: u16,
|
||||||
|
}
|
||||||
|
|
||||||
impl MapGenerator for FlyGenerator {
|
impl MapGenerator for FlyGenerator {
|
||||||
fn generate<R: Rng + ?Sized>(
|
fn generate<R: Rng + ?Sized>(
|
||||||
|
&self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
mapres: &Path,
|
mapres: &Path,
|
||||||
width: usize,
|
width: usize,
|
||||||
|
@ -14,7 +19,7 @@ impl MapGenerator for FlyGenerator {
|
||||||
) -> Result<TwMap> {
|
) -> Result<TwMap> {
|
||||||
let mut map = create_initial_map(mapres)?;
|
let mut map = create_initial_map(mapres)?;
|
||||||
|
|
||||||
let mut tiles = Array2::from_shape_simple_fn((height, width), || {
|
let mut game_tiles = Array2::from_shape_simple_fn((height, width), || {
|
||||||
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
GameTile::new(TILE_EMPTY, TileFlags::empty())
|
||||||
});
|
});
|
||||||
let mut front_tiles = Array2::from_shape_simple_fn((height, width), || {
|
let mut front_tiles = Array2::from_shape_simple_fn((height, width), || {
|
||||||
|
@ -26,7 +31,8 @@ impl MapGenerator for FlyGenerator {
|
||||||
let mut freeze_tiles =
|
let mut freeze_tiles =
|
||||||
Array2::from_shape_simple_fn((height, width), || Tile::new(0, TileFlags::empty()));
|
Array2::from_shape_simple_fn((height, width), || Tile::new(0, TileFlags::empty()));
|
||||||
|
|
||||||
tiles
|
// Create the ceiling and spawn.
|
||||||
|
game_tiles
|
||||||
.row_mut(height - 2)
|
.row_mut(height - 2)
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.for_each(|tile| tile.id = TILE_UNHOOKABLE);
|
.for_each(|tile| tile.id = TILE_UNHOOKABLE);
|
||||||
|
@ -35,8 +41,9 @@ impl MapGenerator for FlyGenerator {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.for_each(|tile| tile.id = 2);
|
.for_each(|tile| tile.id = 2);
|
||||||
|
|
||||||
tiles[(height - 3, width / 2)].id = TILE_SPAWN;
|
game_tiles[(height - 3, width / 2)].id = TILE_SPAWN;
|
||||||
|
|
||||||
|
// Place the start and finish tiles.
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
front_tiles[(height - 6, x)].id = TILE_START;
|
front_tiles[(height - 6, x)].id = TILE_START;
|
||||||
front_tiles[(10, x)].id = TILE_FINISH;
|
front_tiles[(10, x)].id = TILE_FINISH;
|
||||||
|
@ -50,25 +57,29 @@ impl MapGenerator for FlyGenerator {
|
||||||
let mut direction_steps: i64 = rng.gen_range((max_steps / 2)..=max_steps);
|
let mut direction_steps: i64 = rng.gen_range((max_steps / 2)..=max_steps);
|
||||||
let mut direction: i64 = rng.gen_range(-1..=1);
|
let mut direction: i64 = rng.gen_range(-1..=1);
|
||||||
|
|
||||||
|
let direction_steps_sampler = Uniform::from(1..=10);
|
||||||
|
let direction_sampler = Uniform::from(-1..=1);
|
||||||
|
let width_sampler = Uniform::from(-1..=1);
|
||||||
|
|
||||||
for y in (0..=(height - 3)).rev() {
|
for y in (0..=(height - 3)).rev() {
|
||||||
if direction_steps == 0 {
|
if direction_steps == 0 {
|
||||||
direction_steps = rng.gen_range(1..=10);
|
direction_steps = direction_steps_sampler.sample(rng);
|
||||||
direction = rng.gen_range(-1..=1);
|
direction = direction_sampler.sample(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
let width_change: i64 = rng.gen_range(-1..=1);
|
let width_change: i64 = width_sampler.sample(rng);
|
||||||
center += direction;
|
center += direction;
|
||||||
fly_width += width_change;
|
fly_width += width_change;
|
||||||
fly_width = fly_width.clamp(3, 12);
|
fly_width = fly_width.clamp(self.min_fly_width as i64, self.max_fly_width as i64);
|
||||||
center = center.clamp(fly_width, width as i64 - fly_width - 1);
|
center = center.clamp(fly_width, width as i64 - fly_width - 1);
|
||||||
|
|
||||||
for x in ((center + fly_width) as usize)..width {
|
for x in ((center + fly_width) as usize)..width {
|
||||||
tiles[(y, x)].id = TILE_FREEZE;
|
game_tiles[(y, x)].id = TILE_FREEZE;
|
||||||
freeze_tiles[(y, x)].id = 4;
|
freeze_tiles[(y, x)].id = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in 0..=((center - fly_width) as usize) {
|
for x in 0..=((center - fly_width) as usize) {
|
||||||
tiles[(y, x)].id = TILE_FREEZE;
|
game_tiles[(y, x)].id = TILE_FREEZE;
|
||||||
freeze_tiles[(y, x)].id = 4;
|
freeze_tiles[(y, x)].id = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +87,7 @@ impl MapGenerator for FlyGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
let game_layer = GameLayer {
|
let game_layer = GameLayer {
|
||||||
tiles: CompressedData::Loaded(tiles),
|
tiles: CompressedData::Loaded(game_tiles),
|
||||||
};
|
};
|
||||||
|
|
||||||
let front_layer = FrontLayer {
|
let front_layer = FrontLayer {
|
||||||
|
|
|
@ -7,6 +7,7 @@ pub struct MazeGenerator;
|
||||||
|
|
||||||
impl MapGenerator for MazeGenerator {
|
impl MapGenerator for MazeGenerator {
|
||||||
fn generate<R: Rng + ?Sized>(
|
fn generate<R: Rng + ?Sized>(
|
||||||
|
&self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
mapres: &Path,
|
mapres: &Path,
|
||||||
width: usize,
|
width: usize,
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub const TILE_SPAWN: u8 = 192;
|
||||||
|
|
||||||
pub trait MapGenerator {
|
pub trait MapGenerator {
|
||||||
fn generate<R: Rng + ?Sized>(
|
fn generate<R: Rng + ?Sized>(
|
||||||
|
&self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
mapres: &Path,
|
mapres: &Path,
|
||||||
width: usize,
|
width: usize,
|
||||||
|
@ -27,13 +28,14 @@ pub trait MapGenerator {
|
||||||
) -> Result<TwMap>;
|
) -> Result<TwMap>;
|
||||||
|
|
||||||
fn save_file<R: Rng + ?Sized>(
|
fn save_file<R: Rng + ?Sized>(
|
||||||
|
&self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
mapres: &Path,
|
mapres: &Path,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut map = Self::generate(rng, mapres, width, height)?;
|
let mut map = self.generate(rng, mapres, width, height)?;
|
||||||
map.save_file(path)?;
|
map.save_file(path)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue