mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-26 10:29:20 +00:00
初步实现台阶
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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: 烈焰甘蔗
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: 凝固火药块
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public abstract class AbstractBlockBehavior extends BlockBehavior {
|
||||
this.customBlock = customBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomBlock block() {
|
||||
return this.customBlock;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.momirealms.craftengine.core.block.state.properties;
|
||||
|
||||
public enum SlabType {
|
||||
TOP,
|
||||
BOTTOM,
|
||||
DOUBLE
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user