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

2
.gitignore vendored
View file

@ -2,3 +2,5 @@
server/
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"
authors = ["Edgar <git@edgarluque.com>"]
description = "A DDraceNetwork map generator."
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "AGPL-3.0-only"
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
[dependencies]
clap = { version = "3.1.6", features = ["cargo", "derive"] }
color-eyre = "0.6.1"
eyre = "0.6.7"
clap = { version = "4.0.18", features = ["cargo", "derive"] }
color-eyre = "0.6.2"
eyre = "0.6.8"
fixed = "1.19.0"
irrgarten = "0.1.1"
itertools = "0.10.3"
ndarray = "0.15.4"
itertools = "0.10.5"
ndarray = "0.15.6"
owo-colors = "3.5.0"
rand = "0.8.5"
rand_chacha = "0.3.1"
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 clap::{arg, command, Command};
use clap::{arg, Parser, Subcommand};
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<()> {
let matches = command!()
.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 cli = Cli::parse();
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)) => {
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());
MazeGenerator::save_file(&mut rng, width, height, output)?
let seed: String = {
if let Some(x) = &cli.seed {
x.clone()
} else {
thread_rng()
.sample_iter(&Alphanumeric)
.take(8)
.map(char::from)
.collect()
}
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());
FlyGenerator::save_file(&mut rng, width, height, output)?
}
_ => panic!("invalid command"),
};
println!("Using seed: {}", seed.green().bold());
let mut rng: ChaCha8Rng = Seeder::from(seed).make_rng();
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 eyre::Result;
use ndarray::{Array2};
use fixed::types::I17F15;
use ndarray::Array2;
use rand::Rng;
use twmap::*;
@ -20,7 +21,12 @@ pub const TILE_SPAWN: u8 = 192;
pub trait MapGenerator {
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)?;
map.save_file(path)?;
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.images.push(Image::External(ExternalImage {
name: "generic_unhookable".to_string(),
width: 1024,
height: 1024,
size: Point::new_same(1024),
}));
map.images.push(Image::Embedded(EmbeddedImage::from_file(
"mapres/basic_freeze.png",
@ -42,14 +47,15 @@ pub fn create_initial_map() -> Result<TwMap> {
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;
quads_group.parallax.x = 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 = [
Color {
r: 94,
@ -90,7 +96,13 @@ 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 height = tiles.nrows();
@ -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 {
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,
);
}
}
}