2023-08-21 21:50:32 +02:00
|
|
|
#![doc = env!("CARGO_PKG_DESCRIPTION")]
|
|
|
|
#![warn(missing_docs)]
|
|
|
|
#![warn(clippy::missing_docs_in_private_items)]
|
2023-08-18 19:13:43 +02:00
|
|
|
|
2023-04-06 21:35:01 +02:00
|
|
|
mod biomes;
|
2023-05-04 20:53:06 +02:00
|
|
|
mod block_color;
|
2023-02-12 19:02:00 +01:00
|
|
|
mod legacy_block_types;
|
2023-02-07 22:09:14 +01:00
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
#[allow(clippy::missing_docs_in_private_items)] // Generated module
|
|
|
|
mod block_types;
|
|
|
|
|
2023-02-07 22:09:14 +01:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
use enumflags2::{bitflags, BitFlags};
|
2023-08-19 16:01:51 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-02-12 19:02:00 +01:00
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Flags describing special properties of [BlockType]s
|
2023-02-07 22:09:14 +01:00
|
|
|
#[bitflags]
|
|
|
|
#[repr(u8)]
|
2023-08-19 16:01:51 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
2023-02-13 00:11:36 +01:00
|
|
|
pub enum BlockFlag {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is opaque
|
2023-02-07 22:09:14 +01:00
|
|
|
Opaque,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is colored using biome grass colors
|
2023-02-07 22:09:14 +01:00
|
|
|
Grass,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is colored using biome foliage colors
|
2023-02-07 22:09:14 +01:00
|
|
|
Foliage,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is birch foliage
|
2023-02-07 22:09:14 +01:00
|
|
|
Birch,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is spurce foliage
|
2023-02-07 22:09:14 +01:00
|
|
|
Spruce,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// The block type is colored using biome water colors
|
2023-02-07 22:09:14 +01:00
|
|
|
Water,
|
|
|
|
}
|
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// An RGB color
|
2023-08-03 21:27:08 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2023-04-05 20:05:59 +02:00
|
|
|
pub struct Color(pub [u8; 3]);
|
2023-02-07 22:09:14 +01:00
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// A block type specification
|
2023-02-25 23:23:00 +01:00
|
|
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
2023-02-07 22:09:14 +01:00
|
|
|
pub struct BlockType {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Bit set of [BlockFlag]s describing special properties of the block type
|
2023-02-13 00:11:36 +01:00
|
|
|
pub flags: BitFlags<BlockFlag>,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Base color of the block type
|
2023-04-05 20:05:59 +02:00
|
|
|
pub color: Color,
|
2023-02-07 22:09:14 +01:00
|
|
|
}
|
|
|
|
|
2023-02-15 00:20:15 +01:00
|
|
|
impl BlockType {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Checks whether a block type has a given [BlockFlag] set
|
2023-08-20 16:28:10 +02:00
|
|
|
#[inline]
|
2023-02-15 00:20:15 +01:00
|
|
|
pub fn is(&self, flag: BlockFlag) -> bool {
|
|
|
|
self.flags.contains(flag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Used to look up standard Minecraft block types
|
2023-03-01 22:45:56 +01:00
|
|
|
#[derive(Debug)]
|
2023-03-02 00:03:39 +01:00
|
|
|
pub struct BlockTypes {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Map of string IDs to block types
|
2023-03-02 00:03:39 +01:00
|
|
|
block_type_map: HashMap<String, BlockType>,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Array used to look up old numeric block type and subtype values
|
2023-03-02 00:03:39 +01:00
|
|
|
legacy_block_types: Box<[[BlockType; 16]; 256]>,
|
|
|
|
}
|
2023-03-01 21:54:40 +01:00
|
|
|
|
2023-03-01 22:45:56 +01:00
|
|
|
impl Default for BlockTypes {
|
|
|
|
fn default() -> Self {
|
2023-03-02 00:03:39 +01:00
|
|
|
let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES
|
|
|
|
.iter()
|
|
|
|
.map(|(k, v)| (String::from(*k), *v))
|
|
|
|
.collect();
|
2023-03-02 00:41:39 +01:00
|
|
|
let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| {
|
|
|
|
inner.map(|id| *block_type_map.get(id).expect("Unknown legacy block type"))
|
2023-03-02 00:03:39 +01:00
|
|
|
}));
|
|
|
|
|
|
|
|
BlockTypes {
|
|
|
|
block_type_map,
|
|
|
|
legacy_block_types,
|
|
|
|
}
|
2023-03-01 22:45:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BlockTypes {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Resolves a Minecraft 1.13+ string block type ID
|
2023-03-01 21:54:40 +01:00
|
|
|
#[inline]
|
|
|
|
pub fn get(&self, id: &str) -> Option<BlockType> {
|
2023-03-01 21:58:43 +01:00
|
|
|
let suffix = id.strip_prefix("minecraft:")?;
|
2023-03-02 00:03:39 +01:00
|
|
|
self.block_type_map.get(suffix).copied()
|
|
|
|
}
|
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Resolves a Minecraft pre-1.13 numeric block type ID
|
2023-03-02 00:03:39 +01:00
|
|
|
#[inline]
|
|
|
|
pub fn get_legacy(&self, id: u8, data: u8) -> Option<BlockType> {
|
|
|
|
Some(self.legacy_block_types[id as usize][data as usize])
|
2023-03-01 21:54:40 +01:00
|
|
|
}
|
|
|
|
}
|
2023-04-06 21:35:01 +02:00
|
|
|
|
2023-05-04 22:08:33 +02:00
|
|
|
pub use biomes::{Biome, BiomeGrassColorModifier};
|
2023-08-03 18:28:57 +02:00
|
|
|
pub use block_color::{block_color, needs_biome};
|
2023-04-06 21:35:01 +02:00
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Used to look up standard Minecraft biome types
|
2023-04-06 21:35:01 +02:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct BiomeTypes {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Map of string IDs to biome types
|
2023-04-06 21:35:01 +02:00
|
|
|
biome_map: HashMap<String, &'static Biome>,
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Array used to look up old numeric biome IDs
|
2023-04-06 21:35:01 +02:00
|
|
|
legacy_biomes: Box<[&'static Biome; 256]>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for BiomeTypes {
|
|
|
|
fn default() -> Self {
|
|
|
|
let mut biome_map: HashMap<_, _> = biomes::BIOMES
|
|
|
|
.iter()
|
|
|
|
.map(|(k, v)| (String::from(*k), v))
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
for &(old, new) in biomes::BIOME_ALIASES.iter().rev() {
|
|
|
|
let biome = biome_map
|
|
|
|
.get(new)
|
|
|
|
.copied()
|
|
|
|
.expect("Biome alias for unknown biome");
|
|
|
|
assert!(biome_map.insert(String::from(old), biome).is_none());
|
|
|
|
}
|
|
|
|
|
|
|
|
let legacy_biomes = (0..=255)
|
|
|
|
.map(|index| {
|
|
|
|
let id = biomes::legacy_biome(index);
|
|
|
|
*biome_map.get(id).expect("Unknown legacy biome")
|
|
|
|
})
|
|
|
|
.collect::<Box<[_]>>()
|
|
|
|
.try_into()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
Self {
|
|
|
|
biome_map,
|
|
|
|
legacy_biomes,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BiomeTypes {
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Resolves a Minecraft 1.18+ string biome type ID
|
2023-04-06 21:35:01 +02:00
|
|
|
#[inline]
|
|
|
|
pub fn get(&self, id: &str) -> Option<&Biome> {
|
|
|
|
let suffix = id.strip_prefix("minecraft:")?;
|
|
|
|
self.biome_map.get(suffix).copied()
|
|
|
|
}
|
|
|
|
|
2023-08-18 19:13:43 +02:00
|
|
|
/// Resolves a Minecraft pre-1.18 numeric biome type ID
|
2023-04-06 21:35:01 +02:00
|
|
|
#[inline]
|
|
|
|
pub fn get_legacy(&self, id: u8) -> Option<&Biome> {
|
|
|
|
Some(self.legacy_biomes[id as usize])
|
|
|
|
}
|
|
|
|
}
|