9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

添加允许液体流过的方块行为

This commit is contained in:
XiaoMoMi
2025-09-14 04:34:04 +08:00
parent 94c02f6b7b
commit d6f3ff4725
11 changed files with 105 additions and 20 deletions

View File

@@ -7,7 +7,7 @@ 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.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.behavior.special.TriggerOnceBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.FallOnBlockBehavior;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -17,7 +17,7 @@ import org.bukkit.entity.Entity;
import java.util.Map;
import java.util.concurrent.Callable;
public class BouncingBlockBehavior extends BukkitBlockBehavior implements TriggerOnceBlockBehavior {
public class BouncingBlockBehavior extends BukkitBlockBehavior implements FallOnBlockBehavior {
public static final Factory FACTORY = new Factory();
private final double bounceHeight;
private final boolean syncPlayerPosition;

View File

@@ -33,6 +33,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
public static final Key SOFA_BLOCK = Key.from("craftengine:sofa_block");
public static final Key BOUNCING_BLOCK = Key.from("craftengine:bouncing_block");
public static final Key DIRECTIONAL_ATTACHED_BLOCK = Key.from("craftengine:directional_attached_block");
public static final Key LIQUID_FLOWABLE_BLOCK = Key.from("craftengine:liquid_flowable_block");
public static void init() {
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
@@ -64,5 +65,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(SOFA_BLOCK, SofaBlockBehavior.FACTORY);
register(BOUNCING_BLOCK, BouncingBlockBehavior.FACTORY);
register(DIRECTIONAL_ATTACHED_BLOCK, DirectionalAttachedBlockBehavior.FACTORY);
register(LIQUID_FLOWABLE_BLOCK, LiquidFlowableBlockBehavior.FACTORY);
}
}

View File

@@ -0,0 +1,49 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.behavior.special.PlaceLiquidBlockBehavior;
import net.momirealms.craftengine.core.world.WorldEvents;
import java.util.Map;
import java.util.concurrent.Callable;
public class LiquidFlowableBlockBehavior extends BukkitBlockBehavior implements PlaceLiquidBlockBehavior {
public static final Factory FACTORY = new Factory();
public LiquidFlowableBlockBehavior(CustomBlock customBlock) {
super(customBlock);
}
@Override
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
return true;
}
@Override
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object level = args[0];
Object pos = args[1];
Object blockState = args[2];
Object fluidState = args[3];
Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(fluidState);
if (fluidType == MFluids.LAVA || fluidType == MFluids.FLOWING_LAVA) {
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.LAVA_CONVERTS_BLOCK, pos, 0);
} else {
FastNMS.INSTANCE.method$Block$dropResources(blockState, level, pos);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, FastNMS.INSTANCE.method$FluidState$createLegacyBlock(fluidState), UpdateOption.UPDATE_ALL.flags());
return true;
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
return new LiquidFlowableBlockBehavior(block);
}
}
}

View File

