update deps and cli

This commit is contained in:
Edgar 2022-10-28 12:29:51 +02:00
parent 22b0633bb4
commit f7d6c08dd3
No known key found for this signature in database
5 changed files with 353 additions and 618 deletions

4
.gitignore vendored
View file

@ -1,4 +1,6 @@
/target /target
server/ server/
TODO.md TODO.md
test.map

789
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
name = "ddnet-map-gen" name = "ddnet-map-gen"
authors = ["Edgar <git@edgarluque.com>"] authors = ["Edgar <git@edgarluque.com>"]
description = "A DDraceNetwork map generator." description = "A DDraceNetwork map generator."
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
keywords = ["ddnet", "teeworlds", "mapgen"] keywords = ["ddnet", "teeworlds", "mapgen"]
@ -10,12 +10,16 @@ keywords = ["ddnet", "teeworlds", "mapgen"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
clap = { version = "3.1.6", features = ["cargo", "derive"] } clap = { version = "4.0.18", features = ["cargo", "derive"] }
color-eyre = "0.6.1" color-eyre = "0.6.2"
eyre = "0.6.7" eyre = "0.6.8"
fixed = "1.19.0"
irrgarten = "0.1.1" irrgarten = "0.1.1"
itertools = "0.10.3" itertools = "0.10.5"
ndarray = "0.15.4" ndarray = "0.15.6"
owo-colors = "3.5.0"
rand = "0.8.5" rand = "0.8.5"
rand_chacha = "0.3.1"
rand_distr = "0.4.3" rand_distr = "0.4.3"
twmap = "0.6.0" rand_seeder = "0.2.3"
twmap = "0.9.0"

View file

@ -1,62 +1,72 @@
use crate::generators::{fly::FlyGenerator, maze::MazeGenerator, MapGenerator}; use crate::generators::{fly::FlyGenerator, maze::MazeGenerator, MapGenerator};
use clap::{arg, command, Command}; use clap::{arg, Parser, Subcommand};
use eyre::Result; use eyre::Result;
use std::path::Path; use owo_colors::OwoColorize;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use rand_chacha::ChaCha8Rng;
use rand_seeder::Seeder;
use std::path::PathBuf;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// The width of the map.
#[arg(long, default_value_t = 1000)]
width: usize,
/// The height of the map.
#[arg(long, default_value_t = 1000)]
height: usize,
/// The seed used when generating a map. By default a random one.
#[arg(short, long)]
seed: Option<String>,
/// The output map file.
#[arg(short, long)]
output: PathBuf,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Generate a map for fly techniques.
Fly,
/// Generate a maze-like map.
Maze,
}
impl Commands {
pub fn print(&self) {
let name = match self {
Self::Fly => "Maze",
Self::Maze => "Fly",
};
println!("Selected map generator: {}", name.purple().bold());
}
}
pub fn run_cli() -> Result<()> { pub fn run_cli() -> Result<()> {
let matches = command!() let cli = Cli::parse();
.about("A DDraceNetwork map generator")
.arg_required_else_help(true)
.subcommand_required(true)
.arg(arg!(<FILE> "The output map file").required(true))
.subcommand(
Command::new("maze")
.about("Generate a maze-like map")
.arg(
arg!(--width <WIDTH> "The width of the map")
.default_value("1000")
.required(false),
)
.arg(
arg!(--height <HEIGHT> "The height of the map")
.default_value("1000")
.required(false),
),
)
.subcommand(
Command::new("fly")
.about("Generate a map for fly techniques")
.arg(
arg!(--width <WIDTH> "The width of the map")
.default_value("1000")
.required(false),
)
.arg(
arg!(--height <HEIGHT> "The height of the map")
.default_value("1000")
.required(false),
),
)
.get_matches();
let output = matches.value_of("FILE").expect("output is required"); let seed: String = {
let output = Path::new(output); if let Some(x) = &cli.seed {
x.clone()
let mut rng = rand::thread_rng(); } else {
thread_rng()
match matches.subcommand() { .sample_iter(&Alphanumeric)
Some(("maze", sub_m)) => { .take(8)
let width: usize = sub_m.value_of_t("width").unwrap_or_else(|e| e.exit()); .map(char::from)
let height: usize = sub_m.value_of_t("height").unwrap_or_else(|e| e.exit()); .collect()
MazeGenerator::save_file(&mut rng, width, height, output)?
} }
Some(("fly", sub_m)) => { };
let width: usize = sub_m.value_of_t("width").unwrap_or_else(|e| e.exit());
let height: usize = sub_m.value_of_t("height").unwrap_or_else(|e| e.exit()); println!("Using seed: {}", seed.green().bold());
FlyGenerator::save_file(&mut rng, width, height, output)?
} let mut rng: ChaCha8Rng = Seeder::from(seed).make_rng();
_ => panic!("invalid command"),
cli.command.print();
match cli.command {
Commands::Maze => MazeGenerator::save_file(&mut rng, cli.width, cli.height, &cli.output),
Commands::Fly => FlyGenerator::save_file(&mut rng, cli.width, cli.height, &cli.output),
} }
Ok(())
} }

