A few more events

This commit is contained in:
shedaniel
2020-11-08 17:46:29 +08:00
parent cd595fc55a
commit 1a2d921ad0
11 changed files with 682 additions and 6 deletions

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.event.events;
import me.shedaniel.architectury.event.Event;
import me.shedaniel.architectury.event.EventFactory;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
public interface InteractionEvent {
Event<LeftClickBlock> LEFT_CLICK_BLOCK = EventFactory.createInteractionResult(LeftClickBlock.class);
Event<RightClickBlock> RIGHT_CLICK_BLOCK = EventFactory.createInteractionResult(RightClickBlock.class);
Event<RightClickItem> RIGHT_CLICK_ITEM = EventFactory.createInteractionResultHolder(RightClickItem.class);
Event<ClientLeftClickAir> CLIENT_LEFT_CLICK_AIR = EventFactory.createLoop(ClientLeftClickAir.class);
Event<ClientRightClickAir> CLIENT_RIGHT_CLICK_AIR = EventFactory.createLoop(ClientRightClickAir.class);
Event<InteractEntity> INTERACT_ENTITY = EventFactory.createInteractionResult(InteractEntity.class);
interface RightClickBlock {
InteractionResult click(Player player, InteractionHand hand, BlockPos pos, Direction face);
}
interface LeftClickBlock {
InteractionResult click(Player player, InteractionHand hand, BlockPos pos, Direction face);
}
interface RightClickItem {
InteractionResultHolder<ItemStack> click(Player player, InteractionHand hand);
}
interface ClientRightClickAir {
void click(Player player, InteractionHand hand);
}
interface ClientLeftClickAir {
void click(Player player, InteractionHand hand);
}
interface InteractEntity {
InteractionResult interact(Player player, Entity entity, InteractionHand hand);
}
interface BlockBreak {
InteractionResult breakBlock(Player player, BlockPos pos, BlockState state);
}
}

View File

