From 69e5d24d7773a7e411a93382f15904f7abbf74a1 Mon Sep 17 00:00:00 2001 From: MaXFeeD Date: Sun, 11 Feb 2024 02:31:22 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BA=D0=B0=D0=BB=D0=B1=D0=B5=D0=BA?= =?UTF-8?q?=D0=B0=20ItemDispensed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Превент действия отменяет дроп, позволяя задать пользовательское поведение. --- src/main/java/com/reider745/Main.java | 2 + .../event/DispenseBehaviorOverrides.java | 68 +++++++++++++++++++ .../com/reider745/event/EventListener.java | 2 - 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/reider745/event/DispenseBehaviorOverrides.java diff --git a/src/main/java/com/reider745/Main.java b/src/main/java/com/reider745/Main.java index 19a695dc..f5c2797b 100644 --- a/src/main/java/com/reider745/Main.java +++ b/src/main/java/com/reider745/Main.java @@ -6,6 +6,7 @@ import cn.nukkit.network.Network; import java.util.Arrays; import com.reider745.api.hooks.JarEditor; +import com.reider745.event.DispenseBehaviorOverrides; import com.reider745.hooks.*; import com.reider745.hooks.bugfix.DimensionsFix; import com.reider745.hooks.bugfix.EntityItemHooks; @@ -79,6 +80,7 @@ public class Main { loader.registerHooksInitializationForClass(LevelHooks.class); loader.registerHooksInitializationForClass(ItemUtils.class); loader.registerHooksInitializationForClass(EntityOverrides.class); + loader.registerHooksInitializationForClass(DispenseBehaviorOverrides.class); loader.registerHooksInitializationForClass(AndroidHooks.class); if (Arrays.stream(args).anyMatch("--snowfall-everywhere"::equals)) { diff --git a/src/main/java/com/reider745/event/DispenseBehaviorOverrides.java b/src/main/java/com/reider745/event/DispenseBehaviorOverrides.java new file mode 100644 index 00000000..1b92bd97 --- /dev/null +++ b/src/main/java/com/reider745/event/DispenseBehaviorOverrides.java @@ -0,0 +1,68 @@ +package com.reider745.event; + +import com.reider745.api.hooks.HookClass; +import com.reider745.api.hooks.HookController; +import com.reider745.api.hooks.TypeHook; +import com.reider745.api.hooks.annotation.Hooks; +import com.reider745.api.hooks.annotation.Inject; +import com.reider745.hooks.ItemUtils; +import com.zhekasmirnov.innercore.api.NativeCallback; + +import cn.nukkit.block.BlockDispenser; +import cn.nukkit.dispenser.DefaultDispenseBehavior; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.block.BlockEvent; +import cn.nukkit.item.Item; +import cn.nukkit.math.BlockFace; +import cn.nukkit.math.BlockFace.Axis; +import javassist.CannotCompileException; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; +import cn.nukkit.math.Vector3; + +@Hooks(className = "cn.nukkit.block.BlockDispenser") +public class DispenseBehaviorOverrides implements HookClass { + public static int dispenseSlot = -1; + + @Override + public void init(CtClass ctClass) { + try { + CtMethod dispenseMethod = ctClass.getDeclaredMethod("dispense"); + dispenseMethod.insertAt(dispenseMethod.getMethodInfo().getLineNumber(310), + "com.reider745.event.DispenseBehaviorOverrides.dispenseSlot = slot;"); + } catch (NotFoundException | CannotCompileException e) { + System.out.println("Nukkit-MOT has been updated and overrides for `BlockDispenser.dispense` method are no longer available."); + } + } + + public static class BlockDispenseEvent extends BlockEvent implements Cancellable { + public BlockDispenseEvent(BlockDispenser block) { + super(block); + } + } + + @Inject(className = "cn.nukkit.dispenser.DefaultDispenseBehavior", type = TypeHook.BEFORE, signature = "(Lcn/nukkit/block/BlockDispenser;Lcn/nukkit/math/BlockFace;Lcn/nukkit/item/Item;)Lcn/nukkit/item/Item;") + public static void dispense(HookController controller, DefaultDispenseBehavior behavior, BlockDispenser block, + BlockFace face, Item item) { + Vector3 dispensePos = block.getDispensePosition(); + + if (face.getAxis() == Axis.Y) { + dispensePos.y -= 0.125; + } else { + dispensePos.y -= 0.15625; + } + + BlockDispenseEvent event = new BlockDispenseEvent(block); + EventListener.consumeEvent(event, + () -> NativeCallback.onItemDispensed((float) dispensePos.x, (float) dispensePos.y, + (float) dispensePos.z, face.getIndex(), item.getId(), item.getCount(), item.getDamage(), + ItemUtils.getItemInstanceExtra(item), block.getLevel(), dispenseSlot)); + dispenseSlot = -1; + + if (event.isCancelled()) { + controller.setReplace(true); + controller.setResult(null); + } + } +} diff --git a/src/main/java/com/reider745/event/EventListener.java b/src/main/java/com/reider745/event/EventListener.java index 2ab4ca92..56b35ff6 100644 --- a/src/main/java/com/reider745/event/EventListener.java +++ b/src/main/java/com/reider745/event/EventListener.java @@ -478,6 +478,4 @@ public class EventListener implements Listener { // TODO: onItemUseReleased (not only custom items) // TODO: onItemUseComplete (not only custom items) - - // TODO: onItemDispensed }