mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 18:09:27 +00:00
大宝贝
This commit is contained in:
@@ -1,12 +1,21 @@
|
||||
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.plugin.reflection.minecraft.MItems;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
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.util.VersionHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class WaterLoggedBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
@@ -18,64 +27,52 @@ public class WaterLoggedBlockBehavior extends BukkitBlockBehavior {
|
||||
this.waterloggedProperty = waterloggedProperty;
|
||||
}
|
||||
|
||||
// TODO create real waterlogged blocks, needs to have real waterlogged property
|
||||
// @Override
|
||||
// public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// if (this.waterloggedProperty == null) return Reflections.instance$ItemStack$EMPTY;
|
||||
// Object blockState;
|
||||
// Object world;
|
||||
// Object pos;
|
||||
// if (VersionHelper.isVersionNewerThan1_20_2()) {
|
||||
// world = args[1];
|
||||
// pos = args[2];
|
||||
// blockState = args[3];
|
||||
// } else {
|
||||
// world = args[0];
|
||||
// pos = args[1];
|
||||
// blockState = args[2];
|
||||
// }
|
||||
// ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (immutableBlockState != null) {
|
||||
// if (immutableBlockState.get(this.waterloggedProperty)) {
|
||||
// Reflections.method$LevelWriter$setBlock.invoke(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
|
||||
// // TODO check can survive
|
||||
// Object itemStack = Reflections.constructor$ItemStack.newInstance(Reflections.instance$Items$WATER_BUCKET);
|
||||
// return itemStack;
|
||||
// }
|
||||
// }
|
||||
// return Reflections.instance$ItemStack$EMPTY;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// if (this.waterloggedProperty == null) return false;
|
||||
// Object blockState = args[2];
|
||||
// ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (immutableBlockState != null) {
|
||||
// Object fluidType = Reflections.method$FluidState$getType.invoke(args[3]);
|
||||
// if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == Reflections.instance$Fluids$WATER) {
|
||||
// Reflections.method$LevelWriter$setBlock.invoke(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
|
||||
// Reflections.method$LevelAccessor$scheduleTick.invoke(args[0], fluidType, Reflections.method$Fluid$getTickDelay.invoke(fluidType, args[0]));
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // use water
|
||||
// @Override
|
||||
// public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return super.canPlaceLiquid(thisBlock, args, superMethod);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Object getFluidState(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// Object blockState = args[0];
|
||||
// ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (state == null || state.isEmpty() || this.waterloggedProperty == null) return super.getFluidState(thisBlock, args, superMethod);
|
||||
// boolean waterlogged = state.get(this.waterloggedProperty);
|
||||
// return waterlogged ? Reflections.method$FlowingFluid$getSource.invoke(Reflections.instance$Fluids$WATER, false) : super.getFluidState(thisBlock, args, superMethod);
|
||||
// }
|
||||
@Override
|
||||
public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return CoreReflections.instance$ItemStack$EMPTY;
|
||||
Object blockState;
|
||||
Object world;
|
||||
Object pos;
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
world = args[1];
|
||||
pos = args[2];
|
||||
blockState = args[3];
|
||||
} else {
|
||||
world = args[0];
|
||||
pos = args[1];
|
||||
blockState = args[2];
|
||||
}
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState != null) {
|
||||
if (immutableBlockState.get(this.waterloggedProperty)) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
|
||||
return FastNMS.INSTANCE.constructor$ItemStack(MItems.WATER_BUCKET, 1);
|
||||
}
|
||||
}
|
||||
return CoreReflections.instance$ItemStack$EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
Object blockState = args[2];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState != null) {
|
||||
Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(args[3]);
|
||||
if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == MFluids.WATER) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(args[0], args[1], fluidType, 5);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
return (VersionHelper.isOrAbove1_20_2() ? args[4] : args[3]) == MFluids.WATER;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||
import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener;
|
||||
import net.momirealms.craftengine.bukkit.item.listener.DebugStickListener;
|
||||
@@ -40,8 +38,8 @@ import java.util.Set;
|
||||
|
||||
public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
static {
|
||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
// registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
// registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.bukkit.FluidCollisionMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.RayTraceResult;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class BucketItemBehavior extends ItemBehavior {
|
||||
public static final BucketItemBehavior INSTANCE = new BucketItemBehavior();
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
return use(context.getLevel(), context.getPlayer(), context.getHand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(net.momirealms.craftengine.core.world.World world, net.momirealms.craftengine.core.entity.player.Player player, InteractionHand hand) {
|
||||
if (player.isAdventureMode()) return InteractionResult.PASS;
|
||||
Player bukkitPlayer = (Player) player.platformPlayer();
|
||||
RayTraceResult result = bukkitPlayer.rayTraceBlocks(player.getCachedInteractionRange(), FluidCollisionMode.SOURCE_ONLY);
|
||||
if (result == null) return InteractionResult.PASS;
|
||||
Block block = result.getHitBlock();
|
||||
if (block == null) return InteractionResult.PASS;
|
||||
return tryFillBucket(world, player, hand, new BlockPos(block.getX(), block.getY(), block.getZ()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private InteractionResult tryFillBucket(net.momirealms.craftengine.core.world.World world,
|
||||
net.momirealms.craftengine.core.entity.player.Player player,
|
||||
InteractionHand hand,
|
||||
BlockPos pos) {
|
||||
Object nmsPos = LocationUtils.toBlockPos(pos.x(), pos.y(), pos.z());
|
||||
Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(world.serverWorld(), nmsPos);
|
||||
ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (customState == null || customState.isEmpty()) return InteractionResult.PASS;
|
||||
CustomBlock customBlock = customState.owner().value();
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) customBlock.getProperty("waterlogged");
|
||||
if (waterlogged == null) return InteractionResult.PASS;
|
||||
boolean waterloggedState = customState.get(waterlogged);
|
||||
if (!waterloggedState) return InteractionResult.PASS;
|
||||
EquipmentSlot slot = hand == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND;
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), nmsPos, customState.with(waterlogged, false).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
|
||||
Player bukkitPlayer = (Player) player.platformPlayer();
|
||||
if (player.isSurvivalMode()) {
|
||||
// to prevent dupe in moment
|
||||
bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.AIR));
|
||||
if (VersionHelper.isFolia()) {
|
||||
bukkitPlayer.getScheduler().run(BukkitCraftEngine.instance().javaPlugin(), (t) -> bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.WATER_BUCKET)), () -> {});
|
||||
} else {
|
||||
BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.WATER_BUCKET)));
|
||||
}
|
||||
}
|
||||
bukkitPlayer.setStatistic(Statistic.USE_ITEM, Material.BUCKET, bukkitPlayer.getStatistic(Statistic.USE_ITEM, Material.BUCKET) + 1);
|
||||
// client will assume it has sounds
|
||||
// context.getPlayer().level().playBlockSound(Vec3d.atCenterOf(context.getClickedPos()), ITEM_BUCKET_FILL, 1, 1);
|
||||
return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
public static final Key BLOCK_ITEM = Key.from("craftengine:block_item");
|
||||
public static final Key ON_LIQUID_BLOCK_ITEM = Key.from("craftengine:liquid_collision_block_item");
|
||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||
public static final Key FLINT_AND_STEEL_ITEM = Key.from("craftengine:flint_and_steel_item");
|
||||
public static final Key COMPOSTABLE_ITEM = Key.from("craftengine:compostable_item");
|
||||
|
||||
@@ -18,8 +16,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
register(BLOCK_ITEM, BlockItemBehavior.FACTORY);
|
||||
register(ON_LIQUID_BLOCK_ITEM, LiquidCollisionBlockItemBehavior.FACTORY);
|
||||
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||
register(BUCKET_ITEM, BucketItemBehavior.FACTORY);
|
||||
register(FLINT_AND_STEEL_ITEM, FlintAndSteelItemBehavior.FACTORY);
|
||||
register(COMPOSTABLE_ITEM, CompostableItemBehavior.FACTORY);
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
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.bukkit.world.BukkitBlockInWorld;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class WaterBucketItemBehavior extends ItemBehavior {
|
||||
public static final WaterBucketItemBehavior INSTANCE = new WaterBucketItemBehavior();
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
// todo 需要修复不完整方块取水
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
if (context.getPlayer().isAdventureMode()) return InteractionResult.PASS;
|
||||
BlockPos pos = context.getClickedPos();
|
||||
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(pos);
|
||||
Block block = clicked.block();
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData()));
|
||||
if (state == null || state.isEmpty()) return InteractionResult.PASS;
|
||||
CustomBlock customBlock = state.owner().value();
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) customBlock.getProperty("waterlogged");
|
||||
if (waterlogged == null) return InteractionResult.PASS;
|
||||
|
||||
Player player = (Player) context.getPlayer().platformPlayer();
|
||||
World world = player.getWorld();
|
||||
Location location = new Location(world, pos.x(), pos.y(), pos.z());
|
||||
|
||||
// TODO Refactor all of this because it's playing a trick with the server
|
||||
ImmutableBlockState nextState = state.with(waterlogged, true);
|
||||
block.setBlockData(BlockStateUtils.fromBlockData(nextState.vanillaBlockState().handle()), false);
|
||||
// actually we should broadcast this change
|
||||
context.getPlayer().sendPacket(BlockStateUtils.createBlockUpdatePacket(pos, state), true);
|
||||
BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> {
|
||||
Object blockPos = LocationUtils.toBlockPos(pos);
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world), blockPos, nextState.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world), blockPos, MFluids.WATER, 5);
|
||||
}, world, location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public final class BlockGenerator {
|
||||
// should always implement this interface
|
||||
.implement(CoreReflections.clazz$Fallable)
|
||||
.implement(CoreReflections.clazz$BonemealableBlock)
|
||||
// TODO .implement(CoreReflections.clazz$SimpleWaterloggedBlock)
|
||||
.implement(CoreReflections.clazz$SimpleWaterloggedBlock)
|
||||
// internal interfaces
|
||||
.implement(BehaviorHolder.class)
|
||||
.implement(ShapeHolder.class)
|
||||
@@ -152,7 +152,16 @@ public final class BlockGenerator {
|
||||
.intercept(MethodDelegation.to(OnExplosionHitInterceptor.INSTANCE))
|
||||
// neighborChanged
|
||||
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$neighborChanged))
|
||||
.intercept(MethodDelegation.to(NeighborChangedInterceptor.INSTANCE));
|
||||
.intercept(MethodDelegation.to(NeighborChangedInterceptor.INSTANCE))
|
||||
// pickupBlock
|
||||
.method(ElementMatchers.is(CoreReflections.method$SimpleWaterloggedBlock$pickupBlock))
|
||||
.intercept(MethodDelegation.to(PickUpBlockInterceptor.INSTANCE))
|
||||
// placeLiquid
|
||||
.method(ElementMatchers.is(CoreReflections.method$SimpleWaterloggedBlock$placeLiquid))
|
||||
.intercept(MethodDelegation.to(PlaceLiquidInterceptor.INSTANCE))
|
||||
// canPlaceLiquid
|
||||
.method(ElementMatchers.is(CoreReflections.method$SimpleWaterloggedBlock$canPlaceLiquid))
|
||||
.intercept(MethodDelegation.to(CanPlaceLiquidInterceptor.INSTANCE));
|
||||
Class<?> clazz$CraftEngineBlock = builder.make().load(BlockGenerator.class.getClassLoader()).getLoaded();
|
||||
constructor$CraftEngineBlock = MethodHandles.publicLookup().in(clazz$CraftEngineBlock)
|
||||
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$BlockBehaviour$Properties))
|
||||
@@ -468,4 +477,49 @@ public final class BlockGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PickUpBlockInterceptor {
|
||||
public static final PickUpBlockInterceptor INSTANCE = new PickUpBlockInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
try {
|
||||
return holder.value().pickupBlock(thisObj, args, () -> CoreReflections.instance$ItemStack$EMPTY);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run pickupBlock", e);
|
||||
return CoreReflections.instance$ItemStack$EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlaceLiquidInterceptor {
|
||||
public static final PlaceLiquidInterceptor INSTANCE = new PlaceLiquidInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public boolean intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) throws Exception {
|
||||
ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
try {
|
||||
return holder.value().placeLiquid(thisObj, args, superMethod);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run placeLiquid", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CanPlaceLiquidInterceptor {
|
||||
public static final CanPlaceLiquidInterceptor INSTANCE = new CanPlaceLiquidInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public boolean intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
try {
|
||||
return holder.value().canPlaceLiquid(thisObj, args, superMethod);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run canPlaceLiquid", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,4 +98,16 @@ public abstract class BlockBehavior {
|
||||
public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user