mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
A few more events
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"client.MixinDebugScreenOverlay",
|
||||
"client.MixinGameRenderer",
|
||||
"client.MixinMinecraft",
|
||||
"client.MixinMultiPlayerGameMode",
|
||||
"client.MixinScreen"
|
||||
],
|
||||
"mixins": [
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user