67 lines
2.0 KiB
Rust
67 lines
2.0 KiB
Rust
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<F, Fut>(
|
|
ignite_logic: F,
|
|
player: &Player,
|
|
location: BlockPos,
|
|
face: BlockDirection,
|
|
block: &Block,
|
|
_server: &Server,
|
|
) where
|
|
F: FnOnce(Arc<World>, BlockPos, u16) -> Fut,
|
|
Fut: Future<Output = ()>,
|
|
{
|
|
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<u16> {
|
|
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)
|
|
}
|