9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-26 10:29:20 +00:00

初步实现台阶

This commit is contained in:
XiaoMoMi
2025-06-21 04:41:05 +08:00
parent 56d797f59f
commit 16fea80479
19 changed files with 435 additions and 51 deletions

View File

@@ -23,6 +23,8 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
public static final Key STACKABLE_BLOCK = Key.from("craftengine:stackable_block");
public static final Key STURDY_BASE_BLOCK = Key.from("craftengine:sturdy_base_block");
public static final Key FENCE_GATE_BLOCK = Key.from("craftengine:fence_gate_block");
public static final Key SLAB_BLOCK = Key.from("craftengine:slab_block");
public static final Key STAIRS_BLOCK = Key.from("craftengine:stairs_block");
public static void init() {
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
@@ -44,5 +46,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(STACKABLE_BLOCK, StackableBlockBehavior.FACTORY);
register(STURDY_BASE_BLOCK, SturdyBaseBlockBehavior.FACTORY);
register(FENCE_GATE_BLOCK, FenceGateBlockBehavior.FACTORY);
register(SLAB_BLOCK, SlabBlockBehavior.FACTORY);
register(STAIRS_BLOCK, StairsBlockBehavior.FACTORY);
}
}

View File

@@ -0,0 +1,127 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.block.state.properties.SlabType;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.behavior.BlockBoundItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.BlockPos;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
public class SlabBlockBehavior extends BukkitBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Property<SlabType> typeProperty;
public SlabBlockBehavior(CustomBlock block, Property<SlabType> typeProperty) {
super(block);
this.typeProperty = typeProperty;
}
@SuppressWarnings("unchecked")
@Override
public boolean canBeReplaced(BlockPlaceContext context, ImmutableBlockState state) {
SlabType type = state.get(this.typeProperty);
Item<ItemStack> item = (Item<ItemStack>) context.getItem();
if (type == SlabType.DOUBLE) return false;
Optional<CustomItem<ItemStack>> itemInHand = item.getCustomItem();
if (itemInHand.isEmpty()) return false;
CustomItem<ItemStack> customItem = itemInHand.get();
Key blockId = null;
for (ItemBehavior itemBehavior : customItem.behaviors()) {
if (itemBehavior instanceof BlockBoundItemBehavior behavior) {
blockId = behavior.block();
}
}
if (blockId == null || !blockId.equals(super.customBlock.id())) return false;
if (!context.replacingClickedOnBlock()) return true;
boolean upper = context.getClickLocation().y - (double) context.getClickedPos().y() > (double) 0.5F;
Direction clickedFace = context.getClickedFace();
return type == SlabType.BOTTOM ?
clickedFace == Direction.UP || upper && clickedFace.axis().isHorizontal() :
clickedFace == Direction.DOWN || !upper && clickedFace.axis().isHorizontal();
}
@Override
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
BlockPos clickedPos = context.getClickedPos();
ImmutableBlockState blockState = context.getLevel().getBlockAt(clickedPos).customBlockState();
if (blockState != null && blockState.owner().value() == super.customBlock) {
return blockState.with(this.typeProperty, SlabType.DOUBLE).with(super.waterloggedProperty, false);
} else {
Object fluidState = FastNMS.INSTANCE.method$Level$getFluidState(context.getLevel().serverWorld(), LocationUtils.toBlockPos(clickedPos));
state = state.with(super.waterloggedProperty, FastNMS.INSTANCE.method$FluidState$getType(fluidState) == MFluids.WATER);
Direction clickedFace = context.getClickedFace();
return clickedFace == Direction.DOWN || clickedFace != Direction.UP && context.getClickLocation().y - (double) clickedPos.y() > (double) 0.5F ? state.with(this.typeProperty, SlabType.TOP) : state.with(this.typeProperty, SlabType.BOTTOM);
}
}
@Override
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object blockState = args[2];
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
if (immutableBlockState == null || immutableBlockState.isEmpty()) return false;
return immutableBlockState.get(this.typeProperty) != SlabType.DOUBLE && super.placeLiquid(thisBlock, args, superMethod);
}
@Override
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object blockState = VersionHelper.isOrAbove1_20_2() ? args[3] : args[2];
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
if (immutableBlockState == null || immutableBlockState.isEmpty()) return false;
return immutableBlockState.get(this.typeProperty) != SlabType.DOUBLE && super.canPlaceLiquid(thisBlock, args, superMethod);
}
@Override
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object blockState = args[0];
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
if (immutableBlockState == null || immutableBlockState.isEmpty()) return blockState;
if (immutableBlockState.get(super.waterloggedProperty)) {
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(VersionHelper.isOrAbove1_21_2() ? args[2] : args[3], VersionHelper.isOrAbove1_21_2() ? args[3] : args[4], MFluids.WATER, 5);
}
return blockState;
}
@Override
public boolean isPathFindable(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object type = VersionHelper.isOrAbove1_20_5() ? args[1] : args[3];
Object blockState = args[0];
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
if (state == null || state.isEmpty()) return false;
if (type == CoreReflections.instance$PathComputationType$WATER) {
return state.get(this.typeProperty) != SlabType.DOUBLE && state.get(super.waterloggedProperty);
}
return false;
}
public static class Factory implements BlockBehaviorFactory {
@SuppressWarnings("unchecked")
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
Property<SlabType> type = (Property<SlabType>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("type"), "warning.config.block.behavior.trapdoor.missing_type");
return new SlabBlockBehavior(block, type);
}
}
}

