mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 17:21:49 -10:00
Merge branch 'pr/2570' into union/pt2-a
This commit is contained in:
commit
7e322f591a
9 files changed
+293
-80
No files matched your search
@@ -9249,7 +9249,8 @@ impl Game<'_> {
|
||||
book.to_be_displayed.retain(|r| index.contains(r));
|
||||
self.dim = dim;
|
||||
self.world_root = save_root.clone();
|
||||
self.world_flat = horizon_client::save::WorldGen::read(&save_root).is_some_and(|w| w.flat);
|
||||
self.world_flat = horizon_client::save::WorldGen::read(&save_root)
|
||||
.is_some_and(|w| w.preset == horizon_client::save::WorldPreset::Flat);
|
||||
self.block_ticks = Ticks::new(self.level.seed as i32);
|
||||
self.tick_chunks.clear();
|
||||
self.clear_entities();
|
||||
|
||||
@@ -564,7 +564,7 @@ impl Game<'_> {
|
||||
"hardcore": options.hardcore,
|
||||
"difficulty": horizon_client::title::DIFFICULTIES[options.difficulty()],
|
||||
"allow_commands": options.commands(*creative),
|
||||
"superflat": options.flat,
|
||||
"world_type": options.world_type.id(),
|
||||
"generate_structures": options.structures,
|
||||
"bonus_chest": options.bonus_chest(),
|
||||
}),
|
||||
@@ -577,7 +577,7 @@ impl Game<'_> {
|
||||
} => json!({
|
||||
"mode": "customize-flat",
|
||||
"fields": { "name": name, "seed": seed },
|
||||
"superflat": options.flat,
|
||||
"superflat": options.world_type == horizon_client::save::WorldPreset::Flat,
|
||||
"biome": flat.settings().biome,
|
||||
"layers": flat.settings().layers.iter().map(|layer| json!({
|
||||
"block": layer.block,
|
||||
|
||||
@@ -298,15 +298,14 @@ impl Lists {
|
||||
}
|
||||
}
|
||||
|
||||
/// The world presets of 26.3's `worldgen/world_preset`.
|
||||
const WORLD_PRESETS: [&str; 7] = [
|
||||
"minecraft:normal",
|
||||
"minecraft:flat",
|
||||
"minecraft:large_biomes",
|
||||
"minecraft:amplified",
|
||||
"minecraft:single_biome_surface",
|
||||
"minecraft:debug_all_block_states",
|
||||
"minecraft:flat_all_dimensions",
|
||||
/// DedicatedServerProperties.LEGACY_PRESET_NAMES: the old `level-type`
|
||||
/// names, before the presets had their own ids.
|
||||
const LEGACY_PRESET_NAMES: [(&str, horizon_client::save::WorldPreset); 2] = [
|
||||
("default", horizon_client::save::WorldPreset::Normal),
|
||||
(
|
||||
"largebiomes",
|
||||
horizon_client::save::WorldPreset::LargeBiomes,
|
||||
),
|
||||
];
|
||||
|
||||
/// Identifier.tryParse: `namespace:path`, or a path in `minecraft`.
|
||||
@@ -323,11 +322,18 @@ impl Game<'_> {
|
||||
/// DedicatedServerProperties.createDimensions for a world that doesn't
|
||||
/// exist yet: `level-type`'s preset, a flat world's `generator-settings`
|
||||
/// and `generate-structures`, written before the world opens so that
|
||||
/// streaming reads them. Horizon generates the normal and flat presets.
|
||||
/// streaming reads them.
|
||||
fn write_world_gen(&self, dir: &std::path::Path, props: &ServerProperties) -> Result<()> {
|
||||
let level_type = &props.level_type;
|
||||
let preset = parse_identifier(level_type)
|
||||
.filter(|id| WORLD_PRESETS.contains(&id.as_str()))
|
||||
.as_deref()
|
||||
.and_then(horizon_client::save::WorldPreset::of_id)
|
||||
.or_else(|| {
|
||||
LEGACY_PRESET_NAMES
|
||||
.iter()
|
||||
.find(|(name, _)| *name == level_type)
|
||||
.map(|(_, preset)| *preset)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
log_from(
|
||||
"Worker-Main-1",
|
||||
@@ -336,18 +342,9 @@ impl Game<'_> {
|
||||
"Failed to parse level-type {level_type}, defaulting to minecraft:normal"
|
||||
),
|
||||
);
|
||||
"minecraft:normal".to_owned()
|
||||
horizon_client::save::WorldPreset::Normal
|
||||
});
|
||||
let flat = preset == "minecraft:flat";
|
||||
if !flat && preset != "minecraft:normal" {
|
||||
log_from(
|
||||
"Worker-Main-1",
|
||||
"WARN",
|
||||
&format!(
|
||||
"Horizon doesn't generate the {preset} world preset yet: using minecraft:normal"
|
||||
),
|
||||
);
|
||||
}
|
||||
let flat = preset == horizon_client::save::WorldPreset::Flat;
|
||||
let settings = if flat {
|
||||
let biomes = self.res.biomes();
|
||||
let (settings, errors) = horizon_client::flatgen::settings_from_json(
|
||||
@@ -363,7 +360,7 @@ impl Game<'_> {
|
||||
None
|
||||
};
|
||||
let options = horizon_client::save::WorldGen {
|
||||
flat,
|
||||
preset,
|
||||
structures: props.generate_structures,
|
||||
bonus_chest: false,
|
||||
};
|
||||
|
||||
@@ -2503,14 +2503,83 @@ const INT_RULES: [&str; 11] = [
|
||||
"respawn_radius",
|
||||
];
|
||||
|
||||
/// The world presets of 26.3's `worldgen/world_preset` that the create
|
||||
/// screen offers, in the order of `WorldPresetTags.NORMAL`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum WorldPreset {
|
||||
Normal,
|
||||
Flat,
|
||||
LargeBiomes,
|
||||
Amplified,
|
||||
SingleBiomeSurface,
|
||||
}
|
||||
impl WorldPreset {
|
||||
/// The presets, in the order the world-type button cycles through them.
|
||||
pub const ALL: [Self; 5] = [
|
||||
Self::Normal,
|
||||
Self::Flat,
|
||||
Self::LargeBiomes,
|
||||
Self::Amplified,
|
||||
Self::SingleBiomeSurface,
|
||||
];
|
||||
/// The preset's registry id (`minecraft:normal`).
|
||||
pub const fn id(self) -> &'static str {
|
||||
match self {
|
||||
Self::Normal => "minecraft:normal",
|
||||
Self::Flat => "minecraft:flat",
|
||||
Self::LargeBiomes => "minecraft:large_biomes",
|
||||
Self::Amplified => "minecraft:amplified",
|
||||
Self::SingleBiomeSurface => "minecraft:single_biome_surface",
|
||||
}
|
||||
}
|
||||
/// The preset an id names, if it is one of them.
|
||||
pub fn of_id(id: &str) -> Option<Self> {
|
||||
Self::ALL.into_iter().find(|preset| preset.id() == id)
|
||||
}
|
||||
/// The language key the world-type button shows
|
||||
/// (`Identifier.toLanguageKey("generator")`).
|
||||
pub const fn label(self) -> &'static str {
|
||||
match self {
|
||||
Self::Normal => "generator.minecraft.normal",
|
||||
Self::Flat => "generator.minecraft.flat",
|
||||
Self::LargeBiomes => "generator.minecraft.large_biomes",
|
||||
Self::Amplified => "generator.minecraft.amplified",
|
||||
Self::SingleBiomeSurface => "generator.minecraft.single_biome_surface",
|
||||
}
|
||||
}
|
||||
/// The preset the world-type button cycles to next.
|
||||
pub fn next(self) -> Self {
|
||||
let index = Self::ALL
|
||||
.iter()
|
||||
.position(|preset| *preset == self)
|
||||
.unwrap_or(0);
|
||||
Self::ALL[(index + 1) % Self::ALL.len()]
|
||||
}
|
||||
/// The preset a saved overworld generator is: the noise settings name
|
||||
/// the preset, and the single-biome preset shares the overworld's noise
|
||||
/// settings, so its fixed biome source tells the two apart.
|
||||
pub fn of_generator(generator: &Tag) -> Self {
|
||||
if text(generator.get("type")).as_deref() == Some("minecraft:flat") {
|
||||
return Self::Flat;
|
||||
}
|
||||
let source = generator.get("biome_source");
|
||||
let fixed = text(source.and_then(|s| s.get("type"))).as_deref() == Some("minecraft:fixed");
|
||||
match text(generator.get("settings")).as_deref() {
|
||||
Some("minecraft:large_biomes") => Self::LargeBiomes,
|
||||
Some("minecraft:amplified") => Self::Amplified,
|
||||
Some("minecraft:overworld") if fixed => Self::SingleBiomeSurface,
|
||||
_ => Self::Normal,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// World and player state stored in `level.dat`, the saved-data files and
|
||||
/// the player file.
|
||||
/// The world options CreateWorldScreen sets (`WorldOptions` and the world
|
||||
/// preset) that `world_gen_settings` keeps.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct WorldGen {
|
||||
/// The `minecraft:flat` preset (Superflat) instead of `normal`.
|
||||
pub flat: bool,
|
||||
/// The world preset the world is created with.
|
||||
pub preset: WorldPreset,
|
||||
pub structures: bool,
|
||||
pub bonus_chest: bool,
|
||||
}
|
||||
@@ -2524,8 +2593,7 @@ impl WorldGen {
|
||||
.and_then(|d| d.get("minecraft:overworld"))
|
||||
.and_then(|o| o.get("generator"));
|
||||
Some(Self {
|
||||
flat: text(generator.and_then(|g| g.get("type")))
|
||||
.is_some_and(|t| t.trim_start_matches("minecraft:") == "flat"),
|
||||
preset: generator.map_or(WorldPreset::Normal, WorldPreset::of_generator),
|
||||
structures: flag("generate_structures", true),
|
||||
bonus_chest: flag("bonus_chest", false),
|
||||
})
|
||||
@@ -2558,7 +2626,7 @@ impl WorldGen {
|
||||
impl Default for WorldGen {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
flat: false,
|
||||
preset: WorldPreset::Normal,
|
||||
structures: true,
|
||||
bonus_chest: false,
|
||||
}
|
||||
@@ -2633,6 +2701,34 @@ pub fn write_world_gen_settings_with(
|
||||
("preset", string(p)),
|
||||
])
|
||||
};
|
||||
// The overworld generator of worldgen/world_preset/<preset>.json: the
|
||||
// noise settings and the biome source each preset uses.
|
||||
let overworld = match options.preset {
|
||||
WorldPreset::Flat => flat,
|
||||
WorldPreset::LargeBiomes => dimension(
|
||||
"minecraft:overworld",
|
||||
"minecraft:large_biomes",
|
||||
preset("minecraft:overworld"),
|
||||
),
|
||||
WorldPreset::Amplified => dimension(
|
||||
"minecraft:overworld",
|
||||
"minecraft:amplified",
|
||||
preset("minecraft:overworld"),
|
||||
),
|
||||
WorldPreset::SingleBiomeSurface => dimension(
|
||||
"minecraft:overworld",
|
||||
"minecraft:overworld",
|
||||
Tag::compound([
|
||||
("type", string("minecraft:fixed")),
|
||||
("biome", string("minecraft:plains")),
|
||||
]),
|
||||
),
|
||||
WorldPreset::Normal => dimension(
|
||||
"minecraft:overworld",
|
||||
"minecraft:overworld",
|
||||
preset("minecraft:overworld"),
|
||||
),
|
||||
};
|
||||
write_saved_data(
|
||||
dir,
|
||||
"world_gen_settings",
|
||||
@@ -2646,18 +2742,7 @@ pub fn write_world_gen_settings_with(
|
||||
(
|
||||
"dimensions",
|
||||
Tag::compound([
|
||||
(
|
||||
"minecraft:overworld",
|
||||
if options.flat {
|
||||
flat
|
||||
} else {
|
||||
dimension(
|
||||
"minecraft:overworld",
|
||||
"minecraft:overworld",
|
||||
preset("minecraft:overworld"),
|
||||
)
|
||||
},
|
||||
),
|
||||
("minecraft:overworld", overworld),
|
||||
(
|
||||
"minecraft:the_nether",
|
||||
dimension(
|
||||
|
||||
@@ -399,7 +399,7 @@ impl Title {
|
||||
} = mode
|
||||
{
|
||||
if apply {
|
||||
options.flat = true;
|
||||
options.world_type = crate::save::WorldPreset::Flat;
|
||||
options.flat_settings = Some(flat.settings);
|
||||
}
|
||||
self.mode = Mode::Create {
|
||||
|
||||
@@ -30,8 +30,8 @@ pub struct WorldOptions {
|
||||
pub difficulty: usize,
|
||||
/// Allow Cheats as toggled; unset follows the game mode.
|
||||
pub commands: Option<bool>,
|
||||
/// The Superflat world preset instead of Default.
|
||||
pub flat: bool,
|
||||
/// The world preset the world is created with.
|
||||
pub world_type: crate::save::WorldPreset,
|
||||
/// CreateFlatWorldScreen's layers and biome, kept with the world type.
|
||||
pub flat_settings: Option<super::flat::FlatSettings>,
|
||||
pub structures: bool,
|
||||
@@ -46,7 +46,7 @@ impl Default for WorldOptions {
|
||||
hardcore: false,
|
||||
difficulty: 2,
|
||||
commands: None,
|
||||
flat: false,
|
||||
world_type: crate::save::WorldPreset::Normal,
|
||||
flat_settings: None,
|
||||
structures: true,
|
||||
bonus_chest: false,
|
||||
@@ -69,9 +69,8 @@ impl WorldOptions {
|
||||
.position(|d| *d == level.difficulty)
|
||||
.unwrap_or(2),
|
||||
commands: Some(commands),
|
||||
flat: generation.flat,
|
||||
flat_settings: generation
|
||||
.flat
|
||||
world_type: generation.preset,
|
||||
flat_settings: (generation.preset == crate::save::WorldPreset::Flat)
|
||||
.then(|| super::flat::FlatSettings::from_world(dir))
|
||||
.flatten(),
|
||||
structures: generation.structures,
|
||||
@@ -94,7 +93,7 @@ impl WorldOptions {
|
||||
}
|
||||
pub fn world_gen(&self) -> crate::save::WorldGen {
|
||||
crate::save::WorldGen {
|
||||
flat: self.flat,
|
||||
preset: self.world_type,
|
||||
structures: self.structures,
|
||||
bonus_chest: self.bonus_chest(),
|
||||
}
|
||||
@@ -119,8 +118,8 @@ impl WorldOptions {
|
||||
23 => self.difficulty = (self.difficulty + 1) % DIFFICULTIES.len(),
|
||||
24 => self.commands = Some(!self.commands(*creative)),
|
||||
25 => {
|
||||
self.flat = !self.flat;
|
||||
if self.flat {
|
||||
self.world_type = self.world_type.next();
|
||||
if self.world_type == crate::save::WorldPreset::Flat {
|
||||
// setWorldType starts the generator from the flat preset.
|
||||
self.flat_settings = Some(super::flat::FlatSettings::default());
|
||||
}
|
||||
@@ -255,14 +254,7 @@ pub(super) fn buttons(w: f32, h: f32, creative: bool, o: &WorldOptions) -> Vec<B
|
||||
gx,
|
||||
gy,
|
||||
150.0,
|
||||
labelled(
|
||||
"selectWorld.mapType",
|
||||
tr(if o.flat {
|
||||
"generator.minecraft.flat"
|
||||
} else {
|
||||
"generator.minecraft.normal"
|
||||
}),
|
||||
),
|
||||
labelled("selectWorld.mapType", tr(o.world_type.label())),
|
||||
true,
|
||||
25,
|
||||
),
|
||||
@@ -272,7 +264,7 @@ pub(super) fn buttons(w: f32, h: f32, creative: bool, o: &WorldOptions) -> Vec<B
|
||||
gy,
|
||||
150.0,
|
||||
tr("selectWorld.customizeType"),
|
||||
o.flat,
|
||||
o.world_type == crate::save::WorldPreset::Flat,
|
||||
26,
|
||||
),
|
||||
// SwitchGrid: 44-wide value-only buttons at the grid's right.
|
||||
|
||||
@@ -797,27 +797,49 @@ fn create_world_tabs_follow_vanilla_and_their_choices_reach_the_action() {
|
||||
};
|
||||
assert!(*creative && !options.hardcore && options.commands(true));
|
||||
// The World tab (second of three 124-wide tabs from x 54): its seed box
|
||||
// takes the focus, Superflat and the switches toggle.
|
||||
// takes the focus, the world type cycles and the switches toggle.
|
||||
let (action, sound) = f.title.click(54.0 + 124.0 + 10.0, 10.0, size);
|
||||
assert!(sound && action == Action::None);
|
||||
let world = labels(&f);
|
||||
assert_eq!((world[0].1, world[0].2), (85.0, 38.0));
|
||||
assert_eq!((world[2].1, world[2].2), (85.0 + 266.0, 38.0 + 73.0));
|
||||
f.title.click(world[0].1 + 10.0, world[0].2 + 10.0, size);
|
||||
// The world-type button cycles through vanilla's world presets.
|
||||
let world_type = |f: &Fixture| -> crate::save::WorldPreset {
|
||||
let Mode::Create { options, .. } = &f.title.mode else {
|
||||
panic!()
|
||||
};
|
||||
options.world_type
|
||||
};
|
||||
assert_eq!(world_type(&f), crate::save::WorldPreset::Normal);
|
||||
for expected in [
|
||||
crate::save::WorldPreset::Flat,
|
||||
crate::save::WorldPreset::LargeBiomes,
|
||||
crate::save::WorldPreset::Amplified,
|
||||
crate::save::WorldPreset::SingleBiomeSurface,
|
||||
crate::save::WorldPreset::Normal,
|
||||
] {
|
||||
f.title.click(world[0].1 + 10.0, world[0].2 + 10.0, size);
|
||||
assert_eq!(world_type(&f), expected);
|
||||
}
|
||||
// The amplified preset is the third one.
|
||||
for _ in 0..3 {
|
||||
f.title.click(world[0].1 + 10.0, world[0].2 + 10.0, size);
|
||||
}
|
||||
f.title.click(world[3].1 + 10.0, world[3].2 + 10.0, size);
|
||||
f.title.click(100.0, 38.0 + 41.0 + 10.0, size);
|
||||
let Mode::Create { focus, options, .. } = &f.title.mode else {
|
||||
panic!()
|
||||
};
|
||||
assert_eq!(*focus, 1);
|
||||
assert!(options.flat && options.bonus_chest());
|
||||
assert_eq!(options.world_type, crate::save::WorldPreset::Amplified);
|
||||
assert!(options.bonus_chest());
|
||||
let Action::Create { options, .. } = f.title.create_action() else {
|
||||
panic!()
|
||||
};
|
||||
assert_eq!(
|
||||
options.world_gen(),
|
||||
crate::save::WorldGen {
|
||||
flat: true,
|
||||
preset: crate::save::WorldPreset::Amplified,
|
||||
structures: true,
|
||||
bonus_chest: true
|
||||
}
|
||||
@@ -835,26 +857,86 @@ fn new_world_generation_settings_round_trip() {
|
||||
let f = Fixture::new();
|
||||
let dir = f.root.join("flat");
|
||||
let options = crate::save::WorldGen {
|
||||
flat: true,
|
||||
preset: crate::save::WorldPreset::Flat,
|
||||
structures: false,
|
||||
bonus_chest: true,
|
||||
};
|
||||
crate::save::write_world_gen_settings(&dir, 42, options).unwrap();
|
||||
assert_eq!(crate::save::WorldGen::read(&dir), Some(options));
|
||||
let settings = crate::save::world_gen_settings(&dir).unwrap();
|
||||
let generator = settings
|
||||
.get("dimensions")
|
||||
.and_then(|d| d.get("minecraft:overworld"))
|
||||
.and_then(|o| o.get("generator"));
|
||||
assert_eq!(
|
||||
crate::save::text(
|
||||
settings
|
||||
.get("dimensions")
|
||||
.and_then(|d| d.get("minecraft:overworld"))
|
||||
.and_then(|o| o.get("generator"))
|
||||
.and_then(|g| g.get("type"))
|
||||
)
|
||||
.as_deref(),
|
||||
crate::save::text(generator.and_then(|g| g.get("type"))).as_deref(),
|
||||
Some("minecraft:flat")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_world_preset_writes_its_own_generator() {
|
||||
let f = Fixture::new();
|
||||
let generator = |preset: crate::save::WorldPreset| {
|
||||
let dir = f.root.join(preset.id());
|
||||
let options = crate::save::WorldGen {
|
||||
preset,
|
||||
structures: true,
|
||||
bonus_chest: false,
|
||||
};
|
||||
crate::save::write_world_gen_settings(&dir, 42, options).unwrap();
|
||||
assert_eq!(crate::save::WorldGen::read(&dir), Some(options));
|
||||
let settings = crate::save::world_gen_settings(&dir).unwrap();
|
||||
let generator = settings
|
||||
.get("dimensions")
|
||||
.and_then(|d| d.get("minecraft:overworld"))
|
||||
.and_then(|o| o.get("generator"))
|
||||
.cloned()
|
||||
.unwrap();
|
||||
(
|
||||
crate::save::text(generator.get("type")),
|
||||
crate::save::text(generator.get("settings")),
|
||||
crate::save::text(generator.get("biome_source").and_then(|s| s.get("type"))),
|
||||
)
|
||||
};
|
||||
assert_eq!(
|
||||
generator(crate::save::WorldPreset::Normal),
|
||||
(
|
||||
Some("minecraft:noise".to_owned()),
|
||||
Some("minecraft:overworld".to_owned()),
|
||||
Some("minecraft:multi_noise".to_owned()),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
generator(crate::save::WorldPreset::Amplified),
|
||||
(
|
||||
Some("minecraft:noise".to_owned()),
|
||||
Some("minecraft:amplified".to_owned()),
|
||||
Some("minecraft:multi_noise".to_owned()),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
generator(crate::save::WorldPreset::LargeBiomes),
|
||||
(
|
||||
Some("minecraft:noise".to_owned()),
|
||||
Some("minecraft:large_biomes".to_owned()),
|
||||
Some("minecraft:multi_noise".to_owned()),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
generator(crate::save::WorldPreset::SingleBiomeSurface),
|
||||
(
|
||||
Some("minecraft:noise".to_owned()),
|
||||
Some("minecraft:overworld".to_owned()),
|
||||
Some("minecraft:fixed".to_owned()),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
generator(crate::save::WorldPreset::Flat).0,
|
||||
Some("minecraft:flat".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn world_fields_edit_at_their_cursor() {
|
||||
use winit::keyboard::KeyCode;
|
||||
|
||||
@@ -3322,4 +3322,56 @@ mod tests {
|
||||
assert!(Arc::ptr_eq(first, hit));
|
||||
}
|
||||
}
|
||||
|
||||
/// The resources the worldgen tests read.
|
||||
fn test_root() -> std::path::PathBuf {
|
||||
std::env::var_os("HORIZON_TEST_RESOURCES")
|
||||
.or_else(|| std::env::var_os("HORIZON_RESOURCES"))
|
||||
.map(std::path::PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../.local/horizon-client/26.3")
|
||||
})
|
||||
}
|
||||
/// The block registry the worldgen bundle needs. `GeneratorData` keeps it
|
||||
/// for as long as the generator lives, so it is shared, not freed.
|
||||
static TEST_REGISTRY: std::sync::LazyLock<BlockRegistry> = std::sync::LazyLock::new(|| {
|
||||
crate::level::data::load_registry(&test_root()).expect("registry")
|
||||
});
|
||||
|
||||
/// The world presets with their own noise settings generate the terrain
|
||||
/// those settings describe: the amplified and large-biome presets are not
|
||||
/// the overworld's terrain under another name.
|
||||
#[test]
|
||||
fn world_presets_use_their_own_noise_settings() {
|
||||
let root = test_root();
|
||||
if !root.join("worldgen/world_presets.json").exists() {
|
||||
eprintln!("skipping: no worldgen bundle at {}", root.display());
|
||||
return;
|
||||
}
|
||||
let data =
|
||||
GeneratorData::load(&root.join("worldgen"), &TEST_REGISTRY).expect("worldgen data");
|
||||
let surface = |preset: &str| {
|
||||
let generator = OverworldGenerator::for_world(
|
||||
data.clone(),
|
||||
1234,
|
||||
preset,
|
||||
"minecraft:overworld",
|
||||
false,
|
||||
)
|
||||
.expect("generator");
|
||||
let mut worker = generator.worker();
|
||||
(0..32)
|
||||
.map(|i| {
|
||||
worker
|
||||
.surface_sample(i * 137, i * 91)
|
||||
.expect("surface")
|
||||
.height
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let normal = surface("minecraft:normal");
|
||||
assert!(normal.iter().all(|height| (0..384).contains(height)));
|
||||
assert_ne!(normal, surface("minecraft:amplified"));
|
||||
assert_ne!(normal, surface("minecraft:large_biomes"));
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,8 @@ the worker's number is left out). In a world without structures (`generate-struc
|
||||
finds none) and how many of the saved chunks hold structure starts or references (none:
|
||||
ChunkStatusTasks.generateStructureStarts does nothing).
|
||||
|
||||
Horizon generates the normal and flat presets only: `large_biomes`, `amplified`, `single_biome_surface` and
|
||||
`debug_all_block_states` aren't tested.
|
||||
Horizon generates the normal, flat, amplified, large-biome and single-biome presets:
|
||||
`debug_all_block_states` isn't tested.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
@@ -61,6 +61,9 @@ CASES = {
|
||||
'generator-settings': '{"layers":[{"block":"minecraft:glass","height":5}],"biome":"nowhere"}',
|
||||
},
|
||||
'normal': {'level-type': 'minecraft:normal', 'level-seed': 'abc', 'generate-structures': 'false'},
|
||||
'amplified': {'level-type': 'minecraft:amplified', 'level-seed': '1'},
|
||||
'large-biomes': {'level-type': 'minecraft:large_biomes', 'level-seed': '2'},
|
||||
'single-biome': {'level-type': 'minecraft:single_biome_surface', 'level-seed': '3'},
|
||||
'unknown': {'level-type': 'Some Type', 'level-seed': '42'},
|
||||
}
|
||||
WORKER = re.compile(r'\[Worker-Main-\d+/(WARN|ERROR)\]: (.*)')
|
||||
@@ -155,9 +158,10 @@ def main():
|
||||
schema=1, minecraft=lock['minecraft']['version'], platform=platform.platform(),
|
||||
java=subprocess.check_output(['java', '--version'], text=True).splitlines()[0],
|
||||
cases=list(CASES), lines=len(vanilla), output_sha256=lab.digest(build / 'horizon.txt', 'sha256'),
|
||||
scope='a new dedicated-server world: level-type (flat, normal, unknown), a flat world\'s '
|
||||
'generator-settings, generate-structures, as world_gen_settings.dat and the lines logged; without '
|
||||
'structures, locate structure\'s replies and the saved chunks\' structure starts and references.'))
|
||||
scope='a new dedicated-server world: level-type (flat, normal, amplified, large_biomes, '
|
||||
'single_biome_surface, unknown), a flat world\'s generator-settings, generate-structures, as '
|
||||
'world_gen_settings.dat and the lines logged; without structures, locate structure\'s replies and '
|
||||
'the saved chunks\' structure starts and references.'))
|
||||
print(f'server world gen: {len(CASES)} cases, {len(vanilla)} lines identical')
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user