Skip to content

Commit 2baaa2e

Browse files
committed
Added INVENTORY_HELPER service.
1 parent 375c10e commit 2baaa2e

File tree

6 files changed

+154
-0
lines changed

6 files changed

+154
-0
lines changed

Common/src/main/java/net/darkhax/bookshelf/api/Services.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.darkhax.bookshelf.api.event.IEventHelper;
66
import net.darkhax.bookshelf.api.registry.IGameRegistries;
77
import net.darkhax.bookshelf.api.util.ICreativeTabHelper;
8+
import net.darkhax.bookshelf.api.util.IInventoryHelper;
89
import net.darkhax.bookshelf.api.util.IPlatformHelper;
910

1011
import java.util.ServiceLoader;
@@ -16,6 +17,7 @@ public class Services {
1617
public static final IGameRegistries REGISTRIES = load(IGameRegistries.class);
1718
public static final ITagHelper TAGS = load(ITagHelper.class);
1819
public static final ICreativeTabHelper CREATIVE_TABS = load(ICreativeTabHelper.class);
20+
public static final IInventoryHelper INVENTORY_HELPER = load(IInventoryHelper.class);
1921

2022
public static <T> T load(Class<T> clazz) {
2123

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package net.darkhax.bookshelf.api.util;
2+
3+
import net.darkhax.bookshelf.Constants;
4+
import net.darkhax.bookshelf.mixin.inventory.AccessorCraftingContainer;
5+
import net.darkhax.bookshelf.mixin.inventory.AccessorCraftingMenu;
6+
import net.darkhax.bookshelf.mixin.inventory.AccessorInventoryMenu;
7+
import net.minecraft.core.NonNullList;
8+
import net.minecraft.world.Container;
9+
import net.minecraft.world.entity.EquipmentSlot;
10+
import net.minecraft.world.entity.LivingEntity;
11+
import net.minecraft.world.entity.player.Inventory;
12+
import net.minecraft.world.entity.player.Player;
13+
import net.minecraft.world.inventory.AbstractContainerMenu;
14+
import net.minecraft.world.inventory.CraftingContainer;
15+
import net.minecraft.world.item.ItemStack;
16+
17+
import javax.annotation.Nullable;
18+
import java.util.Random;
19+
20+
public interface IInventoryHelper {
21+
22+
/**
23+
* Gets the internal menu context that is backing a crafting container.
24+
*
25+
* @param container The crafting container to retrieve internal menu context from.
26+
* @return The internal menu, or null if the menu could not be found.
27+
*/
28+
@Nullable
29+
default AbstractContainerMenu getCraftingContainer(CraftingContainer container) {
30+
31+
return (container instanceof AccessorCraftingContainer accessor) ? accessor.bookshelf$getMenu() : null;
32+
}
33+
34+
@Nullable
35+
default Player getCraftingPlayer(Container container) {
36+
37+
if (container instanceof Inventory playerInv) {
38+
39+
return playerInv.player;
40+
}
41+
42+
else if (container instanceof CraftingContainer crafting) {
43+
44+
final AbstractContainerMenu menu = getCraftingContainer(crafting);
45+
46+
if (menu instanceof AccessorCraftingMenu accessor) {
47+
48+
return accessor.bookshelf$getPlayer();
49+
}
50+
51+
else if (menu instanceof AccessorInventoryMenu accessor) {
52+
53+
return accessor.bookshelf$getOwner();
54+
}
55+
}
56+
57+
// TODO add some way for dynamic container resolution?
58+
return null;
59+
}
60+
61+
/**
62+
* Damages an ItemStack by a set amount.
63+
* <p>
64+
* ItemStacks with the Unbreakable tag are treated as immune to stack damage as per Minecraft's base spec.
65+
* <p>
66+
* ItemStacks with the unbreaking enchantment will have a chance of ignoring the damage.
67+
* <p>
68+
* ItemStacks that do not have durability will not be modified.
69+
* <p>
70+
* Players in Creative Mode can not damage ItemStacks.
71+
*
72+
* @param stack The ItemStack to damage.
73+
* @param amount The amount of damage to apply to the item.
74+
* @param owner The entity that owns the ItemStack. This is optional but will be used for certain events.
75+
* @param slot The slot the ItemStack is in. This is optional and used for the item break animation.
76+
*/
77+
default ItemStack damageStack(ItemStack stack, int amount, @Nullable LivingEntity owner, @Nullable EquipmentSlot slot) {
78+
79+
// Only items with durability can be damaged. Items with an Unbreakable tag override damage.
80+
if (stack.isDamageableItem()) {
81+
82+
// If an owner is present, use the entity aware version.
83+
if (owner != null) {
84+
85+
stack.hurtAndBreak(amount, owner, e -> {
86+
87+
if (slot != null) {
88+
e.broadcastBreakEvent(slot);
89+
}
90+
});
91+
}
92+
93+
// Try to damage the stack directly.
94+
else if (stack.hurt(amount, Constants.RANDOM, null)) {
95+
96+
// Destroy the ItemStack when it has no more durability.
97+
stack.shrink(1);
98+
stack.setDamageValue(0);
99+
}
100+
}
101+
102+
return stack;
103+
}
104+
105+
default NonNullList<ItemStack> keepDamageableItems(CraftingContainer inv, NonNullList<ItemStack> keptItems, int damageAmount) {
106+
107+
@Nullable final Player player = this.getCraftingPlayer(inv);
108+
final Random random = player != null ? player.getRandom() : Constants.RANDOM;
109+
110+
for (int i = 0; i < keptItems.size(); i++) {
111+
112+
final ItemStack input = inv.getItem(i).copy();
113+
114+
if (input.getItem().canBeDepleted() || (input.hasTag() && input.getTag().getBoolean("Unbreaking"))) {
115+
116+
final ItemStack stack = this.damageStack(input, damageAmount, player, null);
117+
118+
if (!stack.isEmpty()) {
119+
120+
keptItems.set(i, stack);
121+
}
122+
}
123+
}
124+
125+
return keptItems;
126+
}
127+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.darkhax.bookshelf.impl.util;
2+
3+
import net.darkhax.bookshelf.api.util.IInventoryHelper;
4+
5+
public class InventoryHelperFabric implements IInventoryHelper {
6+
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.darkhax.bookshelf.impl.util.InventoryHelperFabric
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.darkhax.bookshelf.impl.util;
2+
3+
import net.darkhax.bookshelf.api.util.IInventoryHelper;
4+
import net.minecraft.world.Container;
5+
import net.minecraft.world.entity.player.Player;
6+
import net.minecraftforge.common.ForgeHooks;
7+
8+
public class InventoryHelperForge implements IInventoryHelper {
9+
10+
@Override
11+
public Player getCraftingPlayer(Container container) {
12+
13+
final Player player = ForgeHooks.getCraftingPlayer();
14+
return player != null ? player : IInventoryHelper.super.getCraftingPlayer(container);
15+
}
16+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.darkhax.bookshelf.impl.util.InventoryHelperForge

0 commit comments

Comments
 (0)