More events

This commit is contained in:
shedaniel
2020-11-08 00:24:53 +08:00
parent 0e8754d7a6
commit c14c78f6ee
6 changed files with 112 additions and 4 deletions

View File

@@ -23,9 +23,11 @@ import net.fabricmc.api.Environment;
import net.minecraft.advancements.Advancement;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
public interface PlayerEvent {
@@ -37,9 +39,13 @@ public interface PlayerEvent {
@Environment(EnvType.CLIENT) Event<ClientPlayerRespawn> CLIENT_PLAYER_RESPAWN = EventFactory.createLoop(ClientPlayerRespawn.class);
Event<PlayerAdvancement> PLAYER_ADVANCEMENT = EventFactory.createLoop(PlayerAdvancement.class);
Event<PlayerClone> PLAYER_CLONE = EventFactory.createLoop(PlayerClone.class);
Event<CraftItem> CRAFT_ITEM = EventFactory.createLoop(CraftItem.class);
Event<SmeltItem> SMELT_ITEM = EventFactory.createLoop(SmeltItem.class);
Event<PickupItemPredicate> PICKUP_ITEM_PRE = EventFactory.createInteractionResult(PickupItemPredicate.class);
Event<PickupItem> PICKUP_ITEM_POST = EventFactory.createLoop(PickupItem.class);
Event<DropItem> DROP_ITEM = EventFactory.createLoop(DropItem.class);
Event<OpenMenu> OPEN_MENU = EventFactory.createLoop(OpenMenu.class);
Event<CloseMenu> CLOSE_MENU = EventFactory.createLoop(CloseMenu.class);
interface PlayerJoin {
void join(ServerPlayer player);
@@ -61,16 +67,32 @@ public interface PlayerEvent {
void award(ServerPlayer player, Advancement advancement);
}
interface CraftItem {
void craft(Player player, ItemStack smelted, Container inventory);
}
interface SmeltItem {
void smelt(Player player, ItemStack smelted);
}
interface PickupItemPredicate {
InteractionResult canPickup(Player player, ItemEntity entity, ItemStack smelted);
InteractionResult canPickup(Player player, ItemEntity entity, ItemStack stack);
}
interface PickupItem {
void pickup(Player player, ItemEntity entity, ItemStack smelted);
void pickup(Player player, ItemEntity entity, ItemStack stack);
}
interface DropItem {
InteractionResult drop(Player player, ItemEntity entity);
}
interface OpenMenu {
void open(Player player, AbstractContainerMenu menu);
}
interface CloseMenu {
void close(Player player, AbstractContainerMenu menu);
}
@Environment(EnvType.CLIENT)

View File

@@ -16,12 +16,17 @@
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.PlayerEvent;
import me.shedaniel.architectury.event.events.TickEvent;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Player.class)
public class MixinPlayer {
@@ -34,4 +39,11 @@ public class MixinPlayer {
private void postTick(CallbackInfo ci) {
TickEvent.PLAYER_POST.invoker().tick((Player) (Object) this);
}
@Inject(method = "drop(Lnet/minecraft/world/item/ItemStack;ZZ)Lnet/minecraft/world/entity/item/ItemEntity;", at = @At("RETURN"), cancellable = true)
private void drop(ItemStack itemStack, boolean bl, boolean bl2, CallbackInfoReturnable<ItemEntity> cir) {
if (PlayerEvent.DROP_ITEM.invoker().drop((Player) (Object) this, cir.getReturnValue()) == InteractionResult.FAIL) {
cir.setReturnValue(null);
}
}
}

View File

@@ -0,0 +1,27 @@
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.PlayerEvent;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.inventory.ResultSlot;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Final;
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;
@Mixin(ResultSlot.class)
public class MixinResultSlot {
@Shadow @Final private Player player;
@Shadow @Final private CraftingContainer craftSlots;
@Inject(method = "checkTakeAchievements", at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/item/ItemStack;onCraftedBy(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;I)V",
shift = At.Shift.AFTER))
private void craft(ItemStack itemStack, CallbackInfo ci) {
PlayerEvent.CRAFT_ITEM.invoker().craft(player, itemStack, craftSlots);
}
}

View File

@@ -18,10 +18,16 @@ package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.PlayerEvent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.OptionalInt;
@Mixin(ServerPlayer.class)
public class MixinServerPlayer {
@@ -29,4 +35,23 @@ public class MixinServerPlayer {
private void restoreFrom(ServerPlayer serverPlayer, boolean bl, CallbackInfo ci) {
PlayerEvent.PLAYER_CLONE.invoker().clone((ServerPlayer) (Object) this, serverPlayer, bl);
}
@Inject(method = "openMenu", at = @At("RETURN"))
private void openMenu(MenuProvider menuProvider, CallbackInfoReturnable<OptionalInt> cir) {
if (cir.getReturnValue().isPresent()) {
PlayerEvent.OPEN_MENU.invoker().open((ServerPlayer) (Object) this, ((ServerPlayer) (Object) this).containerMenu);
}
}
@Inject(method = "openHorseInventory", at = @At("RETURN"))
private void openHorseInventory(AbstractHorse abstractHorse, Container container, CallbackInfo ci) {
PlayerEvent.OPEN_MENU.invoker().open((ServerPlayer) (Object) this, ((ServerPlayer) (Object) this).containerMenu);
}
@Inject(method = "doCloseContainer",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AbstractContainerMenu;removed(Lnet/minecraft/world/entity/player/Player;)V",
shift = At.Shift.AFTER))
private void doCloseContainer(CallbackInfo ci) {
PlayerEvent.CLOSE_MENU.invoker().close((ServerPlayer) (Object) this, ((ServerPlayer) (Object) this).containerMenu);
}
}

View File

@@ -13,8 +13,8 @@
],
"mixins": [
"ExplosionPreInvoker", "LivingDeathInvoker", "MixinCommands", "MixinExplosion", "MixinFurnaceResultSlot", "MixinItemEntity", "MixinLivingEntity",
"MixinPlayer", "MixinPlayerAdvancements", "MixinPlayerList", "MixinServerGamePacketListenerImpl", "MixinServerLevel", "MixinServerPlayer",
"PlayerAttackInvoker"
"MixinPlayer", "MixinPlayerAdvancements", "MixinPlayerList", "MixinResultSlot", "MixinServerGamePacketListenerImpl", "MixinServerLevel",
"MixinServerPlayer", "PlayerAttackInvoker"
],
"injectors": {
"defaultRequire": 1

View File

@@ -35,11 +35,13 @@ import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.TickEvent.*;
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.PlayerEvent.*;
import net.minecraftforge.event.world.ExplosionEvent.Detonate;
import net.minecraftforge.event.world.ExplosionEvent.Start;
@@ -321,6 +323,11 @@ public class EventHandlerImpl implements EventHandler.Impl {
}
}
@SubscribeEvent
public static void event(ItemCraftedEvent event) {
PlayerEvent.CRAFT_ITEM.invoker().craft(event.getPlayer(), event.getCrafting(), event.getInventory());
}
@SubscribeEvent
public static void event(ItemSmeltedEvent event) {
PlayerEvent.SMELT_ITEM.invoker().smelt(event.getPlayer(), event.getSmelting());
@@ -335,6 +342,21 @@ public class EventHandlerImpl implements EventHandler.Impl {
public static void event(ItemPickupEvent event) {
PlayerEvent.PICKUP_ITEM_POST.invoker().pickup(event.getPlayer(), event.getOriginalEntity(), event.getStack());
}
@SubscribeEvent
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());
}
}
@OnlyIn(Dist.DEDICATED_SERVER)