Grindstone Events (#8934)

One to modify the output, and one to modify the input.
This commit is contained in:
ferriarnus authored and GitHub committed 2022-09-08 15:55:43 +01:00
1 parent 73c1934e7e
commit 6d233ac75c
3 files changed
+260 -7

No files matched your search

@@ -1,5 +1,53 @@
--- a/net/minecraft/world/inventory/GrindstoneMenu.java
+++ b/net/minecraft/world/inventory/GrindstoneMenu.java
@@ -34,6 +_,7 @@
}
};
private final ContainerLevelAccess f_39561_;
+ private int xp = -1;
public GrindstoneMenu(int p_39563_, Inventory p_39564_) {
this(p_39563_, p_39564_, ContainerLevelAccess.f_39287_);
@@ -44,12 +_,12 @@
this.f_39561_ = p_39568_;
this.m_38897_(new Slot(this.f_39560_, 0, 49, 19) {
public boolean m_5857_(ItemStack p_39607_) {
- return p_39607_.m_41763_() || p_39607_.m_150930_(Items.f_42690_) || p_39607_.m_41793_();
+ return true; //Allow all items in the slot, not just repairable
}
});
this.m_38897_(new Slot(this.f_39560_, 1, 49, 40) {
public boolean m_5857_(ItemStack p_39616_) {
- return p_39616_.m_41763_() || p_39616_.m_150930_(Items.f_42690_) || p_39616_.m_41793_();
+ return true; //Allow all items in the slot, not just repairable
}
});
this.m_38897_(new Slot(this.f_39559_, 2, 129, 34) {
@@ -58,6 +_,7 @@
}
public void m_142406_(Player p_150574_, ItemStack p_150575_) {
+ if (net.minecraftforge.common.ForgeHooks.onGrindstoneTake(GrindstoneMenu.this.f_39560_, p_39568_, this::m_39631_)) return;
p_39568_.m_39292_((p_39634_, p_39635_) -> {
if (p_39634_ instanceof ServerLevel) {
ExperienceOrb.m_147082_((ServerLevel)p_39634_, Vec3.m_82512_(p_39635_), this.m_39631_(p_39634_));
@@ -70,6 +_,7 @@
}
private int m_39631_(Level p_39632_) {
+ if (xp > -1) return xp;
int l = 0;
l += this.m_39636_(GrindstoneMenu.this.f_39560_.m_8020_(0));
l += this.m_39636_(GrindstoneMenu.this.f_39560_.m_8020_(1));
@@ -122,6 +_,8 @@
ItemStack itemstack1 = this.f_39560_.m_8020_(1);
boolean flag = !itemstack.m_41619_() || !itemstack1.m_41619_();
boolean flag1 = !itemstack.m_41619_() && !itemstack1.m_41619_();
+ this.xp = net.minecraftforge.common.ForgeHooks.onGrindstoneChange(itemstack, itemstack1, this.f_39559_, this.xp);
+ if (this.xp != Integer.MIN_VALUE) return;
if (!flag) {
this.f_39559_.m_6836_(0, ItemStack.f_41583_);
} else {
@@ -143,12 +_,13 @@
}
@@ -9,6 +9,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
@@ -37,18 +38,29 @@ import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.core.*;
import net.minecraft.network.chat.*;
import net.minecraft.network.chat.contents.LiteralContents;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.packs.PackType;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagEntry;
import net.minecraft.tags.TagKey;
import net.minecraft.util.datafix.fixes.StructuresBecomeConfiguredFix;
import net.minecraft.world.Difficulty;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.DefaultAttributes;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.monster.EnderMan;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.item.*;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeType;
@@ -65,11 +77,6 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.server.level.ServerPlayer;
@@ -86,7 +93,6 @@ import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.stats.Stats;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.*;
import net.minecraft.world.level.BaseSpawner;
import net.minecraft.world.level.block.entity.FurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -107,6 +113,7 @@ import net.minecraftforge.common.util.MavenVersionStringHelper;
import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.DifficultyChangeEvent;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.GrindstoneEvent;
import net.minecraftforge.event.ItemAttributeModifierEvent;
import net.minecraftforge.event.ModMismatchEvent;
import net.minecraftforge.event.ServerChatEvent;
@@ -734,6 +741,37 @@ public class ForgeHooks
return e.getBreakChance();
}
public static int onGrindstoneChange(@NotNull ItemStack top, @NotNull ItemStack bottom, Container outputSlot, int xp)
{
GrindstoneEvent.OnplaceItem e = new GrindstoneEvent.OnplaceItem(top, bottom, xp);
if (MinecraftForge.EVENT_BUS.post(e)) return e.getXp();
if (e.getOutput().isEmpty()) return Integer.MIN_VALUE;
outputSlot.setItem(0, e.getOutput());
return e.getXp();
}
public static boolean onGrindstoneTake(Container inputSlots, ContainerLevelAccess access, Function<Level, Integer> xpFunction)
{
access.execute((l,p) -> {
int xp = xpFunction.apply(l);
GrindstoneEvent.OnTakeItem e = new GrindstoneEvent.OnTakeItem(inputSlots.getItem(0), inputSlots.getItem(1), xp);
if (MinecraftForge.EVENT_BUS.post(e))
{
return;
}
if (l instanceof ServerLevel)
{
ExperienceOrb.award((ServerLevel)l, Vec3.atCenterOf(p), e.getXp());
}
l.levelEvent(1042, p, 0);
inputSlots.setItem(0, e.getNewTopItem());
inputSlots.setItem(1, e.getNewBottomItem());
inputSlots.setChanged();
});
return true;
}
private static ThreadLocal<Player> craftingPlayer = new ThreadLocal<Player>();
public static void setCraftingPlayer(Player player)
{
@@ -0,0 +1,167 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
package net.minecraftforge.event;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.GrindstoneMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;
public abstract class GrindstoneEvent extends Event
{
private final ItemStack top;
private final ItemStack bottom;
private int xp;
protected GrindstoneEvent(ItemStack top, ItemStack bottom, int xp)
{
this.top = top;
this.bottom = bottom;
this.xp = xp;
}
/**
* @return The item in the top input grindstone slot. <br>
*/
public ItemStack getTopItem()
{
return top;
}
/**
* @return The item in the bottom input grindstone slot. <br>
*/
public ItemStack getBottomItem()
{
return bottom;
}
/**
* This is the experience amount determined by the event, not the vanilla behavior. <br>
* If you are the first receiver of this event, it is guaranteed to be -1. <br>
* The value must be set to a positive value to override vanilla behavior. <br>
* if the value is equal to -1, the vanilla behavior for calculating experience will run. <br>
* @return The experience amount given to the player. <br>
*/
public int getXp()
{
return xp;
}
/**
* Sets the experience amount. <br>
* @param xp The experience amount given to the player. <br>
*/
public void setXp(int xp)
{
this.xp = xp;
}
/**
* This event is {@link Cancelable} <br>
* {@link OnplaceItem} is fired when the inputs to a grindstone are changed. <br>
* It is called from {@link GrindstoneMenu#createResult()}. <br>
* If the event is canceled, vanilla behavior will not run, and the output will be set to {@link ItemStack#EMPTY}. <br>
* If the event is not canceled, but the output is not empty, it will set the output and not run vanilla behavior. <br>
* if the output is empty, and the event is not canceled, vanilla behavior will execute. <br>
* if the amount of experience is larger than or equal 0, the vanilla behavior for calculating experience will not run. <br>
*/
@Cancelable
public static class OnplaceItem extends GrindstoneEvent
{
private ItemStack output;
public OnplaceItem(ItemStack top, ItemStack bottom, int xp)
{
super(top, bottom, xp);
this.output = ItemStack.EMPTY;
}
/**
* This is the output as determined by the event, not by the vanilla behavior between these two items. <br>
* If you are the first receiver of this event, it is guaranteed to be empty. <br>
* It will only be non-empty if changed by an event handler. <br>
* If this event is cancelled, this output stack is discarded. <br>
* @return The item to set in the output grindstone slot. <br>
*/
public ItemStack getOutput()
{
return output;
}
/**
* Sets the output slot to a specific itemstack.
* @param output The stack to change the output to.
*/
public void setOutput(ItemStack output)
{
this.output = output;
}
}
/**
* This event is {@link Cancelable} <br>
* {@link OnTakeItem} is fired when the output in a grindstone are is taken. <br>
* It is called from {@link GrindstoneMenu#GrindstoneMenu(int, Inventory)}. <br>
* If the event is canceled, vanilla behavior will not run, and no inputs will be consumed. <br>
* if the amount of experience is larger than or equal 0, the vanilla behavior for calculating experience will not run. <br>
*/
@Cancelable
public static class OnTakeItem extends GrindstoneEvent
{
private ItemStack newTop = ItemStack.EMPTY;
private ItemStack newBottom = ItemStack.EMPTY;
public OnTakeItem(ItemStack top, ItemStack bottom, int xp)
{
super(top, bottom, xp);
}
/**
* @return The item in that will be in the top input grindstone slot after the event. <br>
*/
public ItemStack getNewTopItem()
{
return newTop;
}
/**
* @return The item in that will be in the bottom input grindstone slot after the event. <br>
*/
public ItemStack getNewBottomItem()
{
return newBottom;
}
/**
* Sets the itemstack in the top slot. <br>
* @param newTop
*/
public void setNewTopItem(ItemStack newTop)
{
this.newTop = newTop;
}
/**
* Sets the itemstack in the bottom slot. <br>
* @param newBottom
*/
public void setNewBottomItem(ItemStack newBottom)
{
this.newBottom = newBottom;
}
/**
* This is the experience amount that will be returned by the event. <br>
* @return The experience amount given to the player. <br>
*/
public int getXp()
{
return super.getXp();
}
}
}