View file

@ -1,7 +1,8 @@
use std::path::Path; use std::path::Path;
use eyre::Result; use eyre::Result;
use ndarray::{Array2}; use fixed::types::I17F15;
use ndarray::Array2;
use rand::Rng; use rand::Rng;
use twmap::*; use twmap::*;
@ -20,7 +21,12 @@ pub const TILE_SPAWN: u8 = 192;
pub trait MapGenerator { pub trait MapGenerator {
fn generate<R: Rng + ?Sized>(rng: &mut R, width: usize, height: usize) -> Result<TwMap>; fn generate<R: Rng + ?Sized>(rng: &mut R, width: usize, height: usize) -> Result<TwMap>;
fn save_file<R: Rng + ?Sized>(rng: &mut R, width: usize, height: usize, path: &Path) -> Result<()> { fn save_file<R: Rng + ?Sized>(
rng: &mut R,
width: usize,
height: usize,
path: &Path,
) -> Result<()> {
let mut map = Self::generate(rng, width, height)?; let mut map = Self::generate(rng, width, height)?;
map.save_file(path)?; map.save_file(path)?;
Ok(()) Ok(())
@ -33,8 +39,7 @@ pub fn create_initial_map() -> Result<TwMap> {
map.info.credits = "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 { map.images.push(Image::External(ExternalImage {
name: "generic_unhookable".to_string(), name: "generic_unhookable".to_string(),
width: 1024, size: Point::new_same(1024),
height: 1024,
})); }));
map.images.push(Image::Embedded(EmbeddedImage::from_file( map.images.push(Image::Embedded(EmbeddedImage::from_file(
"mapres/basic_freeze.png", "mapres/basic_freeze.png",
@ -42,14 +47,15 @@ pub fn create_initial_map() -> Result<TwMap> {
Ok(map) Ok(map)
} }
// Creates the sky quad from the editor. // Creates the sky quad from the editor.
pub fn quads_sky() -> Group { pub fn quads_sky() -> Group {
let mut quads_group = Group::default(); let mut quads_group = Group::default();
let mut quads_layer = QuadsLayer::default(); let mut quads_layer = QuadsLayer::default();
quads_group.parallax_x = 0; quads_group.parallax.x = 0;
quads_group.parallax_y = 0; quads_group.parallax.y = 0;
let mut quad = Quad::new(50 * 2i32.pow(15), 30 * 2i32.pow(15)); let mut quad = Quad::new(Default::default(), Point::new(I17F15::from_num(50), I17F15::from_num(30))).unwrap();
quad.colors = [ quad.colors = [
Color { Color {
r: 94, r: 94,
@ -90,11 +96,17 @@ pub fn replace_gametile(tiles: &mut Array2<GameTile>, x: usize, y: usize, oldid:
} }
} }
pub fn replace_around_gametile(tiles: &mut Array2<GameTile>, x: usize, y: usize, oldid: u8, newid: u8) { pub fn replace_around_gametile(
tiles: &mut Array2<GameTile>,
x: usize,
y: usize,
oldid: u8,
newid: u8,
) {
let width = tiles.ncols(); let width = tiles.ncols();
let height = tiles.nrows(); let height = tiles.nrows();
let directions = [-1, 0, 1]; let directions = [-1, 0, 1];
for diry in directions { for diry in directions {
for dirx in directions { for dirx in directions {
@ -107,7 +119,13 @@ pub fn replace_around_gametile(tiles: &mut Array2<GameTile>, x: usize, y: usize,
if (x as i64) + dirx < 0 || (x as i64) + dirx >= width as i64 { if (x as i64) + dirx < 0 || (x as i64) + dirx >= width as i64 {
continue; continue;
} }
replace_gametile(tiles, ((x as i64) + dirx) as usize, ((y as i64) + diry) as usize, oldid, newid); replace_gametile(
tiles,
((x as i64) + dirx) as usize,
((y as i64) + diry) as usize,
oldid,
newid,
);
} }
} }
} }