Merge pull request #58 from neocturne/update-1.21.4

Updates + 1.21.4 support
This commit is contained in:
Matthias Schiffer 2025-01-02 01:58:26 +01:00 committed by GitHub
commit c1d2eaa17e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 984 additions and 469 deletions

View file

@ -2,6 +2,10 @@
## [Unreleased] - ReleaseDate
- Added support for Minecraft 1.21.4 block types
- Added support for Minecraft 1.21.4 Pale Garden biome
- viewer: added images for pale oak signs
## [2.2.0] - 2024-06-23
### Added

52
Cargo.lock generated
View file

@ -83,9 +83,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "autocfg"
@ -131,9 +131,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bytemuck"
version = "1.20.0"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
@ -149,9 +149,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "cc"
version = "1.2.4"
version = "1.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
dependencies = [
"jobserver",
"libc",
@ -357,9 +357,9 @@ dependencies = [
[[package]]
name = "foldhash"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "futures-core"
@ -514,9 +514,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.168"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libz-ng-sys"
@ -627,9 +627,9 @@ dependencies = [
[[package]]
name = "miniz_oxide"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
dependencies = [
"adler2",
"simd-adler32",
@ -675,9 +675,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.36.5"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
@ -737,9 +737,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "png"
version = "0.17.15"
version = "0.17.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d"
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
@ -759,9 +759,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@ -863,9 +863,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
@ -881,9 +881,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@ -892,9 +892,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
dependencies = [
"itoa",
"memchr",
@ -946,9 +946,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.90"
version = "2.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
dependencies = [
"proc-macro2",
"quote",

View file

@ -2,7 +2,7 @@
* Render beautiful maps of your [Minecraft](https://minecraft.net/) worlds!
* Put them on a webserver and view them in your browser!
* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21 (no mod installation necessary!)
* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21.4 (no mod installation required!)
* Illumination layer: the world at night
* Fast: create a full map for a huge 3GB savegame in less than 5 minutes in single-threaded operation
* Multi-threading support: pass `-j N` to the renderer to use `N` parallel threads for generation

View file

@ -1,437 +1,117 @@
//! Biome data structures
//! Biome data
//!
//! This file is generated using resource/biomes.py, do not edit
use serde::{Deserialize, Serialize};
use super::*;
use BiomeGrassColorModifier::*;
use super::Color;
/// Grass color modifier used by a biome
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BiomeGrassColorModifier {
/// Grass color modifier used by the dark forest biome
DarkForest,
/// Grass color modifier used by swamp biomes
Swamp,
}
/// A biome specification
///
/// A Biome contains all information about a biome necessary to compute a block
/// color given a block type and depth
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Biome {
/// Temperature value
///
/// For more efficient storage, the temperature is stored as an integer
/// after mutiplying the raw value by 20
pub temp: i8,
/// Downfall value
///
/// For more efficient storage, the downfall is stored as an integer
/// after mutiplying the raw value by 20
pub downfall: i8,
/// Water color override
pub water_color: Option<Color>,
/// Foliage color override
pub foliage_color: Option<Color>,
/// Grass color override
pub grass_color: Option<Color>,
/// Grass color modifier
pub grass_color_modifier: Option<BiomeGrassColorModifier>,
}
impl Biome {
/// Constructs a new Biome
const fn new(temp: i16, downfall: i16) -> Biome {
/// Helper to encode temperature and downfall values
///
/// Converts temperatue and downfall from the input format
/// (mutiplied by 100) to i8 range for more efficient storage.
const fn encode(v: i16) -> i8 {
(v / 5) as i8
}
Biome {
temp: encode(temp),
downfall: encode(downfall),
grass_color_modifier: None,
water_color: None,
foliage_color: None,
grass_color: None,
}
}
/// Builder function to override the biome water color
const fn water(self, water_color: [u8; 3]) -> Biome {
Biome {
water_color: Some(Color(water_color)),
..self
}
}
/// Builder function to override the biome foliage color
const fn foliage(self, foliage_color: [u8; 3]) -> Biome {
Biome {
foliage_color: Some(Color(foliage_color)),
..self
}
}
/// Builder function to override the biome grass color
const fn grass(self, grass_color: [u8; 3]) -> Biome {
Biome {
grass_color: Some(Color(grass_color)),
..self
}
}
/// Builder function to set a grass color modifier
const fn modify(self, grass_color_modifier: BiomeGrassColorModifier) -> Biome {
Biome {
grass_color_modifier: Some(grass_color_modifier),
..self
}
}
/// Decodes a temperature or downfall value from the storage format to
/// f32 for further calculation
fn decode(val: i8) -> f32 {
f32::from(val) / 20.0
}
/// Returns the biome's temperature decoded to its original float value
pub fn temp(&self) -> f32 {
Self::decode(self.temp)
}
/// Returns the biome's downfall decoded to its original float value
pub fn downfall(&self) -> f32 {
Self::decode(self.downfall)
}
}
/// Standard biome specifications
pub const BIOMES: &[(&str, Biome)] = {
use BiomeGrassColorModifier::*;
// Data extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn
// We can't use floats in const functions, to temperature and downfall values
// are specified multipled by 100. The underscore is used in place of the decimal point
// of the original values.
#[allow(clippy::zero_prefixed_literal)]
&[
// Overworld
(
"badlands",
Biome::new(2_00, 0_00)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
("bamboo_jungle", Biome::new(0_95, 0_90)),
("beach", Biome::new(0_80, 0_40)),
("birch_forest", Biome::new(0_60, 0_60)),
(
"cherry_grove",
Biome::new(0_50, 0_80)
.water([93, 183, 239])
.grass([182, 219, 97])
.foliage([182, 219, 97]),
),
("cold_ocean", Biome::new(0_50, 0_50).water([61, 87, 214])),
("dark_forest", Biome::new(0_70, 0_80).modify(DarkForest)),
(
"deep_cold_ocean",
Biome::new(0_50, 0_50).water([61, 87, 214]),
),
("deep_dark", Biome::new(0_80, 0_40)),
(
"deep_frozen_ocean",
Biome::new(0_50, 0_50).water([57, 56, 201]),
),
(
"deep_lukewarm_ocean",
Biome::new(0_50, 0_50).water([69, 173, 242]),
),
("deep_ocean", Biome::new(0_50, 0_50)),
("desert", Biome::new(2_00, 0_00)),
("dripstone_caves", Biome::new(0_80, 0_40)),
(
"eroded_badlands",
Biome::new(2_00, 0_00)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
("flower_forest", Biome::new(0_70, 0_80)),
("forest", Biome::new(0_70, 0_80)),
("frozen_ocean", Biome::new(0_00, 0_50).water([57, 56, 201])),
("frozen_peaks", Biome::new(-0_70, 0_90)),
("frozen_river", Biome::new(0_00, 0_50).water([57, 56, 201])),
("grove", Biome::new(-0_20, 0_80)),
("ice_spikes", Biome::new(0_00, 0_50)),
("jagged_peaks", Biome::new(-0_70, 0_90)),
("jungle", Biome::new(0_95, 0_90)),
(
"lukewarm_ocean",
Biome::new(0_50, 0_50).water([69, 173, 242]),
),
("lush_caves", Biome::new(0_50, 0_50)),
(
"mangrove_swamp",
Biome::new(0_80, 0_90)
.water([58, 122, 106])
.foliage([141, 177, 39])
.modify(Swamp),
),
("meadow", Biome::new(0_50, 0_80).water([14, 78, 207])),
("mushroom_fields", Biome::new(0_90, 1_00)),
("ocean", Biome::new(0_50, 0_50)),
("old_growth_birch_forest", Biome::new(0_60, 0_60)),
("old_growth_pine_taiga", Biome::new(0_30, 0_80)),
("old_growth_spruce_taiga", Biome::new(0_25, 0_80)),
("plains", Biome::new(0_80, 0_40)),
("river", Biome::new(0_50, 0_50)),
("savanna", Biome::new(2_00, 0_00)),
("savanna_plateau", Biome::new(2_00, 0_00)),
("snowy_beach", Biome::new(0_05, 0_30).water([61, 87, 214])),
("snowy_plains", Biome::new(0_00, 0_50)),
("snowy_slopes", Biome::new(-0_30, 0_90)),
("snowy_taiga", Biome::new(-0_50, 0_40).water([61, 87, 214])),
("sparse_jungle", Biome::new(0_95, 0_80)),
("stony_peaks", Biome::new(1_00, 0_30)),
("stony_shore", Biome::new(0_20, 0_30)),
("sunflower_plains", Biome::new(0_80, 0_40)),
(
"swamp",
Biome::new(0_80, 0_90)
.water([97, 123, 100])
.foliage([106, 112, 57])
.modify(Swamp),
),
("taiga", Biome::new(0_25, 0_80)),
("the_void", Biome::new(0_50, 0_50)),
("warm_ocean", Biome::new(0_50, 0_50).water([67, 213, 238])),
("windswept_forest", Biome::new(0_20, 0_30)),
("windswept_gravelly_hills", Biome::new(0_20, 0_30)),
("windswept_hills", Biome::new(0_20, 0_30)),
("windswept_savanna", Biome::new(2_00, 0_00)),
(
"wooded_badlands",
Biome::new(2_00, 0_00)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
// Nether
("basalt_deltas", Biome::new(2_00, 0_00)),
("crimson_forest", Biome::new(2_00, 0_00)),
("nether_wastes", Biome::new(2_00, 0_00)),
("soul_sand_valley", Biome::new(2_00, 0_00)),
("warped_forest", Biome::new(2_00, 0_00)),
// End
("end_barrens", Biome::new(0_50, 0_50)),
("end_highlands", Biome::new(0_50, 0_50)),
("end_midlands", Biome::new(0_50, 0_50)),
("small_end_islands", Biome::new(0_50, 0_50)),
("the_end", Biome::new(0_50, 0_50)),
]
};
/// Biome ID aliases
///
/// Some biomes have been renamed or merged in recent Minecraft versions.
/// Maintain a list of aliases to support chunks saved by older versions.
pub const BIOME_ALIASES: &[(&str, &str)] = &[
// Biomes fix
("beaches", "beach"),
("cold_beach", "snowy_beach"),
("cold_deep_ocean", "deep_cold_ocean"),
("extreme_hills", "mountains"),
("extreme_hills_with_trees", "wooded_mountains"),
("forest_hills", "wooded_hills"),
("frozen_deep_ocean", "deep_frozen_ocean"),
("hell", "nether_wastes"),
("ice_flats", "snowy_tundra"),
("ice_mountains", "snowy_mountains"),
("lukewarm_deep_ocean", "deep_lukewarm_ocean"),
("mesa", "badlands"),
("mesa_clear_rock", "badlands_plateau"),
("mesa_rock", "wooded_badlands_plateau"),
("mushroom_island", "mushroom_fields"),
("mushroom_island_shore", "mushroom_field_shore"),
("mutated_birch_forest", "tall_birch_forest"),
("mutated_birch_forest_hills", "tall_birch_hills"),
("mutated_desert", "desert_lakes"),
("mutated_extreme_hills", "gravelly_mountains"),
/// List if known biomes and their properties
pub const BIOMES: &[(&str, Biome)] = &[
(
"mutated_extreme_hills_with_trees",
"modified_gravelly_mountains",
"badlands",
Biome::new(200, 0)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
("bamboo_jungle", Biome::new(95, 90)),
("basalt_deltas", Biome::new(200, 0)),
("beach", Biome::new(80, 40)),
("birch_forest", Biome::new(60, 60)),
(
"cherry_grove",
Biome::new(50, 80)
.foliage([182, 219, 97])
.grass([182, 219, 97])
.water([93, 183, 239]),
),
("cold_ocean", Biome::new(50, 50).water([61, 87, 214])),
("crimson_forest", Biome::new(200, 0)),
("dark_forest", Biome::new(70, 80).modify(DarkForest)),
("deep_cold_ocean", Biome::new(50, 50).water([61, 87, 214])),
("deep_dark", Biome::new(80, 40)),
("deep_frozen_ocean", Biome::new(50, 50).water([57, 56, 201])),
(
"deep_lukewarm_ocean",
Biome::new(50, 50).water([69, 173, 242]),
),
("deep_ocean", Biome::new(50, 50)),
("desert", Biome::new(200, 0)),
("dripstone_caves", Biome::new(80, 40)),
("end_barrens", Biome::new(50, 50)),
("end_highlands", Biome::new(50, 50)),
("end_midlands", Biome::new(50, 50)),
(
"eroded_badlands",
Biome::new(200, 0)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
("flower_forest", Biome::new(70, 80)),
("forest", Biome::new(70, 80)),
("frozen_ocean", Biome::new(0, 50).water([57, 56, 201])),
("frozen_peaks", Biome::new(-70, 90)),
("frozen_river", Biome::new(0, 50).water([57, 56, 201])),
("grove", Biome::new(-20, 80)),
("ice_spikes", Biome::new(0, 50)),
("jagged_peaks", Biome::new(-70, 90)),
("jungle", Biome::new(95, 90)),
("lukewarm_ocean", Biome::new(50, 50).water([69, 173, 242])),
("lush_caves", Biome::new(50, 50)),
(
"mangrove_swamp",
Biome::new(80, 90)
.foliage([141, 177, 39])
.modify(Swamp)
.water([58, 122, 106]),
),
("meadow", Biome::new(50, 80).water([14, 78, 207])),
("mushroom_fields", Biome::new(90, 100)),
("nether_wastes", Biome::new(200, 0)),
("ocean", Biome::new(50, 50)),
("old_growth_birch_forest", Biome::new(60, 60)),
("old_growth_pine_taiga", Biome::new(30, 80)),
("old_growth_spruce_taiga", Biome::new(25, 80)),
(
"pale_garden",
Biome::new(70, 80)
.foliage([135, 141, 118])
.grass([119, 130, 114])
.water([118, 136, 157]),
),
("plains", Biome::new(80, 40)),
("river", Biome::new(50, 50)),
("savanna", Biome::new(200, 0)),
("savanna_plateau", Biome::new(200, 0)),
("small_end_islands", Biome::new(50, 50)),
("snowy_beach", Biome::new(5, 30).water([61, 87, 214])),
("snowy_plains", Biome::new(0, 50)),
("snowy_slopes", Biome::new(-30, 90)),
("snowy_taiga", Biome::new(-50, 40).water([61, 87, 214])),
("soul_sand_valley", Biome::new(200, 0)),
("sparse_jungle", Biome::new(95, 80)),
("stony_peaks", Biome::new(100, 30)),
("stony_shore", Biome::new(20, 30)),
("sunflower_plains", Biome::new(80, 40)),
(
"swamp",
Biome::new(80, 90)
.foliage([106, 112, 57])
.modify(Swamp)
.water([97, 123, 100]),
),
("taiga", Biome::new(25, 80)),
("the_end", Biome::new(50, 50)),
("the_void", Biome::new(50, 50)),
("warm_ocean", Biome::new(50, 50).water([67, 213, 238])),
("warped_forest", Biome::new(200, 0)),
("windswept_forest", Biome::new(20, 30)),
("windswept_gravelly_hills", Biome::new(20, 30)),
("windswept_hills", Biome::new(20, 30)),
("windswept_savanna", Biome::new(200, 0)),
(
"wooded_badlands",
Biome::new(200, 0)
.foliage([158, 129, 77])
.grass([144, 129, 77]),
),
("mutated_forest", "flower_forest"),
("mutated_ice_flats", "ice_spikes"),
("mutated_jungle", "modified_jungle"),
("mutated_jungle_edge", "modified_jungle_edge"),
("mutated_mesa", "eroded_badlands"),
("mutated_mesa_clear_rock", "modified_badlands_plateau"),
("mutated_mesa_rock", "modified_wooded_badlands_plateau"),
("mutated_plains", "sunflower_plains"),
("mutated_redwood_taiga", "giant_spruce_taiga"),
("mutated_redwood_taiga_hills", "giant_spruce_taiga_hills"),
("mutated_roofed_forest", "dark_forest_hills"),
("mutated_savanna", "shattered_savanna"),
("mutated_savanna_rock", "shattered_savanna_plateau"),
("mutated_swampland", "swamp_hills"),
("mutated_taiga", "taiga_mountains"),
("mutated_taiga_cold", "snowy_taiga_mountains"),
("redwood_taiga", "giant_tree_taiga"),
("redwood_taiga_hills", "giant_tree_taiga_hills"),
("roofed_forest", "dark_forest"),
("savanna_rock", "savanna_plateau"),
("sky", "the_end"),
("sky_island_barren", "end_barrens"),
("sky_island_high", "end_highlands"),
("sky_island_low", "small_end_islands"),
("sky_island_medium", "end_midlands"),
("smaller_extreme_hills", "mountain_edge"),
("stone_beach", "stone_shore"),
("swampland", "swamp"),
("taiga_cold", "snowy_taiga"),
("taiga_cold_hills", "snowy_taiga_hills"),
("void", "the_void"),
("warm_deep_ocean", "deep_warm_ocean"),
// Nether biome rename
("nether", "nether_wastes"),
// Caves and Cliffs biome renames
("badlands_plateau", "badlands"),
("bamboo_jungle_hills", "bamboo_jungle"),
("birch_forest_hills", "birch_forest"),
("dark_forest_hills", "dark_forest"),
("desert_hills", "desert"),
("desert_lakes", "desert"),
("giant_spruce_taiga", "old_growth_spruce_taiga"),
("giant_spruce_taiga_hills", "old_growth_spruce_taiga"),
("giant_tree_taiga", "old_growth_pine_taiga"),
("giant_tree_taiga_hills", "old_growth_pine_taiga"),
("gravelly_mountains", "windswept_gravelly_hills"),
("jungle_edge", "sparse_jungle"),
("jungle_hills", "jungle"),
("lofty_peaks", "jagged_peaks"),
("modified_badlands_plateau", "badlands"),
("modified_gravelly_mountains", "windswept_gravelly_hills"),
("modified_jungle", "jungle"),
("modified_jungle_edge", "sparse_jungle"),
("modified_wooded_badlands_plateau", "wooded_badlands"),
("mountain_edge", "windswept_hills"),
("mountains", "windswept_hills"),
("mushroom_field_shore", "mushroom_fields"),
("shattered_savanna", "windswept_savanna"),
("shattered_savanna_plateau", "windswept_savanna"),
("snowcapped_peaks", "frozen_peaks"),
("snowy_mountains", "snowy_plains"),
("snowy_taiga_hills", "snowy_taiga"),
("snowy_taiga_mountains", "snowy_taiga"),
("snowy_tundra", "snowy_plains"),
("stone_shore", "stony_shore"),
("swamp_hills", "swamp"),
("taiga_hills", "taiga"),
("taiga_mountains", "taiga"),
("tall_birch_forest", "old_growth_birch_forest"),
("tall_birch_hills", "old_growth_birch_forest"),
("wooded_badlands_plateau", "wooded_badlands"),
("wooded_hills", "forest"),
("wooded_mountains", "windswept_forest"),
// Remove Deep Warm Ocean
("deep_warm_ocean", "warm_ocean"),
];
/// Maps old numeric biome IDs to new string IDs
pub fn legacy_biome(index: u8) -> &'static str {
match index {
0 => "ocean",
1 => "plains",
2 => "desert",
3 => "mountains",
4 => "forest",
5 => "taiga",
6 => "swamp",
7 => "river",
8 => "nether_wastes",
9 => "the_end",
10 => "frozen_ocean",
11 => "frozen_river",
12 => "snowy_tundra",
13 => "snowy_mountains",
14 => "mushroom_fields",
15 => "mushroom_field_shore",
16 => "beach",
17 => "desert_hills",
18 => "wooded_hills",
19 => "taiga_hills",
20 => "mountain_edge",
21 => "jungle",
22 => "jungle_hills",
23 => "jungle_edge",
24 => "deep_ocean",
25 => "stone_shore",
26 => "snowy_beach",
27 => "birch_forest",
28 => "birch_forest_hills",
29 => "dark_forest",
30 => "snowy_taiga",
31 => "snowy_taiga_hills",
32 => "giant_tree_taiga",
33 => "giant_tree_taiga_hills",
34 => "wooded_mountains",
35 => "savanna",
36 => "savanna_plateau",
37 => "badlands",
38 => "wooded_badlands_plateau",
39 => "badlands_plateau",
40 => "small_end_islands",
41 => "end_midlands",
42 => "end_highlands",
43 => "end_barrens",
44 => "warm_ocean",
45 => "lukewarm_ocean",
46 => "cold_ocean",
47 => "deep_warm_ocean",
48 => "deep_lukewarm_ocean",
49 => "deep_cold_ocean",
50 => "deep_frozen_ocean",
127 => "the_void",
129 => "sunflower_plains",
130 => "desert_lakes",
131 => "gravelly_mountains",
132 => "flower_forest",
133 => "taiga_mountains",
134 => "swamp_hills",
140 => "ice_spikes",
149 => "modified_jungle",
151 => "modified_jungle_edge",
155 => "tall_birch_forest",
156 => "tall_birch_hills",
157 => "dark_forest_hills",
158 => "snowy_taiga_mountains",
160 => "giant_spruce_taiga",
161 => "giant_spruce_taiga_hills",
162 => "modified_gravelly_mountains",
163 => "shattered_savanna",
164 => "shattered_savanna_plateau",
165 => "eroded_badlands",
166 => "modified_wooded_badlands_plateau",
167 => "modified_badlands_plateau",
168 => "bamboo_jungle",
169 => "bamboo_jungle_hills",
170 => "soul_sand_valley",
171 => "crimson_forest",
172 => "warped_forest",
173 => "basalt_deltas",
174 => "dripstone_caves",
175 => "lush_caves",
177 => "meadow",
178 => "grove",
179 => "snowy_slopes",
180 => "snowcapped_peaks",
181 => "lofty_peaks",
182 => "stony_peaks",
_ => "ocean",
}
}

View file

@ -1,7 +1,12 @@
//! Block type information
//!
//! This file is generated using resource/generate.py, do not edit
use enumflags2::make_bitflags;
use super::*;
/// List if known block types and their properties
pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
(
"acacia_button",
@ -1868,7 +1873,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([47, 23, 28]),
color: Color([45, 22, 27]),
},
sign_material: None,
},
@ -1903,6 +1908,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"chiseled_resin_bricks",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([200, 84, 24]),
},
sign_material: None,
},
),
(
"chiseled_sandstone",
ConstBlockType {
@ -1973,6 +1988,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"closed_eyeblossom",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: None,
},
),
(
"coal_block",
ConstBlockType {
@ -2283,6 +2308,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"creaking_heart",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([73, 59, 54]),
},
sign_material: None,
},
),
(
"creeper_head",
ConstBlockType {
@ -6253,6 +6288,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"open_eyeblossom",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: None,
},
),
(
"orange_banner",
ConstBlockType {
@ -6523,6 +6568,206 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"pale_hanging_moss",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: None,
},
),
(
"pale_moss_block",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([106, 112, 104]),
},
sign_material: None,
},
),
(
"pale_moss_carpet",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([106, 112, 104]),
},
sign_material: None,
},
),
(
"pale_oak_button",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: None,
},
),
(
"pale_oak_door",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([216, 208, 206]),
},
sign_material: None,
},
),
(
"pale_oak_fence",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_fence_gate",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_hanging_sign",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: Some("pale_oak"),
},
),
(
"pale_oak_leaves",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([116, 121, 114]),
},
sign_material: None,
},
),
(
"pale_oak_log",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([198, 189, 187]),
},
sign_material: None,
},
),
(
"pale_oak_planks",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_pressure_plate",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_sapling",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([109, 105, 99]),
},
sign_material: None,
},
),
(
"pale_oak_sign",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: Some("pale_oak"),
},
),
(
"pale_oak_slab",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_stairs",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([227, 217, 216]),
},
sign_material: None,
},
),
(
"pale_oak_trapdoor",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([229, 220, 218]),
},
sign_material: None,
},
),
(
"pale_oak_wall_hanging_sign",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{WallSign}),
color: Color([0, 0, 0]),
},
sign_material: Some("pale_oak"),
},
),
(
"pale_oak_wall_sign",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{WallSign}),
color: Color([0, 0, 0]),
},
sign_material: Some("pale_oak"),
},
),
(
"pale_oak_wood",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([87, 77, 75]),
},
sign_material: None,
},
),
(
"pearlescent_froglight",
ConstBlockType {
@ -7213,6 +7458,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"potted_closed_eyeblossom",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([108, 98, 101]),
},
sign_material: None,
},
),
(
"potted_cornflower",
ConstBlockType {
@ -7333,6 +7588,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"potted_open_eyeblossom",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([133, 124, 127]),
},
sign_material: None,
},
),
(
"potted_orange_tulip",
ConstBlockType {
@ -7353,6 +7618,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"potted_pale_oak_sapling",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([109, 105, 99]),
},
sign_material: None,
},
),
(
"potted_pink_tulip",
ConstBlockType {
@ -8193,6 +8468,66 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"resin_block",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([217, 99, 25]),
},
sign_material: None,
},
),
(
"resin_brick_slab",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([205, 88, 24]),
},
sign_material: None,
},
),
(
"resin_brick_stairs",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([205, 88, 24]),
},
sign_material: None,
},
),
(
"resin_brick_wall",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([205, 88, 24]),
},
sign_material: None,
},
),
(
"resin_bricks",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([205, 88, 24]),
},
sign_material: None,
},
),
(
"resin_clump",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{}),
color: Color([0, 0, 0]),
},
sign_material: None,
},
),
(
"respawn_anchor",
ConstBlockType {
@ -9173,6 +9508,26 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[
sign_material: None,
},
),
(
"stripped_pale_oak_log",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([235, 226, 225]),
},
sign_material: None,
},
),
(
"stripped_pale_oak_wood",
ConstBlockType {
block_color: BlockColor {
flags: make_bitflags!(BlockFlag::{Opaque}),
color: Color([245, 238, 236]),
},
sign_material: None,
},
),
(
"stripped_spruce_log",
ConstBlockType {

View file

@ -0,0 +1,202 @@
//! Manually maintained biome data (aliases and legacy biome IDs)
/// Biome ID aliases
///
/// Some biomes have been renamed or merged in recent Minecraft versions.
/// Maintain a list of aliases to support chunks saved by older versions.
pub const BIOME_ALIASES: &[(&str, &str)] = &[
// Biomes fix
("beaches", "beach"),
("cold_beach", "snowy_beach"),
("cold_deep_ocean", "deep_cold_ocean"),
("extreme_hills", "mountains"),
("extreme_hills_with_trees", "wooded_mountains"),
("forest_hills", "wooded_hills"),
("frozen_deep_ocean", "deep_frozen_ocean"),
("hell", "nether_wastes"),
("ice_flats", "snowy_tundra"),
("ice_mountains", "snowy_mountains"),
("lukewarm_deep_ocean", "deep_lukewarm_ocean"),
("mesa", "badlands"),
("mesa_clear_rock", "badlands_plateau"),
("mesa_rock", "wooded_badlands_plateau"),
("mushroom_island", "mushroom_fields"),
("mushroom_island_shore", "mushroom_field_shore"),
("mutated_birch_forest", "tall_birch_forest"),
("mutated_birch_forest_hills", "tall_birch_hills"),
("mutated_desert", "desert_lakes"),
("mutated_extreme_hills", "gravelly_mountains"),
(
"mutated_extreme_hills_with_trees",
"modified_gravelly_mountains",
),
("mutated_forest", "flower_forest"),
("mutated_ice_flats", "ice_spikes"),
("mutated_jungle", "modified_jungle"),
("mutated_jungle_edge", "modified_jungle_edge"),
("mutated_mesa", "eroded_badlands"),
("mutated_mesa_clear_rock", "modified_badlands_plateau"),
("mutated_mesa_rock", "modified_wooded_badlands_plateau"),
("mutated_plains", "sunflower_plains"),
("mutated_redwood_taiga", "giant_spruce_taiga"),
("mutated_redwood_taiga_hills", "giant_spruce_taiga_hills"),
("mutated_roofed_forest", "dark_forest_hills"),
("mutated_savanna", "shattered_savanna"),
("mutated_savanna_rock", "shattered_savanna_plateau"),
("mutated_swampland", "swamp_hills"),
("mutated_taiga", "taiga_mountains"),
("mutated_taiga_cold", "snowy_taiga_mountains"),
("redwood_taiga", "giant_tree_taiga"),
("redwood_taiga_hills", "giant_tree_taiga_hills"),
("roofed_forest", "dark_forest"),
("savanna_rock", "savanna_plateau"),
("sky", "the_end"),
("sky_island_barren", "end_barrens"),
("sky_island_high", "end_highlands"),
("sky_island_low", "small_end_islands"),
("sky_island_medium", "end_midlands"),
("smaller_extreme_hills", "mountain_edge"),
("stone_beach", "stone_shore"),
("swampland", "swamp"),
("taiga_cold", "snowy_taiga"),
("taiga_cold_hills", "snowy_taiga_hills"),
("void", "the_void"),
("warm_deep_ocean", "deep_warm_ocean"),
// Nether biome rename
("nether", "nether_wastes"),
// Caves and Cliffs biome renames
("badlands_plateau", "badlands"),
("bamboo_jungle_hills", "bamboo_jungle"),
("birch_forest_hills", "birch_forest"),
("dark_forest_hills", "dark_forest"),
("desert_hills", "desert"),
("desert_lakes", "desert"),
("giant_spruce_taiga", "old_growth_spruce_taiga"),
("giant_spruce_taiga_hills", "old_growth_spruce_taiga"),
("giant_tree_taiga", "old_growth_pine_taiga"),
("giant_tree_taiga_hills", "old_growth_pine_taiga"),
("gravelly_mountains", "windswept_gravelly_hills"),
("jungle_edge", "sparse_jungle"),
("jungle_hills", "jungle"),
("lofty_peaks", "jagged_peaks"),
("modified_badlands_plateau", "badlands"),
("modified_gravelly_mountains", "windswept_gravelly_hills"),
("modified_jungle", "jungle"),
("modified_jungle_edge", "sparse_jungle"),
("modified_wooded_badlands_plateau", "wooded_badlands"),
("mountain_edge", "windswept_hills"),
("mountains", "windswept_hills"),
("mushroom_field_shore", "mushroom_fields"),
("shattered_savanna", "windswept_savanna"),
("shattered_savanna_plateau", "windswept_savanna"),
("snowcapped_peaks", "frozen_peaks"),
("snowy_mountains", "snowy_plains"),
("snowy_taiga_hills", "snowy_taiga"),
("snowy_taiga_mountains", "snowy_taiga"),
("snowy_tundra", "snowy_plains"),
("stone_shore", "stony_shore"),
("swamp_hills", "swamp"),
("taiga_hills", "taiga"),
("taiga_mountains", "taiga"),
("tall_birch_forest", "old_growth_birch_forest"),
("tall_birch_hills", "old_growth_birch_forest"),
("wooded_badlands_plateau", "wooded_badlands"),
("wooded_hills", "forest"),
("wooded_mountains", "windswept_forest"),
// Remove Deep Warm Ocean
("deep_warm_ocean", "warm_ocean"),
];
/// Maps old numeric biome IDs to new string IDs
pub fn legacy_biome(index: u8) -> &'static str {
match index {
0 => "ocean",
1 => "plains",
2 => "desert",
3 => "mountains",
4 => "forest",
5 => "taiga",
6 => "swamp",
7 => "river",
8 => "nether_wastes",
9 => "the_end",
10 => "frozen_ocean",
11 => "frozen_river",
12 => "snowy_tundra",
13 => "snowy_mountains",
14 => "mushroom_fields",
15 => "mushroom_field_shore",
16 => "beach",
17 => "desert_hills",
18 => "wooded_hills",
19 => "taiga_hills",
20 => "mountain_edge",
21 => "jungle",
22 => "jungle_hills",
23 => "jungle_edge",
24 => "deep_ocean",
25 => "stone_shore",
26 => "snowy_beach",
27 => "birch_forest",
28 => "birch_forest_hills",
29 => "dark_forest",
30 => "snowy_taiga",
31 => "snowy_taiga_hills",
32 => "giant_tree_taiga",
33 => "giant_tree_taiga_hills",
34 => "wooded_mountains",
35 => "savanna",
36 => "savanna_plateau",
37 => "badlands",
38 => "wooded_badlands_plateau",
39 => "badlands_plateau",
40 => "small_end_islands",
41 => "end_midlands",
42 => "end_highlands",
43 => "end_barrens",
44 => "warm_ocean",
45 => "lukewarm_ocean",
46 => "cold_ocean",
47 => "deep_warm_ocean",
48 => "deep_lukewarm_ocean",
49 => "deep_cold_ocean",
50 => "deep_frozen_ocean",
127 => "the_void",
129 => "sunflower_plains",
130 => "desert_lakes",
131 => "gravelly_mountains",
132 => "flower_forest",
133 => "taiga_mountains",
134 => "swamp_hills",
140 => "ice_spikes",
149 => "modified_jungle",
151 => "modified_jungle_edge",
155 => "tall_birch_forest",
156 => "tall_birch_hills",
157 => "dark_forest_hills",
158 => "snowy_taiga_mountains",
160 => "giant_spruce_taiga",
161 => "giant_spruce_taiga_hills",
162 => "modified_gravelly_mountains",
163 => "shattered_savanna",
164 => "shattered_savanna_plateau",
165 => "eroded_badlands",
166 => "modified_wooded_badlands_plateau",
167 => "modified_badlands_plateau",
168 => "bamboo_jungle",
169 => "bamboo_jungle_hills",
170 => "soul_sand_valley",
171 => "crimson_forest",
172 => "warped_forest",
173 => "basalt_deltas",
174 => "dripstone_caves",
175 => "lush_caves",
177 => "meadow",
178 => "grove",
179 => "snowy_slopes",
180 => "snowcapped_peaks",
181 => "lofty_peaks",
182 => "stony_peaks",
_ => "ocean",
}
}

View file

@ -4,10 +4,9 @@
mod biomes;
mod block_color;
mod legacy_block_types;
#[allow(clippy::missing_docs_in_private_items)] // Generated module
mod block_types;
mod legacy_biomes;
mod legacy_block_types;
use std::collections::HashMap;
@ -135,9 +134,112 @@ impl BlockTypes {
}
}
pub use biomes::{Biome, BiomeGrassColorModifier};
pub use block_color::{block_color, needs_biome};
/// Grass color modifier used by a biome
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BiomeGrassColorModifier {
/// Grass color modifier used by the dark forest biome
DarkForest,
/// Grass color modifier used by swamp biomes
Swamp,
}
/// A biome specification
///
/// A Biome contains all information about a biome necessary to compute a block
/// color given a block type and depth
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Biome {
/// Temperature value
///
/// For more efficient storage, the temperature is stored as an integer
/// after mutiplying the raw value by 20
pub temp: i8,
/// Downfall value
///
/// For more efficient storage, the downfall is stored as an integer
/// after mutiplying the raw value by 20
pub downfall: i8,
/// Water color override
pub water_color: Option<Color>,
/// Foliage color override
pub foliage_color: Option<Color>,
/// Grass color override
pub grass_color: Option<Color>,
/// Grass color modifier
pub grass_color_modifier: Option<BiomeGrassColorModifier>,
}
impl Biome {
/// Constructs a new Biome
const fn new(temp: i16, downfall: i16) -> Biome {
/// Helper to encode temperature and downfall values
///
/// Converts temperatue and downfall from the input format
/// (mutiplied by 100) to i8 range for more efficient storage.
const fn encode(v: i16) -> i8 {
(v / 5) as i8
}
Biome {
temp: encode(temp),
downfall: encode(downfall),
grass_color_modifier: None,
water_color: None,
foliage_color: None,
grass_color: None,
}
}
/// Builder function to override the biome water color
const fn water(self, water_color: [u8; 3]) -> Biome {
Biome {
water_color: Some(Color(water_color)),
..self
}
}
/// Builder function to override the biome foliage color
const fn foliage(self, foliage_color: [u8; 3]) -> Biome {
Biome {
foliage_color: Some(Color(foliage_color)),
..self
}
}
/// Builder function to override the biome grass color
const fn grass(self, grass_color: [u8; 3]) -> Biome {
Biome {
grass_color: Some(Color(grass_color)),
..self
}
}
/// Builder function to set a grass color modifier
const fn modify(self, grass_color_modifier: BiomeGrassColorModifier) -> Biome {
Biome {
grass_color_modifier: Some(grass_color_modifier),
..self
}
}
/// Decodes a temperature or downfall value from the storage format to
/// f32 for further calculation
fn decode(val: i8) -> f32 {
f32::from(val) / 20.0
}
/// Returns the biome's temperature decoded to its original float value
pub fn temp(&self) -> f32 {
Self::decode(self.temp)
}
/// Returns the biome's downfall decoded to its original float value
pub fn downfall(&self) -> f32 {
Self::decode(self.downfall)
}
}
/// Used to look up standard Minecraft biome types
#[derive(Debug)]
pub struct BiomeTypes {
@ -154,7 +256,7 @@ impl Default for BiomeTypes {
.map(|(k, v)| (String::from(*k), v))
.collect();
for &(old, new) in biomes::BIOME_ALIASES.iter().rev() {
for &(old, new) in legacy_biomes::BIOME_ALIASES.iter().rev() {
let biome = biome_map
.get(new)
.copied()
@ -164,7 +266,7 @@ impl Default for BiomeTypes {
let legacy_biomes = (0..=255)
.map(|index| {
let id = biomes::legacy_biome(index);
let id = legacy_biomes::legacy_biome(index);
*biome_map.get(id).expect("Unknown legacy biome")
})
.collect::<Box<[_]>>()

View file

@ -11,13 +11,15 @@ work.
- `extract.py`: Takes the block type information from `blocks.json` and texture data
from an unpacked Minecraft JAR, storing the result in `colors.json`
- `generate.py`: Generates `block_types.rs` from `colors.json`
- `biomes.py`: Generates `biomes.rs` from biome JSON files of an unpacked
Minecraft JAR
- `sign_textures.py`: Generates all needed sign graphics from Minecraft assets
In addition to these scripts, the JSON processor *jq* is a useful tool to work
with MinedMap's resource metadata.
## How to add support for block IDs of a new Minecraft version
## How to add support for block IDs and biomes of a new Minecraft version
1. Download the Minecraft version you want to support as well as the previous
version currently supported by MinedMap. You can use the Minecraft launcher
@ -69,6 +71,17 @@ with MinedMap's resource metadata.
cargo fmt --all
```
8. Update the source code for new biome data:
```sh
./biomes.py data/new ../crates/resource/src/biomes.rs
cargo fmt --all
```
After regenerating, check if only new biomes were added. If entries
got removed, biomes may have been renamed or merged, requiring updates
to the alias list in `crates/resource/src/legacy_biomes.rs`.
After the update, the new version should be tested with old savegames (both
before and after migration by the new version) as well as newly generated
worlds. Use creative mode to add the new block types to your test world.

70
resource/biomes.py Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/env python3
import json
import os
import sys
if len(sys.argv) != 3:
sys.exit('Usage: biomes.py <data directory> <biomes.rs>')
biomes = {}
for file in os.scandir(os.path.join(sys.argv[1], 'data/minecraft/worldgen/biome')):
(name, ext) = os.path.splitext(file.name)
if ext != '.json':
continue
with open(file) as f:
data = json.load(f)
biomes[name] = {
'downfall': data['downfall'],
'temperature': data['temperature'],
'foliage_color': data['effects'].get('foliage_color'),
'grass_color': data['effects'].get('grass_color'),
'grass_color_modifier': data['effects'].get('grass_color_modifier'),
'water_color': data['effects'].get('water_color'),
}
def color(v):
return f'[{v>>16}, {(v>>8)&0xff}, {v&0xff}]'
# Converts the snake_case grass color modifier to CamelCase
def modify(v):
return ''.join([s.capitalize() for s in v.split('_')])
def gen_biome(name, info, f):
temp = round(100*info['temperature'])
downfall = round(100*info['downfall'])
foliage_color = info['foliage_color']
grass_color = info['grass_color']
grass_color_modifier = info['grass_color_modifier']
water_color = info['water_color']
print(f'\t("{name}", Biome::new({temp}, {downfall})', file=f)
if foliage_color is not None:
print(f'\t\t.foliage({color(foliage_color)})', file=f)
if grass_color is not None:
print(f'\t\t.grass({color(grass_color)})', file=f)
if grass_color_modifier is not None:
print(f'\t\t.modify({modify(grass_color_modifier)})', file=f)
if water_color is not None and water_color != 0x3f76e4:
print(f'\t\t.water({color(water_color)})', file=f)
print('\t),', file=f)
with open(sys.argv[2], 'w') as f:
print('//! Biome data', file=f);
print('//!', file=f);
print('//! This file is generated using resource/biomes.py, do not edit', file=f);
print('', file=f)
print('use super::*;', file=f)
print('use BiomeGrassColorModifier::*;', file=f)
print('', file=f)
print('/// List if known biomes and their properties', file=f);
print('pub const BIOMES: &[(&str, Biome)] = &[', file=f)
for name in sorted(biomes):
gen_biome(name, biomes[name], f)
print('];', file=f)

View file

@ -416,6 +416,7 @@
"chiseled_red_sandstone": {
"texture": "red_sandstone_top"
},
"chiseled_resin_bricks": {},
"chiseled_sandstone": {
"texture": "sandstone_top"
},
@ -427,6 +428,7 @@
"chorus_flower": {},
"chorus_plant": {},
"clay": {},
"closed_eyeblossom": null,
"coal_block": {},
"coal_ore": {},
"coarse_dirt": {},
@ -482,6 +484,9 @@
"crafting_table": {
"texture": "crafting_table_top"
},
"creaking_heart": {
"texture": "creaking_heart_top"
},
"creeper_head": null,
"creeper_wall_head": null,
"crimson_button": null,
@ -1269,6 +1274,7 @@
"ochre_froglight": {
"texture": "ochre_froglight_top"
},
"open_eyeblossom": null,
"orange_banner": null,
"orange_bed": null,
"orange_candle": null,
@ -1308,6 +1314,56 @@
},
"packed_ice": {},
"packed_mud": {},
"pale_hanging_moss": null,
"pale_moss_block": {},
"pale_moss_carpet": {},
"pale_oak_button": null,
"pale_oak_door": {
"texture": "pale_oak_door_top"
},
"pale_oak_fence": {
"texture": "pale_oak_planks"
},
"pale_oak_fence_gate": {
"texture": "pale_oak_planks"
},
"pale_oak_hanging_sign": {
"sign_material": "pale_oak",
"texture": null
},
"pale_oak_leaves": {},
"pale_oak_log": {
"texture": "pale_oak_log_top"
},
"pale_oak_planks": {},
"pale_oak_pressure_plate": {
"texture": "pale_oak_planks"
},
"pale_oak_sapling": {},
"pale_oak_sign": {
"sign_material": "pale_oak",
"texture": null
},
"pale_oak_slab": {
"texture": "pale_oak_planks"
},
"pale_oak_stairs": {
"texture": "pale_oak_planks"
},
"pale_oak_trapdoor": {},
"pale_oak_wall_hanging_sign": {
"sign_material": "pale_oak",
"texture": null,
"wall_sign": true
},
"pale_oak_wall_sign": {
"sign_material": "pale_oak",
"texture": null,
"wall_sign": true
},
"pale_oak_wood": {
"texture": "pale_oak_log"
},
"pearlescent_froglight": {
"texture": "pearlescent_froglight_top"
},
@ -1463,6 +1519,9 @@
"potted_cherry_sapling": {
"texture": "cherry_sapling"
},
"potted_closed_eyeblossom": {
"texture": "closed_eyeblossom"
},
"potted_cornflower": {
"texture": "cornflower"
},
@ -1500,12 +1559,18 @@
"potted_oak_sapling": {
"texture": "oak_sapling"
},
"potted_open_eyeblossom": {
"texture": "open_eyeblossom"
},
"potted_orange_tulip": {
"texture": "orange_tulip"
},
"potted_oxeye_daisy": {
"texture": "oxeye_daisy"
},
"potted_pale_oak_sapling": {
"texture": "pale_oak_sapling"
},
"potted_pink_tulip": {
"texture": "pink_tulip"
},
@ -1668,6 +1733,18 @@
"repeating_command_block": {
"texture": "repeating_command_block_front"
},
"resin_block": {},
"resin_brick_slab": {
"texture": "resin_bricks"
},
"resin_brick_stairs": {
"texture": "resin_bricks"
},
"resin_brick_wall": {
"texture": "resin_bricks"
},
"resin_bricks": {},
"resin_clump": null,
"respawn_anchor": {
"texture": "respawn_anchor_top"
},
@ -1903,6 +1980,12 @@
"stripped_oak_wood": {
"texture": "stripped_oak_log"
},
"stripped_pale_oak_log": {
"texture": "stripped_pale_oak_log_top"
},
"stripped_pale_oak_wood": {
"texture": "stripped_pale_oak_log"
},
"stripped_spruce_log": {
"texture": "stripped_spruce_log_top"
},

View file

@ -14,10 +14,15 @@ with open(sys.argv[1]) as f:
output = {}
with open(sys.argv[2], 'w') as f:
print('//! Block type information', file=f);
print('//!', file=f);
print('//! This file is generated using resource/generate.py, do not edit', file=f);
print('', file=f)
print('use enumflags2::make_bitflags;', file=f);
print('', file=f)
print('use super::*;', file=f)
print('', file=f)
print('/// List if known block types and their properties', file=f);
print('pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[', file=f)
for name, info in colors.items():

View file

@ -15,6 +15,7 @@ MATERIALS = [
'jungle',
'mangrove',
'oak',
'pale_oak',
'spruce',
'warped',
]

View file

@ -24,7 +24,7 @@ use crate::{
///
/// Increase when the generation of processed regions from region data changes
/// (usually because of updated resource data)
pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2);
pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3);
/// MinedMap map tile data version number
///
@ -36,7 +36,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0);
///
/// Increase when the generation of lightmap tiles from region data changes
/// (usually because of updated resource data)
pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2);
pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3);
/// MinedMap mipmap data version number
///

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B