Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions api/src/main/java/kr/toxicity/model/api/nms/HitBoxListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
package kr.toxicity.model.api.nms;

import kr.toxicity.model.api.event.ModelDamageSource;
import kr.toxicity.model.api.event.ModelInteractAtEvent;
import kr.toxicity.model.api.event.ModelInteractEvent;
import kr.toxicity.model.api.platform.PlatformEntity;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -49,6 +51,8 @@ public interface HitBoxListener {
return new Builder()
.sync(this::sync)
.damage(this::damage)
.interact(this::interact)
.interactAt(this::interactAt)
.remove(this::remove)
.mount(this::mount)
.dismount(this::dismount);
Expand All @@ -63,12 +67,16 @@ class Builder {

private static final Consumer<HitBox> DEFAULT_SYNC = h -> {};
private static final OnDamage DEFAULT_DAMAGE = (h, s, d) -> false;
private static final Consumer<ModelInteractEvent> DEFAULT_INTERACT = h -> {};
private static final Consumer<ModelInteractAtEvent> DEFAULT_INTERACT_AT = h -> {};
private static final Consumer<HitBox> DEFAULT_REMOVE = h -> {};
private static final BiConsumer<HitBox, PlatformEntity> DEFAULT_MOUNT = (h, e) -> {};
private static final BiConsumer<HitBox, PlatformEntity> DEFAULT_DISMOUNT = (h, e) -> {};

private Consumer<HitBox> sync = DEFAULT_SYNC;
private OnDamage damage = DEFAULT_DAMAGE;
private Consumer<ModelInteractEvent> interact = DEFAULT_INTERACT;
private Consumer<ModelInteractAtEvent> interactAt = DEFAULT_INTERACT_AT;
private Consumer<HitBox> remove = DEFAULT_REMOVE;
private BiConsumer<HitBox, PlatformEntity> mount = DEFAULT_MOUNT;
private BiConsumer<HitBox, PlatformEntity> dismount = DEFAULT_DISMOUNT;
Expand Down Expand Up @@ -103,6 +111,30 @@ private Builder() {
return this;
}

/**
* Adds an interact handler.
*
* @param interact the interact handler
* @return this builder
* @since 2.0.2
*/
public @NotNull Builder interact(@NotNull Consumer<ModelInteractEvent> interact) {
this.interact = this.interact == DEFAULT_INTERACT ? interact : this.interact.andThen(interact);
return this;
}

/**
* Adds an interact-at handler.
*
* @param interactAt the interact-at handler
* @return this builder
* @since 2.0.2
*/
public @NotNull Builder interactAt(@NotNull Consumer<ModelInteractAtEvent> interactAt) {
this.interactAt = this.interactAt == DEFAULT_INTERACT_AT ? interactAt : this.interactAt.andThen(interactAt);
return this;
}

/**
* Adds a remove handler.
*
Expand Down Expand Up @@ -157,6 +189,16 @@ public boolean damage(@NotNull HitBox hitBox, @NotNull ModelDamageSource source,
return Builder.this.damage.event(hitBox, source, damage);
}

@Override
public void interact(@NotNull ModelInteractEvent event) {
interact.accept(event);
}

@Override
public void interactAt(@NotNull ModelInteractAtEvent event) {
interactAt.accept(event);
}

@Override
public void remove(@NotNull HitBox hitBox) {
remove.accept(hitBox);
Expand Down Expand Up @@ -224,6 +266,22 @@ interface OnDamage {
*/
boolean damage(@NotNull HitBox hitBox, @NotNull ModelDamageSource source, double damage);

/**
* Called when the hitbox receives an interaction.
*
* @param event the interaction event
* @since 2.0.2
*/
void interact(@NotNull ModelInteractEvent event);

/**
* Called when the hitbox receives an interaction at a specific position.
*
* @param event the interaction-at event
* @since 2.0.2
*/
void interactAt(@NotNull ModelInteractAtEvent event);

/**
* Called when the hitbox is removed.
*
Expand Down
21 changes: 21 additions & 0 deletions api/src/main/java/kr/toxicity/model/api/tracker/Tracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.function.Supplier;
Expand Down Expand Up @@ -678,6 +679,26 @@ public boolean replace(@NotNull Predicate<RenderedBone> filter, @NotNull String

//--- Update action ---

/**
* Registers a hitbox-listener builder hook that is applied when hitboxes are created.
* <p>
* This delegates to {@link kr.toxicity.model.api.bone.BoneEventDispatcher#handleCreateHitBox(BiFunction)}
* in this tracker's render pipeline event dispatcher.
* </p>
*
* <pre>{@code
* tracker.listenHitBox((bone, builder) -> builder.interact(event -> {
* // custom interaction handling
* }));
* }</pre>
*
* @param function the hitbox listener builder transformer
* @since 2.0.2
*/
public void listenHitBox(@NotNull BiFunction<RenderedBone, HitBoxListener.Builder, HitBoxListener.Builder> function) {
pipeline.eventDispatcher().handleCreateHitBox(function);
}

/**
* Creates a hitbox for bones matching a predicate.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -356,6 +357,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -369,6 +370,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -375,6 +376,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -376,6 +377,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -376,6 +377,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
})
listener.interact(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand))
return InteractionResult.SUCCESS
Expand All @@ -376,6 +377,7 @@ internal class HitBoxImpl(
MAIN_HAND -> ModelInteractionHand.RIGHT
OFF_HAND -> ModelInteractionHand.LEFT
}, vec.toBukkit())
listener.interactAt(interact)
if (!interact.call().triggered()) return InteractionResult.FAIL
(player as ServerPlayer).connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(delegate, player.isShiftKeyDown, hand, vec))
return InteractionResult.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,20 +419,22 @@ class HitBoxEntityImpl(
if (player === delegate) {
return InteractionResult.FAIL
}
val serverPlayer = player as ServerPlayer

val interact = ModelInteractEvent(
(player as ServerPlayer).connection.wrap(),
serverPlayer.connection.wrap(),
this,
when (hand) {
InteractionHand.MAIN_HAND -> ModelInteractionHand.RIGHT
InteractionHand.OFF_HAND -> ModelInteractionHand.LEFT
}
)
listener.interact(interact)
if (!interact.call().triggered()) {
return InteractionResult.FAIL
}

player.connection.handleInteract(
serverPlayer.connection.handleInteract(
ServerboundInteractPacket.createInteractionPacket(
delegate,
player.isShiftKeyDown,
Expand All @@ -446,22 +448,23 @@ class HitBoxEntityImpl(
if (player === delegate) {
return InteractionResult.FAIL
}
val serverPlayer = player as ServerPlayer

val interact = ModelInteractAtEvent(
(player as ServerPlayer).connection.wrap(),
serverPlayer.connection.wrap(),
this,
when (hand) {
InteractionHand.MAIN_HAND -> ModelInteractionHand.RIGHT
InteractionHand.OFF_HAND -> ModelInteractionHand.LEFT
},
vec.toVector3f()
)

listener.interactAt(interact)
if (!interact.call().triggered()) {
return InteractionResult.FAIL
}

player.connection.handleInteract(
serverPlayer.connection.handleInteract(
ServerboundInteractPacket.createInteractionPacket(
delegate,
player.isShiftKeyDown,
Expand Down