View File

@@ -0,0 +1,23 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import java.util.Map;
public class StairsBlockBehavior extends BukkitBlockBehavior {
public static final Factory FACTORY = new Factory();
public StairsBlockBehavior(CustomBlock block) {
super(block);
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
return new StairsBlockBehavior(block);
}
}
}

View File

@@ -42,6 +42,17 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
return super.useOnBlock(context, state);
}
@Override
public InteractionResult useWithoutItem(UseOnContext context, ImmutableBlockState state) {
for (AbstractBlockBehavior behavior : this.behaviors) {
InteractionResult result = behavior.useWithoutItem(context, state);
if (result != InteractionResult.PASS) {
return result;
}
}
return super.useWithoutItem(context, state);
}
@Override
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
for (AbstractBlockBehavior behavior : this.behaviors) {
@@ -189,4 +200,14 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
behavior.setPlacedBy(context, state);
}
}
@Override
public boolean canBeReplaced(BlockPlaceContext context, ImmutableBlockState state) {
for (AbstractBlockBehavior behavior : this.behaviors) {
if (!behavior.canBeReplaced(context, state)) {
return false;
}
}
return super.canBeReplaced(context, state);
}
}

View File

@@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.behavior.BlockBoundItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
@@ -52,7 +53,7 @@ import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
public class BlockItemBehavior extends ItemBehavior {
public class BlockItemBehavior extends BlockBoundItemBehavior {
public static final Factory FACTORY = new Factory();
private final Key blockId;
@@ -196,7 +197,8 @@ public class BlockItemBehavior extends ItemBehavior {
}
}
public Key blockId() {
@Override
public Key block() {
return this.blockId;
}

View File

@@ -30,25 +30,11 @@ public class BukkitBlockInWorld implements BlockInWorld {
this.block = block;
}
@SuppressWarnings("unchecked")
@Override
public boolean canBeReplaced(BlockPlaceContext context) {
ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(this.block.getBlockData()));
if (customState != null && !customState.isEmpty()) {
Key clickedBlockId = customState.owner().value().id();
Item<ItemStack> item = (Item<ItemStack>) context.getPlayer().getItemInHand(context.getHand());
Optional<CustomItem<ItemStack>> customItem = BukkitItemManager.instance().getCustomItem(item.id());
if (customItem.isPresent()) {
CustomItem<ItemStack> custom = customItem.get();
for (ItemBehavior behavior : custom.behaviors()) {
if (behavior instanceof BlockItemBehavior blockItemBehavior) {
Key blockId = blockItemBehavior.blockId();
if (blockId.equals(clickedBlockId)) {
return false;
}
}
}
}
return customState.behavior().canBeReplaced(context, customState);
}
return this.block.isReplaceable();
}

View File

@@ -3928,26 +3928,36 @@ $$>=1.21.4#fence_gate:
#### Slab ####
minecraft:petrified_oak_slab[type=bottom,waterlogged=false]: minecraft:oak_slab[type=bottom,waterlogged=false]
minecraft:petrified_oak_slab[type=top,waterlogged=false]: minecraft:oak_slab[type=top,waterlogged=false]
minecraft:petrified_oak_slab[type=double,waterlogged=false]: minecraft:oak_slab[type=double,waterlogged=false]
minecraft:petrified_oak_slab[type=bottom,waterlogged=true]: minecraft:oak_slab[type=bottom,waterlogged=true]
minecraft:petrified_oak_slab[type=top,waterlogged=true]: minecraft:oak_slab[type=top,waterlogged=true]
minecraft:petrified_oak_slab[type=double,waterlogged=true]: minecraft:oak_slab[type=double,waterlogged=true]
$$>=1.20.3#slab:
minecraft:cut_copper_slab[type=bottom,waterlogged=false]: minecraft:waxed_cut_copper_slab[type=bottom,waterlogged=false]
minecraft:cut_copper_slab[type=top,waterlogged=false]: minecraft:waxed_cut_copper_slab[type=top,waterlogged=false]
minecraft:cut_copper_slab[type=double,waterlogged=false]: minecraft:waxed_cut_copper_slab[type=double,waterlogged=false]
minecraft:cut_copper_slab[type=bottom,waterlogged=true]: minecraft:waxed_cut_copper_slab[type=bottom,waterlogged=true]
minecraft:cut_copper_slab[type=top,waterlogged=true]: minecraft:waxed_cut_copper_slab[type=top,waterlogged=true]
minecraft:cut_copper_slab[type=double,waterlogged=true]: minecraft:waxed_cut_copper_slab[type=double,waterlogged=true]
minecraft:exposed_cut_copper_slab[type=bottom,waterlogged=false]: minecraft:waxed_exposed_cut_copper_slab[type=bottom,waterlogged=false]
minecraft:exposed_cut_copper_slab[type=top,waterlogged=false]: minecraft:waxed_exposed_cut_copper_slab[type=top,waterlogged=false]
minecraft:exposed_cut_copper_slab[type=double,waterlogged=false]: minecraft:waxed_exposed_cut_copper_slab[type=double,waterlogged=false]
minecraft:exposed_cut_copper_slab[type=bottom,waterlogged=true]: minecraft:waxed_exposed_cut_copper_slab[type=bottom,waterlogged=true]
minecraft:exposed_cut_copper_slab[type=top,waterlogged=true]: minecraft:waxed_exposed_cut_copper_slab[type=top,waterlogged=true]
minecraft:exposed_cut_copper_slab[type=double,waterlogged=true]: minecraft:waxed_exposed_cut_copper_slab[type=double,waterlogged=true]
minecraft:weathered_cut_copper_slab[type=bottom,waterlogged=false]: minecraft:waxed_weathered_cut_copper_slab[type=bottom,waterlogged=false]
minecraft:weathered_cut_copper_slab[type=top,waterlogged=false]: minecraft:waxed_weathered_cut_copper_slab[type=top,waterlogged=false]
minecraft:weathered_cut_copper_slab[type=double,waterlogged=false]: minecraft:waxed_weathered_cut_copper_slab[type=double,waterlogged=false]
minecraft:weathered_cut_copper_slab[type=bottom,waterlogged=true]: minecraft:waxed_weathered_cut_copper_slab[type=bottom,waterlogged=true]
minecraft:weathered_cut_copper_slab[type=top,waterlogged=true]: minecraft:waxed_weathered_cut_copper_slab[type=top,waterlogged=true]
minecraft:weathered_cut_copper_slab[type=double,waterlogged=true]: minecraft:waxed_weathered_cut_copper_slab[type=double,waterlogged=true]
minecraft:oxidized_cut_copper_slab[type=bottom,waterlogged=false]: minecraft:waxed_oxidized_cut_copper_slab[type=bottom,waterlogged=false]
minecraft:oxidized_cut_copper_slab[type=top,waterlogged=false]: minecraft:waxed_oxidized_cut_copper_slab[type=top,waterlogged=false]
minecraft:oxidized_cut_copper_slab[type=double,waterlogged=false]: minecraft:waxed_oxidized_cut_copper_slab[type=double,waterlogged=false]
minecraft:oxidized_cut_copper_slab[type=bottom,waterlogged=true]: minecraft:waxed_oxidized_cut_copper_slab[type=bottom,waterlogged=true]
minecraft:oxidized_cut_copper_slab[type=top,waterlogged=true]: minecraft:waxed_oxidized_cut_copper_slab[type=top,waterlogged=true]
minecraft:oxidized_cut_copper_slab[type=double,waterlogged=true]: minecraft:waxed_oxidized_cut_copper_slab[type=double,waterlogged=true]
#### Chorus Plant ####
# Chorus Plant does support transparent textures, but man... its hitbox is super weird. You're probably better off using leaves.

View File

@@ -17,6 +17,8 @@ lang:
block_name:default:palm_trapdoor: Palm Trapdoor
block_name:default:palm_door: Palm Door
block_name:default:palm_fence_gate: Palm Fence Gate
block_name:default:palm_slab: Palm Slab
block_name:default:palm_stairs: Palm Stairs
block_name:default:fairy_flower: Fairy Flower
block_name:default:reed: Reed
block_name:default:flame_cane: Flame Cane
@@ -38,7 +40,9 @@ lang:
block_name:default:palm_leaves: 棕榈树叶
block_name:default:palm_trapdoor: 棕榈木活板门
block_name:default:palm_door: 棕榈木门
block_name:default:palm_fence_gate: 棕榈木栅门
block_name:default:palm_fence_gate: 棕榈木栅
block_name:default:palm_slab: 棕榈木台阶
block_name:default:palm_stairs: 棕榈木楼梯
block_name:default:fairy_flower: 仙灵花
block_name:default:reed: 芦苇
block_name:default:flame_cane: 烈焰甘蔗

View File

@@ -25,6 +25,8 @@ categories:
- default:palm_trapdoor
- default:palm_door
- default:palm_fence_gate
- default:palm_slab
- default:palm_stairs
default:topaz:
name: <!i><#FF8C00><i18n:category.topaz></#FF8C00>
hidden: true

View File

@@ -34,6 +34,8 @@ i18n:
item.palm_trapdoor: Palm Trapdoor
item.palm_door: Palm Door
item.palm_fence_gate: Palm Fence Gate
item.palm_slab: Palm Slab
item.palm_stairs: Palm Stairs
item.netherite_anvil: Netherite Anvil
item.gunpowder_block: GunPowder Block
item.solid_gunpowder_block: Solid GunPowder Block
@@ -84,6 +86,8 @@ i18n:
item.palm_trapdoor: 棕榈木活板门
item.palm_door: 棕榈木门
item.palm_fence_gate: 棕榈木栅栏门
item.palm_slab: 棕榈木台阶
item.palm_stairs: 棕榈木楼梯
item.netherite_anvil: 下界合金砧
item.gunpowder_block: 火药粉末
item.solid_gunpowder_block: 凝固火药块

View File

@@ -286,6 +286,8 @@ items:
custom-model-data: 1006
data:
item-name: <!i><i18n:item.palm_trapdoor>
settings:
fuel-time: 300
model:
type: minecraft:model
path: minecraft:item/custom/palm_trapdoor
@@ -339,6 +341,8 @@ items:
custom-model-data: 1007
data:
item-name: <!i><i18n:item.palm_door>
settings:
fuel-time: 200
model:
template: default:model/simplified_generated
arguments:
@@ -426,6 +430,8 @@ items:
custom-model-data: 1008
data:
item-name: <!i><i18n:item.palm_fence_gate>
settings:
fuel-time: 300
model:
type: minecraft:model
path: minecraft:item/custom/palm_fence_gate
@@ -444,17 +450,18 @@ items:
loot:
template: default:loot_table/self
settings:
item: default:palm_fence_gate
sounds:
break: minecraft:block.wood.break
step: minecraft:block.wood.step
place: minecraft:block.wood.place
hit: minecraft:block.wood.hit
fall: minecraft:block.wood.fall
tags:
- minecraft:fence_gates
- minecraft:mineable/axe
- minecraft:unstable_bottom_center
template:
- default:sound/wood
overrides:
map-color: 2
instrument: bass
hardness: 2.0
resistance: 3.0
burnable: true
tags:
- minecraft:fence_gates
- minecraft:mineable/axe
- minecraft:unstable_bottom_center
states:
template: default:block_state/fence_gate
arguments:
@@ -476,6 +483,57 @@ items:
model_fence_gate_wall_open_generation:
parent: minecraft:block/template_fence_gate_wall_open
textures: *textures
default:palm_slab:
material: nether_brick
custom-model-data: 1009
data:
item-name: <!i><i18n:item.palm_slab>
settings:
fuel-time: 150
model:
type: minecraft:model
path: minecraft:item/custom/palm_slab
generation:
parent: minecraft:block/custom/palm_slab
behavior:
type: block_item
block:
behaviors:
type: slab_block
loot:
template: default:loot_table/self
settings:
template:
- default:sound/wood
- default:burn_data/planks
overrides:
map-color: 2
instrument: bass
hardness: 2.0
resistance: 3.0
tags:
- minecraft:wooden_slabs
- minecraft:slabs
- minecraft:mineable/axe
states:
template: default:block_state/slab
arguments:
base_block: petrified_oak_slab
model_bottom_path: minecraft:block/custom/palm_slab
model_bottom_generation:
parent: minecraft:block/slab
textures:
bottom: minecraft:block/custom/palm_planks
side: minecraft:block/custom/palm_planks
top: minecraft:block/custom/palm_planks
model_top_path: minecraft:block/custom/palm_slab_top
model_top_generation:
parent: minecraft:block/slab_top
textures:
bottom: minecraft:block/custom/palm_planks
side: minecraft:block/custom/palm_planks
top: minecraft:block/custom/palm_planks
model_double_path: minecraft:block/custom/palm_planks
recipes:
default:palm_planks:
template: default:recipe/planks
@@ -498,4 +556,35 @@ recipes:
A: default:palm_planks
result:
id: default:palm_trapdoor
count: 2
count: 2
default:palm_fence_gate:
type: shaped
pattern:
- ABA
- ABA
ingredients:
A: minecraft:stick
B: default:palm_planks
result:
id: default:palm_fence_gate
count: 1
default:palm_slab:
type: shaped
pattern:
- AAA
ingredients:
A: default:palm_planks
result:
id: default:palm_slab
count: 6
# default:palm_stairs:
# type: shaped
# pattern:
# - A
# - AA
# - AAA
# ingredients:
# A: default:palm_planks
# result:
# id: default:palm_stairs
# count: 4

View File

@@ -2039,6 +2039,74 @@ templates#block_states:
facing=north,in_wall=true,open=true,powered=false:
appearance: facing=north,in_wall=true,open=true
id: 31
# slab block
default:block_state/slab:
properties:
type:
type: slab_type
default: bottom
waterlogged:
type: boolean
default: false
appearances:
type=top,waterlogged=false:
state: ${base_block}[type=top,waterlogged=false]
model:
path: ${model_top_path}
generation: ${model_top_generation}
type=bottom,waterlogged=false:
state: ${base_block}[type=bottom,waterlogged=false]
model:
path: ${model_bottom_path}
generation: ${model_bottom_generation}
type=double,waterlogged=false:
state: ${base_block}[type=double,waterlogged=false]
model:
path: ${model_double_path}
generation: ${model_double_generation}
type=top,waterlogged=true:
state: ${base_block}[type=top,waterlogged=true]
model:
path: ${model_top_path}
type=bottom,waterlogged=true:
state: ${base_block}[type=bottom,waterlogged=true]
model:
path: ${model_bottom_path}
type=double,waterlogged=true:
state: ${base_block}[type=double,waterlogged=true]
model:
path: ${model_double_path}
variants:
type=top,waterlogged=false:
appearance: type=top,waterlogged=false
id: 0
type=bottom,waterlogged=false:
appearance: type=bottom,waterlogged=false
id: 1
type=double,waterlogged=false:
appearance: type=double,waterlogged=false
id: 2
type=top,waterlogged=true:
appearance: type=top,waterlogged=true
id: 3
settings:
resistance: 1200.0
burnable: false
fluid-state: water
type=bottom,waterlogged=true:
appearance: type=bottom,waterlogged=true
id: 4
settings:
resistance: 1200.0
burnable: false
fluid-state: water
type=double,waterlogged=true:
appearance: type=double,waterlogged=true
id: 5
settings:
resistance: 1200.0
burnable: false
fluid-state: water
# recipes
templates#recipes:

View File

@@ -1,8 +1,14 @@
package net.momirealms.craftengine.core.block;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.behavior.BlockBoundItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.item.context.UseOnContext;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import java.util.Optional;
import java.util.concurrent.Callable;
@@ -91,10 +97,44 @@ public abstract class BlockBehavior {
public void onExplosionHit(Object thisBlock, Object[] args, Callable<Object> superMethod) {
}
// LevelAccessor level, BlockPos pos, BlockState state, FluidState fluidState
public boolean placeLiquid(Object thisObj, Object[] args, Callable<Object> superMethod) {
return false;
}
// 1.20.1 BlockGetter world, BlockPos pos, BlockState state, Fluid fluid
// 1.20.2+ LivingEntity owner, BlockGetter level, BlockPos pos, BlockState state, Fluid fluid
public boolean canPlaceLiquid(Object thisObj, Object[] args, Callable<Object> superMethod) {
return false;
}
// 1.20.1 LivingEntity owner, LevelAccessor level, BlockPos pos, BlockState state
// 1.20.2+ LevelAccessor world, BlockPos pos, BlockState state
public Object pickupBlock(Object thisObj, Object[] args, Callable<Object> superMethod) throws Exception {
return superMethod.call();
}
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
return state;
}
public boolean canBeReplaced(BlockPlaceContext context, ImmutableBlockState state) {
Key clickedBlockId = state.owner().value().id();
Item<?> item = context.getItem();
Optional<CustomItem<Object>> customItem = CraftEngine.instance().itemManager().getCustomItem(item.id());
if (customItem.isEmpty()) return state.settings().replaceable();
CustomItem<Object> custom = customItem.get();
for (ItemBehavior behavior : custom.behaviors()) {
if (behavior instanceof BlockBoundItemBehavior blockItemBehavior) {
Key blockId = blockItemBehavior.block();
if (blockId.equals(clickedBlockId)) {
return false;
}
}
}
return state.settings().replaceable();
}
public void setPlacedBy(BlockPlaceContext context, ImmutableBlockState state) {
}
@@ -106,15 +146,5 @@ public abstract class BlockBehavior {
return InteractionResult.PASS;
}
public Object pickupBlock(Object thisObj, Object[] args, Callable<Object> superMethod) throws Exception {
return superMethod.call();
}
public boolean placeLiquid(Object thisObj, Object[] args, Callable<Object> superMethod) {
return false;
}
public boolean canPlaceLiquid(Object thisObj, Object[] args, Callable<Object> superMethod) {
return false;
}
public abstract CustomBlock block();
}

