diff --git a/pumpkin-world/src/block/block_registry.rs b/pumpkin-world/src/block/block_registry.rs index 816f70a6d..1759c1ee4 100644 --- a/pumpkin-world/src/block/block_registry.rs +++ b/pumpkin-world/src/block/block_registry.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::sync::LazyLock; use serde::Deserialize; @@ -7,15 +8,57 @@ pub static BLOCKS: LazyLock = LazyLock::new(|| { .expect("Could not parse blocks.json registry.") }); +pub static BLOCKS_BY_ID: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + for block in &BLOCKS.blocks { + map.insert(block.id, block.clone()); + } + map +}); + +pub static BLOCK_ID_BY_REGISTRY_ID: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + for block in &BLOCKS.blocks { + map.insert(block.name.clone(), block.id); + } + map +}); + +pub static BLOCK_ID_BY_STATE_ID: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + for block in &BLOCKS.blocks { + for state in &block.states { + map.insert(state.id, block.id); + } + } + map +}); + +pub static STATE_INDEX_BY_STATE_ID: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + for block in &BLOCKS.blocks { + for (index, state) in block.states.iter().enumerate() { + map.insert(state.id, index as u16); + } + } + map +}); + +pub static BLOCK_ID_BY_ITEM_ID: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + for block in &BLOCKS.blocks { + map.insert(block.item_id, block.id); + } + map +}); + pub fn get_block(registry_id: &str) -> Option<&Block> { - BLOCKS - .blocks - .iter() - .find(|&block| block.name == registry_id) + let id = BLOCK_ID_BY_REGISTRY_ID.get(registry_id)?; + BLOCKS_BY_ID.get(id) } pub fn get_block_by_id<'a>(id: u16) -> Option<&'a Block> { - BLOCKS.blocks.iter().find(|&block| block.id == id) + BLOCKS_BY_ID.get(&id) } pub fn get_state_by_state_id<'a>(id: u16) -> Option<&'a State> { @@ -23,23 +66,21 @@ pub fn get_state_by_state_id<'a>(id: u16) -> Option<&'a State> { } pub fn get_block_by_state_id<'a>(id: u16) -> Option<&'a Block> { - get_block_and_state_by_state_id(id).map(|(block, _)| block) + let block_id = BLOCK_ID_BY_STATE_ID.get(&id)?; + BLOCKS_BY_ID.get(block_id) } pub fn get_block_and_state_by_state_id<'a>(id: u16) -> Option<(&'a Block, &'a State)> { - for block in &BLOCKS.blocks { - for state in &block.states { - if state.id == id { - return Some((block, state)); - } - } - } - - None + let block_id = BLOCK_ID_BY_STATE_ID.get(&id)?; + let block = BLOCKS_BY_ID.get(block_id)?; + let state_index = STATE_INDEX_BY_STATE_ID.get(&id)?; + let state = block.states.get(*state_index as usize)?; + Some((block, state)) } pub fn get_block_by_item<'a>(item_id: u16) -> Option<&'a Block> { - BLOCKS.blocks.iter().find(|&block| block.item_id == item_id) + let block_id = BLOCK_ID_BY_ITEM_ID.get(&item_id)?; + BLOCKS_BY_ID.get(block_id) } #[expect(dead_code)] #[derive(Deserialize, Clone, Debug)]