diff --git a/src/main/java/com/chattriggers/ctjs/mixins/ClientPlayerInteractionManagerMixin.java b/src/main/java/com/chattriggers/ctjs/mixins/ClientPlayerInteractionManagerMixin.java index 55b93b6f..dafdd969 100644 --- a/src/main/java/com/chattriggers/ctjs/mixins/ClientPlayerInteractionManagerMixin.java +++ b/src/main/java/com/chattriggers/ctjs/mixins/ClientPlayerInteractionManagerMixin.java @@ -1,11 +1,8 @@ package com.chattriggers.ctjs.mixins; -import com.chattriggers.ctjs.minecraft.wrappers.World; -import com.chattriggers.ctjs.minecraft.wrappers.world.block.BlockFace; -import com.chattriggers.ctjs.triggers.TriggerType; +import com.chattriggers.ctjs.minecraft.CTEvents; import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -13,13 +10,14 @@ @Mixin(ClientPlayerInteractionManager.class) public class ClientPlayerInteractionManagerMixin { - @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) - void injectAttackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - TriggerType.HIT_BLOCK.triggerAll(World.getBlockAt(pos.getX(), pos.getY(), pos.getZ()).withFace(BlockFace.fromMC(direction)), cir); - } - - @Inject(method = "breakBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;onBreak(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/entity/player/PlayerEntity;)V")) - void injectBreakBlock(BlockPos pos, CallbackInfoReturnable cir) { - TriggerType.BREAK_BLOCK.triggerAll(World.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + @Inject( + method = "breakBlock", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/Block;onBreak(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/entity/player/PlayerEntity;)V" + ) + ) + private void injectBreakBlock(BlockPos pos, CallbackInfoReturnable cir) { + CTEvents.BREAK_BLOCK.invoker().breakBlock(pos); } } diff --git a/src/main/kotlin/com/chattriggers/ctjs/engine/IRegister.kt b/src/main/kotlin/com/chattriggers/ctjs/engine/IRegister.kt index ef512c94..ce1ab8f1 100644 --- a/src/main/kotlin/com/chattriggers/ctjs/engine/IRegister.kt +++ b/src/main/kotlin/com/chattriggers/ctjs/engine/IRegister.kt @@ -473,23 +473,6 @@ interface IRegister { return EventTrigger(method, TriggerType.PLAYER_INTERACT, getImplementationLoader()) } - // TODO(breaking): Rename from blockbreak to breakblock - /** - * Registers a new trigger that runs before the player breaks a block - * - * Passes through one argument: - * - The block - * - * Available modifications: - * - [Trigger.setPriority] Sets the priority - * - * @param method The method to call when the event is fired - * @return The trigger for additional modification - */ - fun registerBreakBlock(method: Any): RegularTrigger { - return RegularTrigger(method, TriggerType.BREAK_BLOCK, getImplementationLoader()) - } - /** * Registers a new trigger that runs before an entity is damaged * @@ -754,25 +737,7 @@ interface IRegister { return EventTrigger(method, TriggerType.SPAWN_PARTICLE, getImplementationLoader()) } - /** - * Registers a new trigger that runs whenever a block is left clicked - * - * Note: this is not continuously called while the block is being broken, only once - * when first left clicked. - * - * Passes through two arguments: - * - The [com.chattriggers.ctjs.minecraft.wrappers.world.block.Block] being hit - * - The event, which can be cancelled - * - * Available modifications: - * - [Trigger.setPriority] Sets the priority - * - * @param method The method to call when the event is fired - * @return The trigger for additional modification - */ - fun registerHitBlock(method: Any): EventTrigger { - return EventTrigger(method, TriggerType.HIT_BLOCK, getImplementationLoader()) - } + // TODO(breaking): Removed hitblock & breakblock triggers. use playerinteract instead /** * Registers a new trigger that runs on a mixin event diff --git a/src/main/kotlin/com/chattriggers/ctjs/minecraft/CTEvents.kt b/src/main/kotlin/com/chattriggers/ctjs/minecraft/CTEvents.kt index 5fb181fa..599fde96 100644 --- a/src/main/kotlin/com/chattriggers/ctjs/minecraft/CTEvents.kt +++ b/src/main/kotlin/com/chattriggers/ctjs/minecraft/CTEvents.kt @@ -4,6 +4,7 @@ import com.chattriggers.ctjs.minecraft.CTEvents.PacketReceivedCallback import com.chattriggers.ctjs.minecraft.CTEvents.RenderScreenCallback import com.chattriggers.ctjs.minecraft.CTEvents.VoidCallback import com.chattriggers.ctjs.utils.MCBlockEntity +import com.chattriggers.ctjs.utils.MCBlockPos import com.chattriggers.ctjs.utils.MCEntity import net.fabricmc.fabric.api.event.EventFactory import net.minecraft.client.gui.Drawable @@ -57,6 +58,10 @@ internal object CTEvents { fun process(dx: Double, dy: Double, mouseX: Double, mouseY: Double, button: Int, gui: Screen, ci: CallbackInfo) } + fun interface BreakBlockCallback { + fun breakBlock(pos: MCBlockPos) + } + @JvmField val PRE_RENDER_OVERLAY = make { listeners -> RenderScreenCallback { stack, mouseX, mouseY, drawable, partialTicks -> @@ -144,5 +149,12 @@ internal object CTEvents { } } + @JvmField + val BREAK_BLOCK = make { listeners -> + BreakBlockCallback { pos -> + listeners.forEach { it.breakBlock(pos) } + } + } + private inline fun make(noinline reducer: (Array) -> T) = EventFactory.createArrayBacked(T::class.java, reducer) } diff --git a/src/main/kotlin/com/chattriggers/ctjs/minecraft/listeners/ClientListener.kt b/src/main/kotlin/com/chattriggers/ctjs/minecraft/listeners/ClientListener.kt index 881c992f..58a8e89a 100644 --- a/src/main/kotlin/com/chattriggers/ctjs/minecraft/listeners/ClientListener.kt +++ b/src/main/kotlin/com/chattriggers/ctjs/minecraft/listeners/ClientListener.kt @@ -18,6 +18,7 @@ import com.chattriggers.ctjs.utils.Config import com.chattriggers.ctjs.utils.Initializer import com.chattriggers.ctjs.console.printToConsole import com.chattriggers.ctjs.engine.module.ModuleManager +import com.chattriggers.ctjs.minecraft.wrappers.inventory.Item import gg.essential.universal.UMatrixStack import gg.essential.universal.UMinecraft import gg.essential.universal.wrappers.message.UTextComponent @@ -35,6 +36,7 @@ import net.fabricmc.fabric.api.event.player.UseEntityCallback import net.fabricmc.fabric.api.event.player.UseItemCallback import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.ActionResult +import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import org.lwjgl.glfw.GLFW import org.mozilla.javascript.Context @@ -191,11 +193,12 @@ object ClientListener : Initializer { } } - AttackBlockCallback.EVENT.register { _, _, _, pos, direction -> + AttackBlockCallback.EVENT.register { player, _, _, pos, direction -> + if (!player.world.isClient) return@register ActionResult.PASS val event = CancellableEvent() TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.ATTACK_BLOCK, + PlayerInteraction.AttackBlock, World.getBlockAt(BlockPos(pos)).withFace(BlockFace.fromMC(direction)), event, ) @@ -203,11 +206,12 @@ object ClientListener : Initializer { if (event.isCancelled()) ActionResult.FAIL else ActionResult.PASS } - AttackEntityCallback.EVENT.register { _, _, _, entity, _ -> + AttackEntityCallback.EVENT.register { player, _, _, entity, _ -> + if (!player.world.isClient) return@register ActionResult.PASS val event = CancellableEvent() TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.ATTACK_ENTITY, + PlayerInteraction.AttackEntity, Entity.fromMC(entity), event, ) @@ -215,23 +219,20 @@ object ClientListener : Initializer { if (event.isCancelled()) ActionResult.FAIL else ActionResult.PASS } - PlayerBlockBreakEvents.BEFORE.register { _, _, pos, state, _ -> - val event = CancellableEvent() - + CTEvents.BREAK_BLOCK.register { pos -> TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.BREAK_BLOCK, - Block(BlockType(state.block), BlockPos(pos)), - event, + PlayerInteraction.BreakBlock, + World.getBlockAt(BlockPos(pos)), + CancellableEvent(), ) - - !event.isCancelled() } - UseBlockCallback.EVENT.register { _, _, _, hitResult -> + UseBlockCallback.EVENT.register { player, _, hand, hitResult -> + if (!player.world.isClient) return@register ActionResult.PASS val event = CancellableEvent() TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.USE_BLOCK, + PlayerInteraction.UseBlock(hand), World.getBlockAt(BlockPos(hitResult.blockPos)).withFace(BlockFace.fromMC(hitResult.side)), event, ) @@ -239,25 +240,29 @@ object ClientListener : Initializer { if (event.isCancelled()) ActionResult.FAIL else ActionResult.PASS } - UseEntityCallback.EVENT.register { _, _, _, entity, _ -> + UseEntityCallback.EVENT.register { player, _, hand, entity, _ -> + if (!player.world.isClient) return@register ActionResult.PASS val event = CancellableEvent() TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.USE_ENTITY, + PlayerInteraction.UseEntity(hand), Entity.fromMC(entity), - event + event, ) if (event.isCancelled()) ActionResult.FAIL else ActionResult.PASS } - UseItemCallback.EVENT.register { _, _, _ -> + UseItemCallback.EVENT.register { player, _, hand -> + if (!player.world.isClient) return@register TypedActionResult.pass(null) val event = CancellableEvent() + val stack = player.getStackInHand(hand) + TriggerType.PLAYER_INTERACT.triggerAll( - PlayerInteraction.USE_ITEM, - // TODO, - event + PlayerInteraction.UseItem(hand), + if (stack.isEmpty) null else Item(stack), + event, ) if (event.isCancelled()) TypedActionResult.fail(null) else TypedActionResult.pass(null) @@ -277,12 +282,12 @@ object ClientListener : Initializer { } // TODO(breaking): Difference cases here - enum class PlayerInteraction(val isLeftHand: Boolean) { - ATTACK_BLOCK(true), - ATTACK_ENTITY(true), - BREAK_BLOCK(true), - USE_BLOCK(false), - USE_ENTITY(false), - USE_ITEM(false), + sealed class PlayerInteraction(val mainHand: Boolean) { + object AttackBlock : PlayerInteraction(true) + object AttackEntity : PlayerInteraction(true) + object BreakBlock : PlayerInteraction(true) + class UseBlock(hand: Hand) : PlayerInteraction(hand == Hand.MAIN_HAND) + class UseEntity(hand: Hand) : PlayerInteraction(hand == Hand.MAIN_HAND) + class UseItem(hand: Hand) : PlayerInteraction(hand == Hand.MAIN_HAND) } } diff --git a/src/main/kotlin/com/chattriggers/ctjs/triggers/TriggerType.kt b/src/main/kotlin/com/chattriggers/ctjs/triggers/TriggerType.kt index 53547bfa..bf3ce457 100644 --- a/src/main/kotlin/com/chattriggers/ctjs/triggers/TriggerType.kt +++ b/src/main/kotlin/com/chattriggers/ctjs/triggers/TriggerType.kt @@ -26,8 +26,6 @@ enum class TriggerType : ITriggerType { MESSAGE_SENT, ITEM_TOOLTIP, PLAYER_INTERACT, - HIT_BLOCK, - BREAK_BLOCK, GUI_KEY, GUI_MOUSE_CLICK, GUI_MOUSE_DRAG,