@@ -5,7 +5,8 @@ import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.EntityBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.TriggerOnceBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.FallOnBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.PlaceLiquidBlockBehavior;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.item.context.UseOnContext;
@@ -15,7 +16,8 @@ import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior implements TriggerOnceBlockBehavior {
public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior
implements FallOnBlockBehavior, PlaceLiquidBlockBehavior {
private final AbstractBlockBehavior[] behaviors;
public UnsafeCompositeBlockBehavior(CustomBlock customBlock, List<AbstractBlockBehavior> behaviors) {
@@ -23,6 +25,26 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior implements
this.behaviors = behaviors.toArray(new AbstractBlockBehavior[0]);
}
@Override
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
for (AbstractBlockBehavior behavior : behaviors) {
if (behavior instanceof PlaceLiquidBlockBehavior) {
return behavior.canPlaceLiquid(thisBlock, args, superMethod);
}
}
return super.canPlaceLiquid(thisBlock, args, superMethod);
}
@Override
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
for (AbstractBlockBehavior behavior : behaviors) {
if (behavior instanceof PlaceLiquidBlockBehavior) {
return behavior.placeLiquid(thisBlock, args, superMethod);
}
}
return super.placeLiquid(thisBlock, args, superMethod);
}
@SuppressWarnings("unchecked")
@Override
public <T extends BlockBehavior> Optional<T> getAs(Class<T> tClass) {
@@ -341,22 +363,22 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior implements
@Override
public void fallOn(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
for (AbstractBlockBehavior behavior : this.behaviors) {
if (behavior instanceof TriggerOnceBlockBehavior f) {
if (behavior instanceof FallOnBlockBehavior f) {
f.fallOn(thisBlock, args, superMethod);
return;
}
}
TriggerOnceBlockBehavior.super.fallOn(thisBlock, args, superMethod);
FallOnBlockBehavior.super.fallOn(thisBlock, args, superMethod);
}
@Override
public void updateEntityMovementAfterFallOn(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
for (AbstractBlockBehavior behavior : this.behaviors) {
if (behavior instanceof TriggerOnceBlockBehavior f) {
if (behavior instanceof FallOnBlockBehavior f) {
f.updateEntityMovementAfterFallOn(thisBlock, args, superMethod);
return;
}
}
TriggerOnceBlockBehavior.super.updateEntityMovementAfterFallOn(thisBlock, args, superMethod);
FallOnBlockBehavior.super.updateEntityMovementAfterFallOn(thisBlock, args, superMethod);
}
}

View File

@@ -41,7 +41,7 @@ public class SimpleStorageBlockEntity extends BlockEntity {
super(BukkitBlockEntityTypes.SIMPLE_STORAGE, pos, blockState);
this.behavior = super.blockState.behavior().getAs(SimpleStorageBlockBehavior.class).orElseThrow();
BlockEntityHolder holder = new BlockEntityHolder(this);
this.inventory = FastNMS.INSTANCE.createCraftEngineWorldlyContainer(holder, this.behavior.rows() * 9, this.behavior.canPlaceItem(), this.behavior.canTakeItem());
this.inventory = FastNMS.INSTANCE.createSimpleStorageContainer(holder, this.behavior.rows() * 9, this.behavior.canPlaceItem(), this.behavior.canTakeItem());
holder.setInventory(this.inventory);
}

View File

@@ -90,7 +90,7 @@ public class BukkitGuiManager implements GuiManager, Listener {
@Override
public Inventory createInventory(Gui gui, int size) {
CraftEngineGUIHolder holder = new CraftEngineGUIHolder(gui);
org.bukkit.inventory.Inventory inventory = FastNMS.INSTANCE.createCraftEngineWorldlyContainer(holder, size, false, false);
org.bukkit.inventory.Inventory inventory = FastNMS.INSTANCE.createSimpleStorageContainer(holder, size, false, false);
holder.holder().bindValue(inventory);
return new BukkitInventory(inventory);
}

View File

@@ -23,7 +23,7 @@ import net.momirealms.craftengine.core.block.BlockKeys;
import net.momirealms.craftengine.core.block.BlockShape;
import net.momirealms.craftengine.core.block.DelegatingBlock;
import net.momirealms.craftengine.core.block.behavior.EmptyBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.TriggerOnceBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.special.FallOnBlockBehavior;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.Key;
@@ -715,7 +715,7 @@ public final class BlockGenerator {
public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
try {
if (holder.value() instanceof TriggerOnceBlockBehavior behavior) {
if (holder.value() instanceof FallOnBlockBehavior behavior) {
behavior.fallOn(thisObj, args, superMethod);
} else {
superMethod.call();
@@ -733,7 +733,7 @@ public final class BlockGenerator {
public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
try {
if (holder.value() instanceof TriggerOnceBlockBehavior behavior) {
if (holder.value() instanceof FallOnBlockBehavior behavior) {
behavior.updateEntityMovementAfterFallOn(thisObj, args, superMethod);
} else {
superMethod.call();

View File

@@ -63,10 +63,11 @@ blocks:
item: default:amethyst_standing_torch
scale: 1.01
behavior:
type: sturdy_base_block
direction: down
support-types:
- center
- type: sturdy_base_block
direction: down
support-types:
- center
- type: liquid_flowable_block
default:amethyst_wall_torch:
loot:
template: default:loot_table/basic
@@ -83,7 +84,8 @@ blocks:
luminance: 15
item: default:amethyst_torch
behavior:
type: directional_attached_block
- type: directional_attached_block
- type: liquid_flowable_block
states:
properties:
facing:

View File

@@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.block.behavior.special;
import java.util.concurrent.Callable;
public interface TriggerOnceBlockBehavior {
public interface FallOnBlockBehavior {
// 1.20.1~1.21.4 Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance
// 1.21.5+ Level level, BlockState state, BlockPos pos, Entity entity, double fallDistance

View File

@@ -0,0 +1,10 @@
package net.momirealms.craftengine.core.block.behavior.special;
import java.util.concurrent.Callable;
public interface PlaceLiquidBlockBehavior {
boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod);
boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod);
}

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3
snake_yaml_version=2.5
anti_grief_version=0.20
nms_helper_version=1.0.86
nms_helper_version=1.0.87
evalex_version=3.5.0
reactive_streams_version=1.0.4
amazon_awssdk_version=2.33.1