@@ -0,0 +1,186 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.fluid;
import me.shedaniel.architectury.hooks.FluidStackHooks;
import me.shedaniel.architectury.utils.Fraction;
import me.shedaniel.architectury.utils.NbtType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Supplier;
public final class FluidStack {
private Fraction amount;
@Nullable
private CompoundTag tag;
private Supplier<Fluid> fluid;
private FluidStack(Supplier<Fluid> fluid, Fraction amount, CompoundTag tag) {
this.fluid = Objects.requireNonNull(fluid);
this.amount = Objects.requireNonNull(amount);
this.tag = tag == null ? null : tag.copy();
}
public static FluidStack create(Supplier<Fluid> fluid, Fraction amount, @Nullable CompoundTag tag) {
return new FluidStack(fluid, amount, tag);
}
public static FluidStack create(Supplier<Fluid> fluid, Fraction amount) {
return create(fluid, amount, null);
}
public static FluidStack create(FluidStack stack, Fraction amount) {
return create(stack.getRawFluidSupplier(), amount, stack.getTag());
}
public static Fraction bucketAmount() {
return FluidStackHooks.bucketAmount();
}
public final Fluid getFluid() {
return isEmpty() ? Fluids.EMPTY : getRawFluid();
}
@Nullable
public final Fluid getRawFluid() {
return fluid.get();
}
public final Supplier<Fluid> getRawFluidSupplier() {
return fluid;
}
public boolean isEmpty() {
return getRawFluid() == Fluids.EMPTY || !amount.isGreaterThan(Fraction.zero());
}
public Fraction getAmount() {
return isEmpty() ? Fraction.zero() : amount;
}
public void setAmount(Fraction amount) {
this.amount = Objects.requireNonNull(amount);
}
public void grow(Fraction amount) {
setAmount(this.amount.add(amount));
}
public void shrink(Fraction amount) {
setAmount(this.amount.minus(amount));
}
public boolean hasTag() {
return tag != null;
}
@Nullable
public CompoundTag getTag() {
return tag;
}
public void setTag(@Nullable CompoundTag tag) {
this.tag = tag;
}
public CompoundTag getOrCreateTag() {
if (tag == null)
setTag(new CompoundTag());
return tag;
}
@Nullable
public CompoundTag getChildTag(String childName) {
if (tag == null)
return null;
return tag.getCompound(childName);
}
public CompoundTag getOrCreateChildTag(String childName) {
getOrCreateTag();
CompoundTag child = tag.getCompound(childName);
if (!tag.contains(childName, NbtType.COMPOUND)) {
tag.put(childName, child);
}
return child;
}
public void removeChildTag(String childName) {
if (tag != null)
tag.remove(childName);
}
public Component getName() {
return FluidStackHooks.getName(this);
}
public String getTranslationKey() {
return FluidStackHooks.getTranslationKey(this);
}
public FluidStack copy() {
return new FluidStack(fluid, amount, tag);
}
@Override
public final int hashCode() {
int code = 1;
code = 31 * code + getFluid().hashCode();
code = 31 * code + amount.hashCode();
if (tag != null)
code = 31 * code + tag.hashCode();
return code;
}
@Override
public final boolean equals(Object o) {
if (!(o instanceof FluidStack)) {
return false;
}
return isFluidStackEqual((FluidStack) o);
}
public boolean isFluidStackEqual(FluidStack other) {
return getFluid() == other.getFluid() && getAmount().equals(other.getAmount()) && isTagEqual(other);
}
private boolean isTagEqual(FluidStack other) {
return tag == null ? other.tag == null : other.tag != null && tag.equals(other.tag);
}
public static FluidStack read(FriendlyByteBuf buf) {
return FluidStackHooks.read(buf);
}
public static FluidStack read(CompoundTag tag) {
return FluidStackHooks.read(tag);
}
public void write(FriendlyByteBuf buf) {
FluidStackHooks.write(this, buf);
}
public CompoundTag write(CompoundTag tag) {
return FluidStackHooks.write(this, tag);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.hooks;
import me.shedaniel.architectury.ArchitecturyPopulator;
import me.shedaniel.architectury.Populatable;
import me.shedaniel.architectury.fluid.FluidStack;
import me.shedaniel.architectury.utils.Fraction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
public class FluidStackHooks {
private FluidStackHooks() {}
@Populatable
private static final Impl IMPL = null;
public static Component getName(FluidStack stack) {
return IMPL.getName(stack);
}
public static String getTranslationKey(FluidStack stack) {
return IMPL.getTranslationKey(stack);
}
/**
* Platform-specific FluidStack read.
*/
public static FluidStack read(FriendlyByteBuf buf) {
return IMPL.read(buf);
}
/**
* Platform-specific FluidStack write.
*/
public static void write(FluidStack stack, FriendlyByteBuf buf) {
IMPL.write(stack, buf);
}
/**
* Platform-specific FluidStack read.
*/
public static FluidStack read(CompoundTag tag) {
return IMPL.read(tag);
}
/**
* Platform-specific FluidStack write.
*/
public static CompoundTag write(FluidStack stack, CompoundTag tag) {
return IMPL.write(stack, tag);
}
/**
* Platform-specific bucket amount.
* Forge: 1000
* Fabric: 1
*/
public static Fraction bucketAmount() {
return IMPL.bucketAmount();
}
public interface Impl {
Fraction bucketAmount();
Component getName(FluidStack stack);
String getTranslationKey(FluidStack stack);
FluidStack read(FriendlyByteBuf buf);
void write(FluidStack stack, FriendlyByteBuf buf);
FluidStack read(CompoundTag tag);
CompoundTag write(FluidStack stack, CompoundTag tag);
}
static {
ArchitecturyPopulator.populate();
}
}

View File

@@ -0,0 +1,177 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.utils;
import com.google.common.math.LongMath;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
public final class Fraction extends Number implements Comparable<Fraction> {
private static final Fraction ZERO = ofWhole(0);
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.###");
private final long numerator;
private final long denominator;
private boolean simplified;
private Fraction(long numerator, long denominator) {
if (denominator > 0) {
this.numerator = numerator;
this.denominator = denominator;
} else if (denominator < 0) {
this.numerator = -numerator;
this.denominator = -denominator;
} else {
throw new ArithmeticException("/ by zero");
}
this.simplified = (this.numerator >= -1 && this.numerator <= 1) || this.denominator == 1;
}
public static Fraction zero() {
return ZERO;
}
public static Fraction ofWhole(long whole) {
return new Fraction(whole, 1);
}
public static Fraction of(long numerator, long denominator) {
return new Fraction(numerator, denominator);
}
public static Fraction of(long whole, long numerator, long denominator) {
return of(numerator + whole * denominator, denominator);
}
public static Fraction from(double value) {
int whole = (int) value;
double part = value - whole;
int i = 1;
while (true) {
double tem = part / (1D / i);
long numerator = Math.round(tem);
if (Math.abs(tem - numerator) < 0.00001) {
return of(whole, numerator, i);
}
i++;
}
}
public long getNumerator() {
return numerator;
}
public long getDenominator() {
return denominator;
}
public Fraction add(Fraction other) {
if (other.numerator == 0) return this;
return of(numerator * other.denominator + other.numerator * denominator, denominator * other.denominator);
}
public Fraction minus(Fraction other) {
if (other.numerator == 0) return this;
return of(numerator * other.denominator - other.numerator * denominator, denominator * other.denominator);
}
public Fraction multiply(Fraction other) {
if (other.numerator == other.denominator) return this;
return of(numerator * other.numerator, denominator * other.denominator);
}
public Fraction divide(Fraction other) {
if (other.numerator == other.denominator) return this;
return of(numerator * other.denominator, denominator * other.numerator);
}
public Fraction inverse() {
if (numerator == denominator)
return this;
Fraction fraction = of(denominator, numerator);
fraction.simplified = fraction.simplified && this.simplified;
return fraction;
}
public Fraction simplify() {
if (simplified)
return this;
if (numerator == 0)
return ofWhole(0);
long gcd = LongMath.gcd(Math.abs(numerator), denominator);
Fraction fraction = of(numerator / gcd, denominator / gcd);
fraction.simplified = true;
return fraction;
}
public boolean isGreaterThan(Fraction fraction) {
return compareTo(fraction) > 0;
}
public boolean isLessThan(Fraction fraction) {
return compareTo(fraction) < 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Fraction fraction = (Fraction) o;
return numerator * fraction.denominator == denominator * fraction.numerator;
}
@Override
public int hashCode() {
return Double.hashCode(doubleValue());
}
@Override
public int compareTo(@NotNull Fraction fraction) {
return Long.compare(numerator * fraction.denominator, denominator * fraction.numerator);
}
@Override
public int intValue() {
return (int) longValue();
}
@Override
public long longValue() {
return numerator / denominator;
}
@Override
public float floatValue() {
return (float) numerator / denominator;
}
@Override
public double doubleValue() {
return (double) numerator / denominator;
}
public String toDecimalString() {
return DECIMAL_FORMAT.format(doubleValue());
}
@Override
public String toString() {
if (intValue() == doubleValue()) return toDecimalString();
return String.format("%s (%d/%d)", toDecimalString(), numerator, denominator);
}
}

View File

@@ -26,6 +26,9 @@ import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.minecraft.commands.Commands;
public class EventHandlerImpl implements EventHandler.Impl {
@@ -59,6 +62,10 @@ public class EventHandlerImpl implements EventHandler.Impl {
ServerWorldEvents.UNLOAD.register((server, world) -> LifecycleEvent.SERVER_WORLD_UNLOAD.invoker().act(world));
CommandRegistrationCallback.EVENT.register((commandDispatcher, b) -> CommandRegistrationEvent.EVENT.invoker().register(commandDispatcher, b ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED));
UseItemCallback.EVENT.register((player, world, hand) -> InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(player, hand));
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(player, hand, hitResult.getBlockPos(), hitResult.getDirection()));
AttackBlockCallback.EVENT.register((player, world, hand, pos, face) -> InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(player, hand, pos, face));
}
@Override

View File

@@ -16,9 +16,12 @@
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.InteractionEvent;
import me.shedaniel.architectury.event.events.PlayerEvent;
import me.shedaniel.architectury.event.events.TickEvent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
@@ -46,4 +49,15 @@ public class MixinPlayer {
cir.setReturnValue(null);
}
}
@Inject(method = "interactOn", at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Player;getItemInHand(Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/item/ItemStack;",
ordinal = 0),
cancellable = true)
private void entityInteract(Entity entity, InteractionHand interactionHand, CallbackInfoReturnable<InteractionResult> cir) {
InteractionResult result = InteractionEvent.INTERACT_ENTITY.invoker().interact((Player) (Object) this, entity, interactionHand);
if (result != InteractionResult.PASS) {
cir.setReturnValue(result);
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.PlayerEvent;

View File

@@ -16,24 +16,44 @@
package me.shedaniel.architectury.mixin.fabric.client;
import me.shedaniel.architectury.event.events.InteractionEvent;
import me.shedaniel.architectury.event.events.PlayerEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(Minecraft.class)
public class MixinMinecraft {
@Shadow @Nullable public LocalPlayer player;
@Shadow @Nullable public HitResult hitResult;
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/chat/NarratorChatListener;clear()V"))
private void handleLogin(Screen screen, CallbackInfo ci) {
PlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(player);
}
@Inject(method = "startUseItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z", ordinal = 1),
locals = LocalCapture.CAPTURE_FAILHARD)
private void rightClickAir(CallbackInfo ci, InteractionHand var1[], int var2, int var3, InteractionHand interactionHand, ItemStack itemStack) {
if (itemStack.isEmpty() && (this.hitResult == null || this.hitResult.getType() == HitResult.Type.MISS)) {
InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(player, interactionHand);
}
}
@Inject(method = "startAttack", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;resetAttackStrengthTicker()V", ordinal = 0))
private void leftClickAir(CallbackInfo ci) {
InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(player, InteractionHand.MAIN_HAND);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2020 shedaniel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.shedaniel.architectury.mixin.fabric.client;
import me.shedaniel.architectury.event.events.InteractionEvent;
import net.minecraft.client.multiplayer.MultiPlayerGameMode;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(MultiPlayerGameMode.class)
public class MixinMultiPlayerGameMode {
@Inject(method = "interact",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientPacketListener;send(Lnet/minecraft/network/protocol/Packet;)V",
shift = At.Shift.AFTER),
cancellable = true)
private void entityInteract(Player player, Entity entity, InteractionHand interactionHand, CallbackInfoReturnable<InteractionResult> cir) {
InteractionResult result = InteractionEvent.INTERACT_ENTITY.invoker().interact(player, entity, interactionHand);
if (result != InteractionResult.PASS) {
cir.setReturnValue(result);
}
}
}

View File

@@ -9,6 +9,7 @@
"client.MixinDebugScreenOverlay",
"client.MixinGameRenderer",
"client.MixinMinecraft",
"client.MixinMultiPlayerGameMode",
"client.MixinScreen"
],
"mixins": [

View File

@@ -17,11 +17,13 @@
package me.shedaniel.architectury.event.forge;
import me.shedaniel.architectury.event.EventHandler;
import me.shedaniel.architectury.event.events.PlayerEvent;
import me.shedaniel.architectury.event.events.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.text.ITextComponent;
@@ -38,14 +40,12 @@ import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.player.AdvancementEvent;
import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import net.minecraftforge.event.entity.player.*;
import net.minecraftforge.event.entity.player.PlayerEvent.*;
import net.minecraftforge.event.world.ExplosionEvent.Detonate;
import net.minecraftforge.event.world.ExplosionEvent.Start;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
@@ -163,6 +163,16 @@ public class EventHandlerImpl implements EventHandler.Impl {
public static void event(GuiScreenEvent.DrawScreenEvent.Post event) {
GuiEvent.RENDER_POST.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks());
}
@SubscribeEvent
public static void event(PlayerInteractEvent.RightClickEmpty event) {
InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
}
@SubscribeEvent
public static void event(PlayerInteractEvent.LeftClickEmpty event) {
InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
}
}
public static class Common {
@@ -347,16 +357,56 @@ public class EventHandlerImpl implements EventHandler.Impl {
public static void event(ItemTossEvent event) {
PlayerEvent.DROP_ITEM.invoker().drop(event.getPlayer(), event.getEntityItem());
}
@SubscribeEvent
public static void event(PlayerContainerEvent.Open event) {
PlayerEvent.OPEN_MENU.invoker().open(event.getPlayer(), event.getContainer());
}
@SubscribeEvent
public static void event(PlayerContainerEvent.Close event) {
PlayerEvent.CLOSE_MENU.invoker().close(event.getPlayer(), event.getContainer());
}
@SubscribeEvent
public static void event(PlayerInteractEvent.RightClickItem event) {
ActionResult<ItemStack> result = InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(event.getPlayer(), event.getHand());
if (result.getResult() != ActionResultType.PASS) {
event.setCanceled(true);
event.setCancellationResult(result.getResult());
}
}
@SubscribeEvent
public static void event(PlayerInteractEvent.RightClickBlock event) {
ActionResultType result = InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
if (result != ActionResultType.PASS) {
event.setCanceled(true);
event.setCancellationResult(result);
event.setUseBlock(Event.Result.DENY);
event.setUseItem(Event.Result.DENY);
}
}
@SubscribeEvent
public static void event(PlayerInteractEvent.EntityInteract event) {
ActionResultType result = InteractionEvent.INTERACT_ENTITY.invoker().interact(event.getPlayer(), event.getTarget(), event.getHand());
if (result != ActionResultType.PASS) {
event.setCanceled(true);
event.setCancellationResult(result);
}
}
@SubscribeEvent
public static void event(PlayerInteractEvent.LeftClickBlock event) {
ActionResultType result = InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
if (result != ActionResultType.PASS) {
event.setCanceled(true);
event.setCancellationResult(result);
event.setUseBlock(Event.Result.DENY);
event.setUseItem(Event.Result.DENY);
}
}
}
@OnlyIn(Dist.DEDICATED_SERVER)