mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Custom difficulty serialization and can_place_at with block face (#775)
This commit is contained in:
committed by
GitHub
parent
999f27721e
commit
2123aaf095
@@ -10,7 +10,7 @@ serde_json.workspace = true
|
||||
bytes.workspace = true
|
||||
rand = "0.9"
|
||||
|
||||
|
||||
num-derive = "0.4"
|
||||
num-traits = "0.2"
|
||||
|
||||
colored = "3.0"
|
||||
@@ -19,4 +19,3 @@ quote = "1.0"
|
||||
syn = "2.0"
|
||||
proc-macro2 = "1.0"
|
||||
enum_dispatch = "0.3.13"
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
pub use gamemode::GameMode;
|
||||
pub use permission::PermissionLvl;
|
||||
|
||||
pub mod biome;
|
||||
pub mod gamemode;
|
||||
pub mod loot_table;
|
||||
@@ -6,16 +13,10 @@ pub mod noise;
|
||||
pub mod permission;
|
||||
pub mod random;
|
||||
pub mod registry;
|
||||
pub mod serde_enum_as_integer;
|
||||
pub mod text;
|
||||
pub mod translation;
|
||||
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
pub use gamemode::GameMode;
|
||||
pub use permission::PermissionLvl;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! global_path {
|
||||
($path:expr) => {{
|
||||
@@ -50,7 +51,7 @@ pub fn encompassing_bits(count: usize) -> u8 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Serialize, Deserialize, Clone)]
|
||||
#[derive(Serialize, Deserialize, FromPrimitive, ToPrimitive, PartialEq, Clone, Debug)]
|
||||
pub enum Difficulty {
|
||||
Peaceful,
|
||||
Easy,
|
||||
|
||||
22
pumpkin-util/src/serde_enum_as_integer.rs
Normal file
22
pumpkin-util/src/serde_enum_as_integer.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub fn serialize<S, V>(value: &V, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
V: ToPrimitive,
|
||||
{
|
||||
let value = value
|
||||
.to_i8()
|
||||
.ok_or_else(|| serde::ser::Error::custom("Invalid enum value"))?;
|
||||
value.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D, V>(deserializer: D) -> Result<V, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
V: FromPrimitive,
|
||||
{
|
||||
let value = Deserialize::deserialize(deserializer)?;
|
||||
V::from_i8(value).ok_or_else(|| serde::de::Error::custom("Invalid enum value"))
|
||||
}
|
||||
@@ -117,6 +117,7 @@ mod test {
|
||||
|
||||
use flate2::read::GzDecoder;
|
||||
use pumpkin_nbt::{deserializer::from_bytes, serializer::to_bytes};
|
||||
use pumpkin_util::Difficulty;
|
||||
use temp_dir::TempDir;
|
||||
|
||||
use crate::{
|
||||
@@ -172,7 +173,7 @@ mod test {
|
||||
},
|
||||
data_version: 4189,
|
||||
day_time: 1727,
|
||||
difficulty: 2,
|
||||
difficulty: Difficulty::Normal,
|
||||
difficulty_locked: false,
|
||||
world_gen_settings: WorldGenSettings { seed: 1 },
|
||||
last_played: 1733847709327,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use pumpkin_config::BASIC_CONFIG;
|
||||
use pumpkin_util::Difficulty;
|
||||
use pumpkin_util::{Difficulty, serde_enum_as_integer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -59,7 +59,8 @@ pub struct LevelData {
|
||||
// The time of day. 0 is sunrise, 6000 is mid day, 12000 is sunset, 18000 is mid night, 24000 is the next day's 0. This value keeps counting past 24000 and does not reset to 0.
|
||||
pub day_time: i64,
|
||||
// The current difficulty setting.
|
||||
pub difficulty: i8,
|
||||
#[serde(with = "serde_enum_as_integer")]
|
||||
pub difficulty: Difficulty,
|
||||
// 1 or 0 (true/false) - True if the difficulty has been locked. Defaults to 0.
|
||||
pub difficulty_locked: bool,
|
||||
// TODO: DimensionData
|
||||
@@ -158,7 +159,7 @@ impl Default for LevelData {
|
||||
},
|
||||
data_version: MAXIMUM_SUPPORTED_WORLD_DATA_VERSION,
|
||||
day_time: 0,
|
||||
difficulty: Difficulty::Normal as i8,
|
||||
difficulty: Difficulty::Normal,
|
||||
difficulty_locked: false,
|
||||
world_gen_settings: Default::default(),
|
||||
last_played: -1,
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct CactusBlock;
|
||||
#[async_trait]
|
||||
impl PumpkinBlock for CactusBlock {
|
||||
async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
world.break_block(pos, None, BlockFlags::empty()).await;
|
||||
}
|
||||
}
|
||||
@@ -62,11 +62,11 @@ impl PumpkinBlock for CactusBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
pos: &BlockPos,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
world
|
||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
||||
.await;
|
||||
@@ -74,7 +74,7 @@ impl PumpkinBlock for CactusBlock {
|
||||
state
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
// TODO: use tags
|
||||
// Disallow to place any blocks nearby a cactus
|
||||
for direction in BlockDirection::horizontal() {
|
||||
|
||||
@@ -32,13 +32,13 @@ impl PumpkinBlock for DirtPathBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
_replacing: BlockIsReplacing,
|
||||
) -> BlockStateId {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
return Block::DIRT.default_state_id;
|
||||
}
|
||||
block.default_state_id
|
||||
@@ -50,11 +50,13 @@ impl PumpkinBlock for DirtPathBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
if direction == &BlockDirection::Up && !self.can_place_at(world, pos).await {
|
||||
if direction == BlockDirection::Up
|
||||
&& !self.can_place_at(world, pos, BlockDirection::Down).await
|
||||
{
|
||||
world
|
||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
||||
.await;
|
||||
@@ -62,7 +64,7 @@ impl PumpkinBlock for DirtPathBlock {
|
||||
state
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
let state = world.get_block_state(&pos.up()).await.unwrap();
|
||||
!state.is_solid() // TODO: add fence gata block
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ impl PumpkinBlock for DoorBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -190,8 +190,13 @@ impl PumpkinBlock for DoorBlock {
|
||||
door_props.to_state_id(block)
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, block_pos: &BlockPos) -> bool {
|
||||
if world
|
||||
async fn can_place_at(
|
||||
&self,
|
||||
world: &World,
|
||||
block_pos: &BlockPos,
|
||||
_face: BlockDirection,
|
||||
) -> bool {
|
||||
world
|
||||
.get_block_state(&block_pos.offset(BlockDirection::Up.to_offset()))
|
||||
.await
|
||||
.is_ok_and(|state| state.replaceable())
|
||||
@@ -199,10 +204,6 @@ impl PumpkinBlock for DoorBlock {
|
||||
.get_block_state(&block_pos.offset(BlockDirection::Down.to_offset()))
|
||||
.await
|
||||
.is_ok_and(|state| state.is_solid() && state.is_full_cube())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
async fn placed(
|
||||
@@ -317,17 +318,17 @@ impl PumpkinBlock for DoorBlock {
|
||||
block: &Block,
|
||||
state: u16,
|
||||
block_pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
neighbor_state: u16,
|
||||
) -> u16 {
|
||||
let lv = DoorProperties::from_state_id(state, block).half;
|
||||
if direction.to_axis() != Axis::Y
|
||||
|| (lv == DoubleBlockHalf::Lower) != (direction == &BlockDirection::Up)
|
||||
|| (lv == DoubleBlockHalf::Lower) != (direction == BlockDirection::Up)
|
||||
{
|
||||
if lv == DoubleBlockHalf::Lower
|
||||
&& direction == &BlockDirection::Down
|
||||
&& !self.can_place_at(world, block_pos).await
|
||||
&& direction == BlockDirection::Down
|
||||
&& !self.can_place_at(world, block_pos, direction).await
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -32,13 +32,13 @@ impl PumpkinBlock for FarmLandBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player_direction: &Player,
|
||||
_replacing: BlockIsReplacing,
|
||||
) -> BlockStateId {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, face).await {
|
||||
return Block::DIRT.default_state_id;
|
||||
}
|
||||
block.default_state_id
|
||||
@@ -50,11 +50,13 @@ impl PumpkinBlock for FarmLandBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
if direction == &BlockDirection::Up && !self.can_place_at(world, pos).await {
|
||||
if direction == BlockDirection::Up
|
||||
&& !self.can_place_at(world, pos, BlockDirection::Down).await
|
||||
{
|
||||
world
|
||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
||||
.await;
|
||||
@@ -62,7 +64,7 @@ impl PumpkinBlock for FarmLandBlock {
|
||||
state
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
let state = world.get_block_state(&pos.up()).await.unwrap();
|
||||
!state.is_solid() // TODO: add fence gata block
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ impl PumpkinBlock for FenceGateBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
|
||||
@@ -83,7 +83,7 @@ impl PumpkinBlock for FenceBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
@@ -98,7 +98,7 @@ impl PumpkinBlock for FenceBlock {
|
||||
block: &Block,
|
||||
_state: BlockStateId,
|
||||
block_pos: &BlockPos,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
|
||||
@@ -33,7 +33,7 @@ impl PumpkinBlock for LogBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
|
||||
@@ -65,7 +65,7 @@ impl PumpkinBlock for ButtonBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -79,7 +79,7 @@ impl PumpkinBlock for ButtonBlock {
|
||||
_ => props.face = BlockFace::Wall,
|
||||
}
|
||||
|
||||
if face == &BlockDirection::Up || face == &BlockDirection::Down {
|
||||
if face == BlockDirection::Up || face == BlockDirection::Down {
|
||||
props.facing = player.living_entity.entity.get_horizontal_facing();
|
||||
} else {
|
||||
props.facing = face.opposite().to_cardinal_direction();
|
||||
@@ -126,7 +126,7 @@ impl PumpkinBlock for ButtonBlock {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
@@ -137,7 +137,7 @@ impl PumpkinBlock for ButtonBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let button_props = ButtonLikeProperties::from_state_id(state.id, block);
|
||||
if button_props.powered { 15 } else { 0 }
|
||||
@@ -149,10 +149,10 @@ impl PumpkinBlock for ButtonBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let button_props = ButtonLikeProperties::from_state_id(state.id, block);
|
||||
if button_props.powered && button_props.get_direction() == *direction {
|
||||
if button_props.powered && button_props.get_direction() == direction {
|
||||
15
|
||||
} else {
|
||||
0
|
||||
|
||||
@@ -46,7 +46,7 @@ impl PumpkinBlock for LeverBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -60,7 +60,7 @@ impl PumpkinBlock for LeverBlock {
|
||||
_ => lever_props.face = BlockFace::Wall,
|
||||
}
|
||||
|
||||
if face == &BlockDirection::Up || face == &BlockDirection::Down {
|
||||
if face == BlockDirection::Up || face == BlockDirection::Down {
|
||||
lever_props.facing = player.living_entity.entity.get_horizontal_facing();
|
||||
} else {
|
||||
lever_props.facing = face.opposite().to_cardinal_direction();
|
||||
@@ -97,7 +97,7 @@ impl PumpkinBlock for LeverBlock {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
@@ -108,7 +108,7 @@ impl PumpkinBlock for LeverBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let lever_props = LeverLikeProperties::from_state_id(state.id, block);
|
||||
if lever_props.powered { 15 } else { 0 }
|
||||
@@ -120,10 +120,10 @@ impl PumpkinBlock for LeverBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let lever_props = LeverLikeProperties::from_state_id(state.id, block);
|
||||
if lever_props.powered && &lever_props.get_direction() == direction {
|
||||
if lever_props.powered && lever_props.get_direction() == direction {
|
||||
15
|
||||
} else {
|
||||
0
|
||||
|
||||
@@ -24,14 +24,15 @@ pub(crate) mod target_block;
|
||||
pub(crate) mod turbo;
|
||||
|
||||
pub async fn update_wire_neighbors(world: &Arc<World>, pos: &BlockPos) {
|
||||
for direction in &BlockDirection::all() {
|
||||
for direction in BlockDirection::all() {
|
||||
let neighbor_pos = pos.offset(direction.to_offset());
|
||||
let block = world.get_block(&neighbor_pos).await.unwrap();
|
||||
world
|
||||
.block_registry
|
||||
.on_neighbor_update(world, &block, &neighbor_pos, &block, true)
|
||||
.await;
|
||||
for n_direction in &BlockDirection::all() {
|
||||
|
||||
for n_direction in BlockDirection::all() {
|
||||
let n_neighbor_pos = neighbor_pos.offset(n_direction.to_offset());
|
||||
let block = world.get_block(&n_neighbor_pos).await.unwrap();
|
||||
world
|
||||
@@ -47,7 +48,7 @@ pub async fn get_redstone_power(
|
||||
state: &BlockState,
|
||||
world: &World,
|
||||
pos: BlockPos,
|
||||
facing: &BlockDirection,
|
||||
facing: BlockDirection,
|
||||
) -> u8 {
|
||||
if state.is_solid() {
|
||||
return std::cmp::max(
|
||||
@@ -63,7 +64,7 @@ async fn get_redstone_power_no_dust(
|
||||
state: &BlockState,
|
||||
world: &World,
|
||||
pos: BlockPos,
|
||||
facing: &BlockDirection,
|
||||
facing: BlockDirection,
|
||||
) -> u8 {
|
||||
if state.is_solid() {
|
||||
return std::cmp::max(
|
||||
@@ -76,7 +77,7 @@ async fn get_redstone_power_no_dust(
|
||||
|
||||
async fn get_max_strong_power(world: &World, pos: &BlockPos, dust_power: bool) -> u8 {
|
||||
let mut max_power = 0;
|
||||
for side in &BlockDirection::all() {
|
||||
for side in BlockDirection::all() {
|
||||
let (block, state) = world
|
||||
.get_block_and_block_state(&pos.offset(side.to_offset()))
|
||||
.await
|
||||
@@ -98,7 +99,7 @@ async fn get_max_strong_power(world: &World, pos: &BlockPos, dust_power: bool) -
|
||||
|
||||
async fn get_max_weak_power(world: &World, pos: &BlockPos, dust_power: bool) -> u8 {
|
||||
let mut max_power = 0;
|
||||
for side in &BlockDirection::all() {
|
||||
for side in BlockDirection::all() {
|
||||
let (block, state) = world
|
||||
.get_block_and_block_state(&pos.offset(side.to_offset()))
|
||||
.await
|
||||
@@ -123,7 +124,7 @@ async fn get_weak_power(
|
||||
state: &BlockState,
|
||||
world: &World,
|
||||
pos: &BlockPos,
|
||||
side: &BlockDirection,
|
||||
side: BlockDirection,
|
||||
dust_power: bool,
|
||||
) -> u8 {
|
||||
if !dust_power && block == &Block::REDSTONE_WIRE {
|
||||
@@ -140,7 +141,7 @@ async fn get_strong_power(
|
||||
state: &BlockState,
|
||||
world: &World,
|
||||
pos: &BlockPos,
|
||||
side: &BlockDirection,
|
||||
side: BlockDirection,
|
||||
dust_power: bool,
|
||||
) -> u8 {
|
||||
if !dust_power && block == &Block::REDSTONE_WIRE {
|
||||
@@ -153,7 +154,7 @@ async fn get_strong_power(
|
||||
}
|
||||
|
||||
pub async fn block_receives_redstone_power(world: &World, pos: &BlockPos) -> bool {
|
||||
for face in &BlockDirection::all() {
|
||||
for face in BlockDirection::all() {
|
||||
let neighbor_pos = pos.offset(face.to_offset());
|
||||
let (block, state) = world
|
||||
.get_block_and_block_state(&neighbor_pos)
|
||||
@@ -170,11 +171,7 @@ pub fn is_diode(block: &Block) -> bool {
|
||||
block == &Block::REPEATER || block == &Block::COMPARATOR
|
||||
}
|
||||
|
||||
pub async fn diode_get_input_strength(
|
||||
world: &World,
|
||||
pos: &BlockPos,
|
||||
facing: &BlockDirection,
|
||||
) -> u8 {
|
||||
pub async fn diode_get_input_strength(world: &World, pos: &BlockPos, facing: BlockDirection) -> u8 {
|
||||
let input_pos = pos.offset(facing.to_offset());
|
||||
let (input_block, input_state) = world.get_block_and_block_state(&input_pos).await.unwrap();
|
||||
let power: u8 = get_redstone_power(&input_block, &input_state, world, input_pos, facing).await;
|
||||
|
||||
@@ -31,7 +31,7 @@ impl PumpkinBlock for ObserverBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -88,13 +88,13 @@ impl PumpkinBlock for ObserverBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
block_pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
let props = ObserverLikeProperties::from_state_id(state, block);
|
||||
|
||||
if &props.facing.to_block_direction() == direction && !props.powered {
|
||||
if props.facing.to_block_direction() == direction && !props.powered {
|
||||
Self::schedule_tick(world, block_pos).await;
|
||||
}
|
||||
|
||||
@@ -105,10 +105,10 @@ impl PumpkinBlock for ObserverBlock {
|
||||
&self,
|
||||
block: &Block,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> bool {
|
||||
let props = ObserverLikeProperties::from_state_id(state.id, block);
|
||||
&props.facing.to_block_direction() == direction
|
||||
props.facing.to_block_direction() == direction
|
||||
}
|
||||
|
||||
async fn get_weak_redstone_power(
|
||||
@@ -117,10 +117,10 @@ impl PumpkinBlock for ObserverBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let props = ObserverLikeProperties::from_state_id(state.id, block);
|
||||
if &props.facing.to_block_direction() == direction && props.powered {
|
||||
if props.facing.to_block_direction() == direction && props.powered {
|
||||
15
|
||||
} else {
|
||||
0
|
||||
@@ -133,7 +133,7 @@ impl PumpkinBlock for ObserverBlock {
|
||||
world: &World,
|
||||
block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
self.get_weak_redstone_power(block, world, block_pos, state, direction)
|
||||
.await
|
||||
@@ -172,7 +172,7 @@ impl ObserverBlock {
|
||||
block_pos.offset(facing.to_block_direction().opposite().to_offset());
|
||||
world.update_neighbor(&opposite_facing_pos, block).await;
|
||||
world
|
||||
.update_neighbors(&opposite_facing_pos, Some(&facing.to_block_direction()))
|
||||
.update_neighbors(&opposite_facing_pos, Some(facing.to_block_direction()))
|
||||
.await;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ impl PumpkinBlock for PistonBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
|
||||
@@ -30,7 +30,7 @@ impl PumpkinBlock for ActivatorRailBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -73,7 +73,7 @@ impl PumpkinBlock for ActivatorRailBlock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
can_place_rail_at(world, pos).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ impl PumpkinBlock for DetectorRailBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -73,7 +73,7 @@ impl PumpkinBlock for DetectorRailBlock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
can_place_rail_at(world, pos).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ impl PumpkinBlock for PoweredRailBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -73,7 +73,7 @@ impl PumpkinBlock for PoweredRailBlock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
can_place_rail_at(world, pos).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ impl PumpkinBlock for RailBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -145,7 +145,7 @@ impl PumpkinBlock for RailBlock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
can_place_rail_at(world, pos).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ impl PumpkinBlock for RedstoneBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> u8 {
|
||||
15
|
||||
}
|
||||
@@ -26,7 +26,7 @@ impl PumpkinBlock for RedstoneBlock {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ impl PumpkinBlock for RedstoneLamp {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
|
||||
@@ -42,7 +42,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
_block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
@@ -55,7 +55,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
return torch_props.to_state_id(&Block::REDSTONE_WALL_TORCH);
|
||||
}
|
||||
let mut torch_props = RTorchProps::default(&Block::REDSTONE_TORCH);
|
||||
torch_props.lit = should_be_lit(world, block_pos, &BlockDirection::Down).await;
|
||||
torch_props.lit = should_be_lit(world, block_pos, BlockDirection::Down).await;
|
||||
return torch_props.to_state_id(&Block::REDSTONE_TORCH);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
!= should_be_lit(
|
||||
world,
|
||||
block_pos,
|
||||
&props.facing.to_block_direction().opposite(),
|
||||
props.facing.to_block_direction().opposite(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -89,7 +89,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
}
|
||||
} else if block == &Block::REDSTONE_TORCH {
|
||||
let props = RTorchProps::from_state_id(state.id, block);
|
||||
if props.lit != should_be_lit(world, block_pos, &BlockDirection::Down).await {
|
||||
if props.lit != should_be_lit(world, block_pos, BlockDirection::Down).await {
|
||||
world
|
||||
.schedule_block_tick(block, *block_pos, 2, TickPriority::Normal)
|
||||
.await;
|
||||
@@ -101,7 +101,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
@@ -112,16 +112,16 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
if block == &Block::REDSTONE_WALL_TORCH {
|
||||
let props = RWallTorchProps::from_state_id(state.id, block);
|
||||
if props.lit && direction != &props.facing.to_block_direction() {
|
||||
if props.lit && direction != props.facing.to_block_direction() {
|
||||
return 15;
|
||||
}
|
||||
} else if block == &Block::REDSTONE_TORCH {
|
||||
let props = RTorchProps::from_state_id(state.id, block);
|
||||
if props.lit && direction != &BlockDirection::Up {
|
||||
if props.lit && direction != BlockDirection::Up {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
@@ -134,9 +134,9 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
if direction == &BlockDirection::Down {
|
||||
if direction == BlockDirection::Down {
|
||||
if block == &Block::REDSTONE_WALL_TORCH {
|
||||
let props = RWallTorchProps::from_state_id(state.id, block);
|
||||
if props.lit {
|
||||
@@ -159,7 +159,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
let should_be_lit_now = should_be_lit(
|
||||
world,
|
||||
block_pos,
|
||||
&props.facing.to_block_direction().opposite(),
|
||||
props.facing.to_block_direction().opposite(),
|
||||
)
|
||||
.await;
|
||||
if props.lit != should_be_lit_now {
|
||||
@@ -171,7 +171,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
}
|
||||
} else if block == &Block::REDSTONE_TORCH {
|
||||
let mut props = RTorchProps::from_state_id(state.id, block);
|
||||
let should_be_lit_now = should_be_lit(world, block_pos, &BlockDirection::Down).await;
|
||||
let should_be_lit_now = should_be_lit(world, block_pos, BlockDirection::Down).await;
|
||||
if props.lit != should_be_lit_now {
|
||||
props.lit = should_be_lit_now;
|
||||
world
|
||||
@@ -206,7 +206,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn should_be_lit(world: &World, pos: &BlockPos, face: &BlockDirection) -> bool {
|
||||
pub async fn should_be_lit(world: &World, pos: &BlockPos, face: BlockDirection) -> bool {
|
||||
let other_pos = pos.offset(face.to_offset());
|
||||
let (block, state) = world.get_block_and_block_state(&other_pos).await.unwrap();
|
||||
get_redstone_power(&block, &state, world, other_pos, face).await == 0
|
||||
|
||||
@@ -32,7 +32,12 @@ pub struct RedstoneWireBlock;
|
||||
impl PumpkinBlock for RedstoneWireBlock {
|
||||
// Start of placement
|
||||
|
||||
async fn can_place_at(&self, world: &World, block_pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(
|
||||
&self,
|
||||
world: &World,
|
||||
block_pos: &BlockPos,
|
||||
_face: BlockDirection,
|
||||
) -> bool {
|
||||
let floor = world.get_block_state(&block_pos.down()).await.unwrap();
|
||||
// TODO: Only check face instead of block
|
||||
return floor.is_full_cube();
|
||||
@@ -43,7 +48,7 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
@@ -65,7 +70,7 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
block_pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
@@ -136,7 +141,7 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
world
|
||||
.replace_with_state_for_neighbor_update(
|
||||
&up_block_pos,
|
||||
&direction.opposite(),
|
||||
direction.opposite(),
|
||||
flags,
|
||||
)
|
||||
.await;
|
||||
@@ -148,7 +153,7 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
world
|
||||
.replace_with_state_for_neighbor_update(
|
||||
&down_block_pos,
|
||||
&direction.opposite(),
|
||||
direction.opposite(),
|
||||
flags,
|
||||
)
|
||||
.await;
|
||||
@@ -196,7 +201,7 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
_source_block: &Block,
|
||||
_notify: bool,
|
||||
) {
|
||||
if self.can_place_at(world, pos).await {
|
||||
if self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
let state = world.get_block_state(pos).await.unwrap();
|
||||
let mut wire = RedstoneWireProperties::from_state_id(state.id, block);
|
||||
let new_power = calculate_power(world, pos).await;
|
||||
@@ -222,10 +227,10 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let wire = RedstoneWireProperties::from_state_id(state.id, block);
|
||||
if direction == &BlockDirection::Up || wire.is_side_connected(direction.opposite()) {
|
||||
if direction == BlockDirection::Up || wire.is_side_connected(direction.opposite()) {
|
||||
wire.power.to_index() as u8
|
||||
} else {
|
||||
0
|
||||
@@ -238,10 +243,10 @@ impl PumpkinBlock for RedstoneWireBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let wire = RedstoneWireProperties::from_state_id(state.id, block);
|
||||
if direction == &BlockDirection::Up || wire.is_side_connected(direction.opposite()) {
|
||||
if direction == BlockDirection::Up || wire.is_side_connected(direction.opposite()) {
|
||||
wire.power.to_index() as u8
|
||||
} else {
|
||||
0
|
||||
@@ -316,7 +321,7 @@ async fn can_connect_to(
|
||||
) -> bool {
|
||||
if world
|
||||
.block_registry
|
||||
.emits_redstone_power(block, state, &side)
|
||||
.emits_redstone_power(block, state, side)
|
||||
.await
|
||||
{
|
||||
return true;
|
||||
@@ -586,7 +591,7 @@ async fn calculate_power(world: &World, pos: &BlockPos) -> u8 {
|
||||
let up_pos = pos.offset(BlockDirection::Up.to_offset());
|
||||
let (_up_block, up_state) = world.get_block_and_block_state(&up_pos).await.unwrap();
|
||||
|
||||
for side in &BlockDirection::all() {
|
||||
for side in BlockDirection::all() {
|
||||
let neighbor_pos = pos.offset(side.to_offset());
|
||||
wire_power = max_wire_power(wire_power, world, neighbor_pos).await;
|
||||
let (neighbor, neighbor_state) = world
|
||||
|
||||
@@ -36,7 +36,7 @@ impl PumpkinBlock for RepeaterBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -146,10 +146,10 @@ impl PumpkinBlock for RepeaterBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let repeater_props = RepeaterProperties::from_state_id(state.id, block);
|
||||
if &repeater_props.facing.to_block_direction() == direction && repeater_props.powered {
|
||||
if repeater_props.facing.to_block_direction() == direction && repeater_props.powered {
|
||||
return 15;
|
||||
}
|
||||
0
|
||||
@@ -161,10 +161,10 @@ impl PumpkinBlock for RepeaterBlock {
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let repeater_props = RepeaterProperties::from_state_id(state.id, block);
|
||||
if &repeater_props.facing.to_block_direction() == direction && repeater_props.powered {
|
||||
if repeater_props.facing.to_block_direction() == direction && repeater_props.powered {
|
||||
return 15;
|
||||
}
|
||||
0
|
||||
@@ -174,10 +174,10 @@ impl PumpkinBlock for RepeaterBlock {
|
||||
&self,
|
||||
block: &Block,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> bool {
|
||||
let repeater_props = RepeaterProperties::from_state_id(state.id, block);
|
||||
&repeater_props.facing.to_block_direction() == direction
|
||||
repeater_props.facing.to_block_direction() == direction
|
||||
|| repeater_props.facing.to_block_direction() == direction.opposite()
|
||||
}
|
||||
}
|
||||
@@ -211,7 +211,7 @@ async fn get_power_on_side(world: &World, pos: &BlockPos, side: HorizontalFacing
|
||||
&side_state,
|
||||
world,
|
||||
&side_pos,
|
||||
&side.to_block_direction(),
|
||||
side.to_block_direction(),
|
||||
false,
|
||||
)
|
||||
.await
|
||||
@@ -224,7 +224,8 @@ async fn on_state_change(rep: RepeaterProperties, world: &Arc<World>, pos: &Bloc
|
||||
let front_pos = pos.offset(rep.facing.opposite().to_block_direction().to_offset());
|
||||
let front_block = world.get_block(&front_pos).await.unwrap();
|
||||
world.update_neighbor(&front_pos, &front_block).await;
|
||||
for direction in &BlockDirection::all() {
|
||||
|
||||
for direction in BlockDirection::all() {
|
||||
let neighbor_pos = front_pos.offset(direction.to_offset());
|
||||
let block = world.get_block(&neighbor_pos).await.unwrap();
|
||||
world.update_neighbor(&neighbor_pos, &block).await;
|
||||
@@ -260,5 +261,5 @@ async fn schedule_tick(
|
||||
}
|
||||
|
||||
async fn should_be_powered(rep: RepeaterProperties, world: &World, pos: &BlockPos) -> bool {
|
||||
diode_get_input_strength(world, pos, &rep.facing.to_block_direction()).await > 0
|
||||
diode_get_input_strength(world, pos, rep.facing.to_block_direction()).await > 0
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ impl PumpkinBlock for TargetBlock {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ impl RedstoneWireTurbo {
|
||||
let pos = self.nodes[upd.index].pos;
|
||||
|
||||
let mut wire_power = 0;
|
||||
for side in &BlockDirection::all() {
|
||||
for side in BlockDirection::all() {
|
||||
let neighbor_pos = pos.offset(side.to_offset());
|
||||
let neighbor = &self.nodes[self.node_cache[&neighbor_pos].index].state;
|
||||
wire_power = wire_power.max(
|
||||
|
||||
@@ -37,7 +37,7 @@ impl PumpkinBlock for SignBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
@@ -68,7 +68,7 @@ impl PumpkinBlock for SignBlock {
|
||||
_block: &Block,
|
||||
_state_id: u16,
|
||||
pos: &BlockPos,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
player: &Player,
|
||||
) {
|
||||
player.send_sign_packet(*pos).await;
|
||||
|
||||
@@ -35,7 +35,7 @@ impl PumpkinBlock for SlabBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
|
||||
@@ -41,7 +41,7 @@ impl PumpkinBlock for StairBlock {
|
||||
_server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct SugarCaneBlock;
|
||||
#[async_trait]
|
||||
impl PumpkinBlock for SugarCaneBlock {
|
||||
async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
world.break_block(pos, None, BlockFlags::empty()).await;
|
||||
}
|
||||
}
|
||||
@@ -62,11 +62,11 @@ impl PumpkinBlock for SugarCaneBlock {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
pos: &BlockPos,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
if !self.can_place_at(world, pos).await {
|
||||
if !self.can_place_at(world, pos, BlockDirection::Down).await {
|
||||
world
|
||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
||||
.await;
|
||||
@@ -74,7 +74,7 @@ impl PumpkinBlock for SugarCaneBlock {
|
||||
state
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(&self, world: &World, pos: &BlockPos, _face: BlockDirection) -> bool {
|
||||
let block = world.get_block(&pos.down()).await.unwrap();
|
||||
|
||||
if block == Block::SUGAR_CANE {
|
||||
@@ -94,6 +94,7 @@ impl PumpkinBlock for SugarCaneBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ impl PumpkinBlock for TorchBlock {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
|
||||
@@ -62,7 +62,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
block: &Block,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_player: &Player,
|
||||
@@ -73,7 +73,12 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
|
||||
async fn random_tick(&self, _block: &Block, _world: &Arc<World>, _pos: &BlockPos) {}
|
||||
|
||||
async fn can_place_at(&self, _world: &World, _pos: &BlockPos) -> bool {
|
||||
async fn can_place_at(
|
||||
&self,
|
||||
_world: &World,
|
||||
_block_pos: &BlockPos,
|
||||
_face: BlockDirection,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
@@ -107,7 +112,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
_block: &Block,
|
||||
_state_id: u16,
|
||||
_pos: &BlockPos,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_player: &Player,
|
||||
) {
|
||||
}
|
||||
@@ -161,7 +166,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
_block: &Block,
|
||||
state: BlockStateId,
|
||||
_pos: &BlockPos,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
_neighbor_pos: &BlockPos,
|
||||
_neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
@@ -185,7 +190,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
&self,
|
||||
_block: &Block,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
@@ -197,7 +202,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
_world: &World,
|
||||
_pos: &BlockPos,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> u8 {
|
||||
0
|
||||
}
|
||||
@@ -209,7 +214,7 @@ pub trait PumpkinBlock: Send + Sync {
|
||||
_world: &World,
|
||||
_pos: &BlockPos,
|
||||
_state: &BlockState,
|
||||
_direction: &BlockDirection,
|
||||
_direction: BlockDirection,
|
||||
) -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ pub trait PumpkinFluid: Send + Sync {
|
||||
_server: &Server,
|
||||
_world: &World,
|
||||
fluid: &Fluid,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block_pos: &BlockPos,
|
||||
_use_item_on: &SUseItemOn,
|
||||
_replacing: BlockIsReplacing,
|
||||
|
||||
@@ -103,7 +103,7 @@ impl BlockRegistry {
|
||||
server: &Server,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block_pos: &BlockPos,
|
||||
use_item_on: &SUseItemOn,
|
||||
player: &Player,
|
||||
@@ -133,7 +133,7 @@ impl BlockRegistry {
|
||||
block: &Block,
|
||||
state_id: u16,
|
||||
pos: &BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
player: &Player,
|
||||
) {
|
||||
let pumpkin_block = self.get_pumpkin_block(block);
|
||||
@@ -144,10 +144,16 @@ impl BlockRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn can_place_at(&self, world: &World, block: &Block, block_pos: &BlockPos) -> bool {
|
||||
pub async fn can_place_at(
|
||||
&self,
|
||||
world: &World,
|
||||
block: &Block,
|
||||
block_pos: &BlockPos,
|
||||
face: BlockDirection,
|
||||
) -> bool {
|
||||
let pumpkin_block = self.get_pumpkin_block(block);
|
||||
if let Some(pumpkin_block) = pumpkin_block {
|
||||
return pumpkin_block.can_place_at(world, block_pos).await;
|
||||
return pumpkin_block.can_place_at(world, block_pos, face).await;
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -273,7 +279,7 @@ impl BlockRegistry {
|
||||
block,
|
||||
state.id,
|
||||
location,
|
||||
&direction.opposite(),
|
||||
direction.opposite(),
|
||||
&neighbor_pos,
|
||||
neighbor_state.id,
|
||||
)
|
||||
@@ -306,7 +312,7 @@ impl BlockRegistry {
|
||||
block: &Block,
|
||||
state: BlockStateId,
|
||||
block_pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
neighbor_pos: &BlockPos,
|
||||
neighbor_state: BlockStateId,
|
||||
) -> BlockStateId {
|
||||
@@ -339,7 +345,7 @@ impl BlockRegistry {
|
||||
|
||||
Box::pin(world.replace_with_state_for_neighbor_update(
|
||||
&pos,
|
||||
&direction.opposite(),
|
||||
direction.opposite(),
|
||||
flags,
|
||||
))
|
||||
.await;
|
||||
@@ -382,7 +388,7 @@ impl BlockRegistry {
|
||||
&self,
|
||||
block: &Block,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> bool {
|
||||
let pumpkin_block = self.get_pumpkin_block(block);
|
||||
if let Some(pumpkin_block) = pumpkin_block {
|
||||
@@ -399,7 +405,7 @@ impl BlockRegistry {
|
||||
world: &World,
|
||||
block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let pumpkin_block = self.get_pumpkin_block(block);
|
||||
if let Some(pumpkin_block) = pumpkin_block {
|
||||
@@ -416,7 +422,7 @@ impl BlockRegistry {
|
||||
world: &World,
|
||||
block_pos: &BlockPos,
|
||||
state: &BlockState,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
) -> u8 {
|
||||
let pumpkin_block = self.get_pumpkin_block(block);
|
||||
if let Some(pumpkin_block) = pumpkin_block {
|
||||
|
||||
@@ -36,7 +36,7 @@ impl PumpkinItem for AxeItem {
|
||||
_item: &Item,
|
||||
player: &Player,
|
||||
location: BlockPos,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block: &Block,
|
||||
_server: &Server,
|
||||
) {
|
||||
|
||||
@@ -36,7 +36,7 @@ impl PumpkinItem for HoeItem {
|
||||
_item: &Item,
|
||||
player: &Player,
|
||||
location: BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block: &Block,
|
||||
_server: &Server,
|
||||
) {
|
||||
@@ -51,7 +51,7 @@ impl PumpkinItem for HoeItem {
|
||||
let world = player.world().await;
|
||||
|
||||
//Only rooted can be right-clicked on the bottom of the block
|
||||
if face == &BlockDirection::Down {
|
||||
if face == BlockDirection::Down {
|
||||
if block == &Block::ROOTED_DIRT {
|
||||
future_block = &Block::DIRT;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ impl PumpkinItem for HoneyCombItem {
|
||||
_item: &Item,
|
||||
player: &Player,
|
||||
location: BlockPos,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
block: &Block,
|
||||
_server: &Server,
|
||||
) {
|
||||
|
||||
@@ -33,7 +33,7 @@ impl PumpkinItem for ShovelItem {
|
||||
_item: &Item,
|
||||
player: &Player,
|
||||
location: BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block: &Block,
|
||||
_server: &Server,
|
||||
) {
|
||||
@@ -46,7 +46,7 @@ impl PumpkinItem for ShovelItem {
|
||||
|| block == &Block::MYCELIUM
|
||||
{
|
||||
let world = player.world().await;
|
||||
if face != &BlockDirection::Down
|
||||
if face != BlockDirection::Down
|
||||
&& world
|
||||
.get_block_state(&location.up())
|
||||
.await
|
||||
|
||||
@@ -19,7 +19,7 @@ pub trait PumpkinItem: Send + Sync {
|
||||
_item: &Item,
|
||||
_player: &Player,
|
||||
_location: BlockPos,
|
||||
_face: &BlockDirection,
|
||||
_face: BlockDirection,
|
||||
_block: &Block,
|
||||
_server: &Server,
|
||||
) {
|
||||
|
||||
@@ -31,7 +31,7 @@ impl ItemRegistry {
|
||||
item: &Item,
|
||||
player: &Player,
|
||||
location: BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
block: &Block,
|
||||
server: &Server,
|
||||
) {
|
||||
|
||||
@@ -1416,7 +1416,7 @@ impl Player {
|
||||
if !sneaking {
|
||||
server
|
||||
.item_registry
|
||||
.use_on_block(&stack.item, self, location, &face, &block, server)
|
||||
.use_on_block(&stack.item, self, location, face, &block, server)
|
||||
.await;
|
||||
|
||||
let action_result = server
|
||||
@@ -1434,13 +1434,13 @@ impl Player {
|
||||
// Check if the item is a block, because not every item can be placed :D
|
||||
if let Some(block) = get_block_by_item(stack.item.id) {
|
||||
should_try_decrement = self
|
||||
.run_is_block_place(block, server, use_item_on, location, &face)
|
||||
.run_is_block_place(block, server, use_item_on, location, face)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Check if the item is a spawn egg
|
||||
if let Some(entity) = entity_from_egg(stack.item.id) {
|
||||
self.spawn_entity_from_egg(entity, location, &face).await;
|
||||
self.spawn_entity_from_egg(entity, location, face).await;
|
||||
should_try_decrement = true;
|
||||
}
|
||||
|
||||
@@ -1619,7 +1619,7 @@ impl Player {
|
||||
&self,
|
||||
entity_type: EntityType,
|
||||
location: BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
) {
|
||||
let world_pos = BlockPos(location.0 + face.to_offset());
|
||||
// Align the position like Vanilla does
|
||||
@@ -1654,7 +1654,7 @@ impl Player {
|
||||
server: &Server,
|
||||
use_item_on: SUseItemOn,
|
||||
location: BlockPos,
|
||||
face: &BlockDirection,
|
||||
face: BlockDirection,
|
||||
) -> Result<bool, Box<dyn PumpkinError>> {
|
||||
let entity = &self.living_entity.entity;
|
||||
let world = &entity.world.read().await;
|
||||
@@ -1697,7 +1697,7 @@ impl Player {
|
||||
&clicked_block,
|
||||
clicked_block_state.id,
|
||||
&clicked_block_pos,
|
||||
*face,
|
||||
face,
|
||||
&use_item_on,
|
||||
)
|
||||
.await
|
||||
@@ -1750,7 +1750,7 @@ impl Player {
|
||||
};
|
||||
|
||||
match replace_previous_block {
|
||||
Some(replacing) => (block_pos, &face.opposite(), replacing),
|
||||
Some(replacing) => (block_pos, face.opposite(), replacing),
|
||||
None => {
|
||||
// Don't place and don't decrement if the previous block is not replaceable
|
||||
return Ok(false);
|
||||
@@ -1760,7 +1760,7 @@ impl Player {
|
||||
|
||||
if !server
|
||||
.block_registry
|
||||
.can_place_at(world, &block, &final_block_pos)
|
||||
.can_place_at(world, &block, &final_block_pos, face)
|
||||
.await
|
||||
{
|
||||
return Ok(false);
|
||||
|
||||
@@ -1595,16 +1595,18 @@ impl World {
|
||||
pub async fn update_neighbors(
|
||||
self: &Arc<Self>,
|
||||
block_pos: &BlockPos,
|
||||
except: Option<&BlockDirection>,
|
||||
except: Option<BlockDirection>,
|
||||
) {
|
||||
let source_block = self.get_block(block_pos).await.unwrap();
|
||||
for direction in BlockDirection::update_order() {
|
||||
if Some(&direction) == except {
|
||||
if except.is_some_and(|d| d == direction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let neighbor_pos = block_pos.offset(direction.to_offset());
|
||||
let neighbor_block = self.get_block(&neighbor_pos).await;
|
||||
let neighbor_fluid = self.get_fluid(&neighbor_pos).await;
|
||||
|
||||
if let Ok(neighbor_block) = neighbor_block {
|
||||
if let Some(neighbor_pumpkin_block) =
|
||||
self.block_registry.get_pumpkin_block(&neighbor_block)
|
||||
@@ -1620,6 +1622,7 @@ impl World {
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(neighbor_fluid) = neighbor_fluid {
|
||||
if let Some(neighbor_pumpkin_fluid) =
|
||||
self.block_registry.get_pumpkin_fluid(&neighbor_fluid)
|
||||
@@ -1656,7 +1659,7 @@ impl World {
|
||||
pub async fn replace_with_state_for_neighbor_update(
|
||||
self: &Arc<Self>,
|
||||
block_pos: &BlockPos,
|
||||
direction: &BlockDirection,
|
||||
direction: BlockDirection,
|
||||
flags: BlockFlags,
|
||||
) {
|
||||
let (block, block_state) = match self.get_block_and_block_state(block_pos).await {
|
||||
|
||||
Reference in New Issue
Block a user