use crate::block::blocks::fire::FireBlockBase; use crate::block::blocks::fire::fire::FireBlock; use crate::entity::player::Player; use crate::server::Server; use crate::world::World; use pumpkin_data::fluid::Fluid; use pumpkin_data::{Block, BlockDirection}; use pumpkin_util::math::position::BlockPos; use std::sync::Arc; pub struct Ignition; impl Ignition { pub async fn ignite_block( ignite_logic: F, player: &Player, location: BlockPos, face: BlockDirection, block: &Block, _server: &Server, ) where F: FnOnce(Arc, BlockPos, u16) -> Fut, Fut: Future, { let world = player.world(); let pos = location.offset(face.to_offset()); if world.get_fluid(&location).await.name != Fluid::EMPTY.name { return; } let fire_block = FireBlockBase::get_fire_type(world, &pos).await; let state_id = world.get_block_state_id(&location).await; if let Some(new_state_id) = can_be_lit(block, state_id) { ignite_logic(world.clone(), location, new_state_id).await; return; } let state_id = FireBlock .get_state_for_position(world, &fire_block, &pos) .await; if FireBlockBase::can_place_at(world, &pos).await { ignite_logic(world.clone(), pos, state_id).await; } } } fn can_be_lit(block: &Block, state_id: u16) -> Option { let mut props = match &block.properties(state_id) { Some(props) => props.to_props(), None => return None, }; if let Some((_, value)) = props.iter_mut().find(|(k, _)| *k == "extinguished") { *value = "false"; } else if let Some((_, value)) = props.iter_mut().find(|(k, _)| *k == "lit") { *value = "true"; } else { return None; } let new_state_id = block.from_properties(&props).to_state_id(block); (new_state_id != state_id).then_some(new_state_id) }