View File

@@ -1,6 +1,10 @@
package net.momirealms.craftengine.core.block;
public class EmptyBlockBehavior extends BlockBehavior {
public static final EmptyBlockBehavior INSTANCE = new EmptyBlockBehavior();
@Override
public CustomBlock block() {
return EmptyBlock.INSTANCE;
}
}

View File

@@ -10,6 +10,7 @@ public abstract class AbstractBlockBehavior extends BlockBehavior {
this.customBlock = customBlock;
}
@Override
public CustomBlock block() {
return this.customBlock;
}

View File

@@ -1,9 +1,6 @@
package net.momirealms.craftengine.core.block.properties;
import net.momirealms.craftengine.core.block.state.properties.DoorHinge;
import net.momirealms.craftengine.core.block.state.properties.DoubleBlockHalf;
import net.momirealms.craftengine.core.block.state.properties.SingleBlockHalf;
import net.momirealms.craftengine.core.block.state.properties.StairsShape;
import net.momirealms.craftengine.core.block.state.properties.*;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
@@ -24,6 +21,7 @@ public class Properties {
public static final Key DOUBLE_BLOCK_HALF = Key.of("craftengine:double_block_half");
public static final Key HINGE = Key.of("craftengine:hinge");
public static final Key STAIRS_SHAPE = Key.of("craftengine:stairs_shape");
public static final Key SLAB_TYPE = Key.of("craftengine:slab_type");
static {
register(BOOLEAN, BooleanProperty.FACTORY);
@@ -38,6 +36,7 @@ public class Properties {
register(DOUBLE_BLOCK_HALF, new EnumProperty.Factory<>(DoubleBlockHalf.class));
register(HINGE, new EnumProperty.Factory<>(DoorHinge.class));
register(STAIRS_SHAPE, new EnumProperty.Factory<>(StairsShape.class));
register(SLAB_TYPE, new EnumProperty.Factory<>(SlabType.class));
}
public static void register(Key key, PropertyFactory factory) {

View File

@@ -0,0 +1,7 @@
package net.momirealms.craftengine.core.block.state.properties;
public enum SlabType {
TOP,
BOTTOM,
DOUBLE
}

View File

@@ -0,0 +1,8 @@
package net.momirealms.craftengine.core.item.behavior;
import net.momirealms.craftengine.core.util.Key;
public abstract class BlockBoundItemBehavior extends ItemBehavior {
public abstract Key block();
}

View File

@@ -15,9 +15,4 @@ public abstract class ItemBehavior {
public InteractionResult use(World world, Player player, InteractionHand hand) {
return InteractionResult.PASS;
}
// TODO
public InteractionResult useOnEntity() {
return InteractionResult.PASS;
}
}