Skip to content

Commit 747d96f

Browse files
committed
refactor: refactor inventory handling of block entities and menus
1 parent 7a47262 commit 747d96f

File tree

67 files changed

+1223
-1224
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1223
-1224
lines changed

src/main/java/com/github/elenterius/biomancy/api/nutrients/Nutrients.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.jetbrains.annotations.ApiStatus;
1212

1313
import java.util.function.IntUnaryOperator;
14+
import java.util.function.Predicate;
1415

1516
@ApiStatus.Experimental
1617
public final class Nutrients {
@@ -19,6 +20,7 @@ public final class Nutrients {
1920
private static final Object2IntMap<Item> REPAIR_VALUES = new Object2IntArrayMap<>();
2021

2122
public static final IntUnaryOperator RAW_MEAT_NUTRITION_MODIFIER = nutrition -> nutrition > 0 ? Mth.ceil(3.75d * Math.exp(0.215d * nutrition)) : 0;
23+
public static final Predicate<ItemStack> FUEL_PREDICATE = Nutrients::isValidFuel;
2224

2325
static {
2426
registerFuel(ModItems.NUTRIENT_PASTE.get(), 3);

src/main/java/com/github/elenterius/biomancy/block/base/MachineBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState new
5858
updateNeighbors(level, pos);
5959
}
6060
BlockEntity blockEntity = level.getBlockEntity(pos);
61-
if (blockEntity instanceof MachineBlockEntity<?, ?, ?> machine) {
61+
if (blockEntity instanceof MachineBlockEntity<?, ?> machine) {
6262
machine.dropAllInvContents(level, pos);
6363
}
6464
if (Boolean.TRUE.equals(state.getValue(CRAFTING))) {

src/main/java/com/github/elenterius/biomancy/block/base/MachineBlockEntity.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
import com.github.elenterius.biomancy.crafting.state.CraftingState;
66
import com.github.elenterius.biomancy.crafting.state.RecipeCraftingStateData;
77
import com.github.elenterius.biomancy.init.ModBlockProperties;
8+
import com.github.elenterius.biomancy.inventory.InventoryHandler;
9+
import com.github.elenterius.biomancy.util.PlayerInteractionPredicate;
810
import com.github.elenterius.biomancy.util.fuel.IFuelHandler;
911
import net.minecraft.core.BlockPos;
1012
import net.minecraft.server.level.ServerLevel;
11-
import net.minecraft.world.Container;
1213
import net.minecraft.world.Nameable;
1314
import net.minecraft.world.entity.player.Player;
1415
import net.minecraft.world.item.ItemStack;
@@ -21,7 +22,7 @@
2122
import net.minecraft.world.phys.Vec3;
2223
import org.jetbrains.annotations.Nullable;
2324

24-
public abstract class MachineBlockEntity<R extends ProcessingRecipe<C>, C extends Container, S extends RecipeCraftingStateData<R, C>> extends BlockEntity implements Nameable {
25+
public abstract class MachineBlockEntity<R extends ProcessingRecipe, S extends RecipeCraftingStateData<R>> extends BlockEntity implements Nameable, PlayerInteractionPredicate {
2526

2627
protected final int tickOffset = BiomancyMod.GLOBAL_RANDOM.nextInt(20);
2728
protected int ticks = tickOffset;
@@ -30,27 +31,33 @@ protected MachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState s
3031
super(type, pos, state);
3132
}
3233

33-
public static <R extends ProcessingRecipe<C>, C extends Container, S extends RecipeCraftingStateData<R, C>> void serverTick(Level level, BlockPos pos, BlockState state, MachineBlockEntity<R, C, S> entity) {
34+
public static <R extends ProcessingRecipe, S extends RecipeCraftingStateData<R>> void serverTick(Level level, BlockPos pos, BlockState state, MachineBlockEntity<R, S> entity) {
3435
entity.serverTick((ServerLevel) level);
3536
}
3637

37-
public boolean canPlayerOpenInv(Player player) {
38+
@Override
39+
public boolean canPlayerInteract(Player player) {
40+
if (isRemoved()) return false;
3841
if (level == null || level.getBlockEntity(worldPosition) != this) return false;
3942
return player.distanceToSqr(Vec3.atCenterOf(worldPosition)) < 8d * 8d;
4043
}
4144

45+
protected void onInventoryChanged() {
46+
if (level != null && !level.isClientSide) setChanged();
47+
}
48+
4249
public int getTicks() {
4350
return ticks - tickOffset;
4451
}
4552

4653
protected abstract S getStateData();
4754

48-
protected abstract C getInputInventory();
55+
protected abstract InventoryHandler getInputInventory();
4956

5057
protected abstract IFuelHandler getFuelHandler();
5158

5259
public int getFuelCost(R recipeToCraft) {
53-
return getFuelHandler().getFuelCost(recipeToCraft.getCraftingCostNutrients(getInputInventory()));
60+
return getFuelHandler().getFuelCost(recipeToCraft.getCraftingCostNutrients(getInputInventory().getRecipeWrapper()));
5461
}
5562

5663
public abstract ItemStack getStackInFuelSlot();
@@ -111,7 +118,7 @@ protected void serverTick(final ServerLevel level) {
111118
if (hasEnoughFuel(craftingGoal)) { //make sure there is enough fuel to craft the recipe
112119
state.setCraftingState(CraftingState.IN_PROGRESS);
113120
state.clear(); //safeguard, shouldn't be needed
114-
state.setCraftingGoalRecipe(craftingGoal, getInputInventory()); // this also sets the time required for crafting
121+
state.setCraftingGoalRecipe(craftingGoal, getInputInventory().getRecipeWrapper()); // this also sets the time required for crafting
115122
}
116123
} else if (!state.isCraftingCanceled()) { // something is being crafted, check that the crafting goals match
117124
R prevCraftingGoal = state.getCraftingGoalRecipe(level).orElse(null);
@@ -163,7 +170,7 @@ else if (state.getCraftingState() == CraftingState.NONE) {
163170

164171
private ItemStack getItemToCraft(ServerLevel level, R craftingGoal) {
165172
if (craftingGoal.isSpecial()) {
166-
return craftingGoal.assemble(getInputInventory(), level.registryAccess());
173+
return craftingGoal.assemble(getInputInventory().getRecipeWrapper(), level.registryAccess());
167174
}
168175
return craftingGoal.getResultItem(level.registryAccess());
169176
}

src/main/java/com/github/elenterius/biomancy/block/base/SimpleContainerBlockEntity.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.elenterius.biomancy.block.base;
22

3+
import com.github.elenterius.biomancy.util.PlayerInteractionPredicate;
34
import net.minecraft.core.BlockPos;
45
import net.minecraft.nbt.CompoundTag;
56
import net.minecraft.nbt.Tag;
@@ -14,15 +15,17 @@
1415
import net.minecraft.world.phys.Vec3;
1516
import org.jetbrains.annotations.Nullable;
1617

17-
public abstract class SimpleContainerBlockEntity extends BlockEntity implements MenuProvider, Nameable {
18+
public abstract class SimpleContainerBlockEntity extends BlockEntity implements MenuProvider, PlayerInteractionPredicate, Nameable {
1819

1920
protected Component name;
2021

2122
protected SimpleContainerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
2223
super(type, pos, state);
2324
}
2425

25-
public boolean canPlayerOpenContainer(Player player) {
26+
@Override
27+
public boolean canPlayerInteract(Player player) {
28+
if (isRemoved()) return false;
2629
if (level == null || level.getBlockEntity(worldPosition) != this) return false;
2730
return player.distanceToSqr(Vec3.atCenterOf(worldPosition)) < 8d * 8d;
2831
}

src/main/java/com/github/elenterius/biomancy/block/bioforge/BioForgeBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource
9090

9191
@Override
9292
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
93-
if (level.getBlockEntity(pos) instanceof BioForgeBlockEntity bioForge && bioForge.canPlayerOpenInv(player)) {
93+
if (level.getBlockEntity(pos) instanceof BioForgeBlockEntity bioForge && bioForge.canPlayerInteract(player)) {
9494
if (!level.isClientSide) {
9595
NetworkHooks.openScreen((ServerPlayer) player, bioForge, buffer -> buffer.writeBlockPos(pos));
9696
SoundUtil.broadcastBlockSound((ServerLevel) level, pos, ModSoundEvents.UI_BIO_FORGE_OPEN);

src/main/java/com/github/elenterius/biomancy/block/bioforge/BioForgeBlockEntity.java

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import com.github.elenterius.biomancy.BiomancyMod;
44
import com.github.elenterius.biomancy.init.ModBlockEntities;
55
import com.github.elenterius.biomancy.init.ModCapabilities;
6-
import com.github.elenterius.biomancy.inventory.BehavioralInventory;
7-
import com.github.elenterius.biomancy.inventory.itemhandler.HandlerBehaviors;
6+
import com.github.elenterius.biomancy.inventory.InventoryHandler;
7+
import com.github.elenterius.biomancy.inventory.InventoryHandlers;
8+
import com.github.elenterius.biomancy.inventory.ItemHandlerUtil;
89
import com.github.elenterius.biomancy.menu.BioForgeMenu;
910
import com.github.elenterius.biomancy.styles.TextComponentUtil;
11+
import com.github.elenterius.biomancy.util.PlayerInteractionPredicate;
1012
import com.github.elenterius.biomancy.util.fuel.FluidFuelConsumerHandler;
1113
import com.github.elenterius.biomancy.util.fuel.FuelHandler;
1214
import com.github.elenterius.biomancy.util.fuel.IFuelHandler;
@@ -16,13 +18,11 @@
1618
import net.minecraft.network.chat.Component;
1719
import net.minecraft.server.level.ServerLevel;
1820
import net.minecraft.util.Mth;
19-
import net.minecraft.world.Containers;
2021
import net.minecraft.world.MenuProvider;
2122
import net.minecraft.world.Nameable;
2223
import net.minecraft.world.entity.player.Inventory;
2324
import net.minecraft.world.entity.player.Player;
2425
import net.minecraft.world.inventory.AbstractContainerMenu;
25-
import net.minecraft.world.inventory.ContainerLevelAccess;
2626
import net.minecraft.world.item.ItemStack;
2727
import net.minecraft.world.level.Level;
2828
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -45,15 +45,17 @@
4545
import javax.annotation.Nonnull;
4646
import java.util.Objects;
4747

48-
public class BioForgeBlockEntity extends BlockEntity implements MenuProvider, Nameable, GeoBlockEntity {
48+
public class BioForgeBlockEntity extends BlockEntity implements MenuProvider, PlayerInteractionPredicate, Nameable, GeoBlockEntity {
4949

5050
public static final int FUEL_SLOTS = 1;
5151
public static final int MAX_FUEL = 1_000;
5252
static final int OPENERS_CHANGE_EVENT = 1;
53+
5354
protected final int tickOffset = BiomancyMod.GLOBAL_RANDOM.nextInt(20);
55+
5456
private final BioForgeStateData stateData;
5557
private final FuelHandler fuelHandler;
56-
private final BehavioralInventory<?> fuelInventory;
58+
private final InventoryHandler fuelInventory;
5759

5860
private final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
5961

@@ -82,7 +84,9 @@ protected boolean isOwnContainer(Player player) {
8284
return false;
8385
}
8486
};
87+
8588
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
89+
8690
protected int ticks = tickOffset;
8791
private boolean playWorkingAnimation = false;
8892
private int nearbyTimer = -10;
@@ -91,9 +95,7 @@ protected boolean isOwnContainer(Player player) {
9195

9296
public BioForgeBlockEntity(BlockPos worldPosition, BlockState blockState) {
9397
super(ModBlockEntities.BIO_FORGE.get(), worldPosition, blockState);
94-
fuelInventory = BehavioralInventory.createServerContents(FUEL_SLOTS, HandlerBehaviors::filterFuel, this::canPlayerOpenInv, this::setChanged);
95-
fuelInventory.setOpenInventoryConsumer(this::startOpen);
96-
fuelInventory.setCloseInventoryConsumer(this::stopOpen);
98+
fuelInventory = InventoryHandlers.filterFuel(FUEL_SLOTS, this::onInventoryChanged);
9799

98100
fuelHandler = FuelHandler.createNutrientFuelHandler(MAX_FUEL, this::setChanged);
99101
stateData = new BioForgeStateData(fuelHandler);
@@ -117,17 +119,22 @@ public boolean triggerEvent(int id, int type) {
117119
return super.triggerEvent(id, type);
118120
}
119121

120-
public boolean canPlayerOpenInv(Player player) {
122+
@Override
123+
public boolean canPlayerInteract(Player player) {
121124
if (level == null || level.getBlockEntity(worldPosition) != this) return false;
122125
return player.distanceToSqr(Vec3.atCenterOf(worldPosition)) < 8d * 8d;
123126
}
124127

125-
private void startOpen(Player player) {
128+
protected void onInventoryChanged() {
129+
if (level != null && !level.isClientSide) setChanged();
130+
}
131+
132+
public void startOpen(Player player) {
126133
if (remove || player.isSpectator()) return;
127134
openersCounter.incrementOpeners(player, Objects.requireNonNull(getLevel()), getBlockPos(), getBlockState());
128135
}
129136

130-
private void stopOpen(Player player) {
137+
public void stopOpen(Player player) {
131138
if (remove || player.isSpectator()) return;
132139
openersCounter.decrementOpeners(player, Objects.requireNonNull(getLevel()), getBlockPos(), getBlockState());
133140
}
@@ -140,7 +147,11 @@ public void recheckOpen() {
140147
@Nullable
141148
@Override
142149
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {
143-
return BioForgeMenu.createServerMenu(containerId, playerInventory, fuelInventory, stateData, ContainerLevelAccess.create(level, getBlockPos()));
150+
return BioForgeMenu.createServerMenu(containerId, playerInventory, this);
151+
}
152+
153+
public InventoryHandler getFuelInventory() {
154+
return fuelInventory;
144155
}
145156

146157
public BioForgeStateData getStateData() {
@@ -176,11 +187,11 @@ public int getMaxFuelAmount() {
176187
}
177188

178189
public ItemStack getStackInFuelSlot() {
179-
return fuelInventory.getItem(0);
190+
return fuelInventory.getStackInSlot(0);
180191
}
181192

182193
public void setStackInFuelSlot(ItemStack stack) {
183-
fuelInventory.setItem(0, stack);
194+
fuelInventory.setStackInSlot(0, stack);
184195
}
185196

186197
@Override
@@ -198,7 +209,7 @@ public void load(CompoundTag tag) {
198209
}
199210

200211
public void dropAllInvContents(Level level, BlockPos pos) {
201-
Containers.dropContents(level, pos, fuelInventory);
212+
ItemHandlerUtil.dropContents(level, pos, fuelInventory);
202213
}
203214

204215
@Nonnull
@@ -207,7 +218,7 @@ public <T> LazyOptional<T> getCapability(Capability<T> cap, @Nullable Direction
207218
if (remove) return super.getCapability(cap, side);
208219

209220
if (cap == ModCapabilities.ITEM_HANDLER && side != null && side.getAxis().isHorizontal()) {
210-
return fuelInventory.getOptionalItemHandler().cast();
221+
return fuelInventory.getLazyOptional().cast();
211222
}
212223

213224
if (cap == ModCapabilities.FLUID_HANDLER) {

src/main/java/com/github/elenterius/biomancy/block/biolab/BioLabBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, Block
7878

7979
@Override
8080
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
81-
if (level.getBlockEntity(pos) instanceof BioLabBlockEntity bioLab && bioLab.canPlayerOpenInv(player)) {
81+
if (level.getBlockEntity(pos) instanceof BioLabBlockEntity bioLab && bioLab.canPlayerInteract(player)) {
8282
if (!level.isClientSide) {
8383
NetworkHooks.openScreen((ServerPlayer) player, bioLab, buffer -> buffer.writeBlockPos(pos));
8484
SoundUtil.broadcastBlockSound((ServerLevel) level, pos, ModSoundEvents.UI_BIO_LAB_OPEN);

0 commit comments

Comments
 (0)