Skip to content

Commit

Permalink
Fluid Handler for EXP Holder
Browse files Browse the repository at this point in the history
  • Loading branch information
Direwolf20-MC committed Sep 13, 2024
1 parent 02609eb commit 07f9876
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// 1.21.1 2024-09-13T13:43:18.3815776 Languages: en_us for mod: justdirethings
a4ea5c922b56481d51520c57e5bed3dc238465e4 assets/justdirethings/lang/en_us.json
// 1.21.1 2024-09-13T13:53:01.5331943 Languages: en_us for mod: justdirethings
50598341120df2f850d5821435699dff7b3dcdb3 assets/justdirethings/lang/en_us.json
2 changes: 2 additions & 0 deletions src/generated/resources/assets/justdirethings/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,10 @@
"justdirethings.screen.paradoxentity": "Revert Entities",
"justdirethings.screen.paradoxfluidcost": "Fluid Cost: %s mb",
"justdirethings.screen.pickupdelay": "Pickup Delay (Ticks)",
"justdirethings.screen.pullfluids": "Pull Fluids",
"justdirethings.screen.pullitems": "Pull Items",
"justdirethings.screen.pulse": "Pulse",
"justdirethings.screen.pushfluids": "Push Fluids",
"justdirethings.screen.redstone-strong": "Strong Signal",
"justdirethings.screen.redstone-weak": "Weak Signal",
"justdirethings.screen.remove_favorite": "Remove Favorite",
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/com/direwolf20/justdirethings/JustDireThings.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.direwolf20.justdirethings;

import com.direwolf20.justdirethings.common.blockentities.EnergyTransmitterBE;
import com.direwolf20.justdirethings.common.blockentities.InventoryHolderBE;
import com.direwolf20.justdirethings.common.blockentities.ParadoxMachineBE;
import com.direwolf20.justdirethings.common.blockentities.PlayerAccessorBE;
import com.direwolf20.justdirethings.common.blockentities.*;
import com.direwolf20.justdirethings.common.blockentities.basebe.BaseMachineBE;
import com.direwolf20.justdirethings.common.blockentities.basebe.FluidMachineBE;
import com.direwolf20.justdirethings.common.blockentities.basebe.PoweredMachineBE;
import com.direwolf20.justdirethings.common.capabilities.EnergyStorageItemStackNoReceive;
import com.direwolf20.justdirethings.common.capabilities.EnergyStorageItemstack;
import com.direwolf20.justdirethings.common.capabilities.ExperienceHolderFluidTank;
import com.direwolf20.justdirethings.common.containers.handlers.PotionCanisterHandler;
import com.direwolf20.justdirethings.common.entities.DecoyEntity;
import com.direwolf20.justdirethings.common.fluids.xpfluid.XPFluid;
import com.direwolf20.justdirethings.common.items.FluidCanister;
import com.direwolf20.justdirethings.common.items.PortalGunV2;
import com.direwolf20.justdirethings.common.items.TimeWand;
Expand Down Expand Up @@ -301,5 +300,14 @@ public boolean canFillFluidType(FluidStack fluid) {
},
Registration.ParadoxMachine.get()
);
event.registerBlock(Capabilities.FluidHandler.BLOCK,
(level, pos, state, be, side) -> {
if (be instanceof ExperienceHolderBE experienceHolderBE) {
return new ExperienceHolderFluidTank(experienceHolderBE, fluidstack -> fluidstack.getFluid() instanceof XPFluid); //TODO Tags?
}
return null;
},
Registration.ExperienceHolder.get()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ public static ToggleButton ALLOWLISTBUTTON(int x, int y, boolean startingValue,
return new ToggleButton(x, y, STANDARD_WIDTH, STANDARD_HEIGHT, ALLOW_LIST_TEXTURES, startingValue, onPress);
}

private static final List<TextureLocalization> PUSH_PULL_FLUIDS_TEXTURES = List.of(
new TextureLocalization(ResourceLocation.fromNamespaceAndPath(JustDireThings.MODID, "textures/gui/buttons/pullfluids.png"), Component.translatable("justdirethings.screen.pullfluids")),
new TextureLocalization(ResourceLocation.fromNamespaceAndPath(JustDireThings.MODID, "textures/gui/buttons/pushfluids.png"), Component.translatable("justdirethings.screen.pushfluids"))
);

public static ToggleButton PUSHPULLFLUIDSBUTTON(int x, int y, boolean startingValue, Button.OnPress onPress) {
return new ToggleButton(x, y, STANDARD_WIDTH, STANDARD_HEIGHT, PUSH_PULL_FLUIDS_TEXTURES, startingValue, onPress);
}

private static final ResourceLocation STORE_EXP_BUTTON = ResourceLocation.fromNamespaceAndPath(JustDireThings.MODID, "textures/gui/buttons/add.png");
private static final Component STORE_EXP_BUTTON_LOCALIZATION = Component.translatable("justdirethings.screen.storeexp");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;

import java.util.List;

public class ExperienceHolderBE extends BaseMachineBE implements AreaAffectingBE, RedstoneControlledBE {
protected BlockCapabilityCache<IFluidHandler, Direction> attachedTank;
public FilterData filterData = new FilterData();
public AreaAffectingData areaAffectingData = new AreaAffectingData(getBlockState().getValue(BlockStateProperties.FACING).getOpposite());
public RedstoneControlData redstoneControlData = getDefaultRedstoneData();
Expand Down Expand Up @@ -76,6 +80,12 @@ public int addExp(int addition) {
}
}

public int subExp(int subtraction) {
int amtToRemove = Math.min(exp, subtraction);
this.exp = this.exp - amtToRemove;
return subtraction - amtToRemove;
}

public void storeExp(Player player, int levelChange) {
if (levelChange == -1) {
// Move all experience from player
Expand Down Expand Up @@ -235,6 +245,22 @@ private void findTargetPlayer() {
}
}

private IFluidHandler getAttachedTank() {
if (attachedTank == null) {
assert this.level != null;
BlockState state = level.getBlockState(getBlockPos());
Direction facing = state.getValue(BlockStateProperties.FACING);
BlockPos inventoryPos = getBlockPos().relative(facing);
attachedTank = BlockCapabilityCache.create(
Capabilities.FluidHandler.BLOCK, // capability to cache
(ServerLevel) this.level, // level
inventoryPos, // target position
facing.getOpposite() // context (The side of the block we're trying to pull/push from?)
);
}
return attachedTank.getCapability();
}

@Override
public void saveAdditional(CompoundTag tag, HolderLookup.Provider provider) {
super.saveAdditional(tag, provider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,34 @@
import com.direwolf20.justdirethings.common.containers.ExperienceHolderContainer;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BucketItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;

import javax.annotation.Nullable;
import java.util.stream.Stream;
Expand Down Expand Up @@ -114,6 +127,44 @@ public void openMenu(Player player, BlockPos blockPos) {
}));
}

@Override
protected ItemInteractionResult useItemOn(ItemStack itemStack, BlockState blockState, Level level, BlockPos blockPos, Player player, InteractionHand hand, BlockHitResult blockHitResult) {
if (level.isClientSide) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
IFluidHandlerItem fluidHandlerItem = itemStack.getCapability(Capabilities.FluidHandler.ITEM);
if (fluidHandlerItem != null) {
IFluidHandler cap = level.getCapability(Capabilities.FluidHandler.BLOCK, blockPos, blockHitResult.getDirection());
if (cap == null) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
if (fluidHandlerItem.getFluidInTank(0).getAmount() < fluidHandlerItem.getTankCapacity(0) && !cap.getFluidInTank(0).isEmpty()) {
FluidStack testStack = cap.drain(fluidHandlerItem.getTankCapacity(0), IFluidHandler.FluidAction.SIMULATE);
if (testStack.getAmount() > 0) {
int amtFit = fluidHandlerItem.fill(testStack, IFluidHandler.FluidAction.SIMULATE);
if (amtFit > 0) {
FluidStack extractedStack = cap.drain(amtFit, IFluidHandler.FluidAction.EXECUTE);
fluidHandlerItem.fill(extractedStack, IFluidHandler.FluidAction.EXECUTE);
if (itemStack.getItem() instanceof BucketItem)
player.setItemSlot(hand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND, fluidHandlerItem.getContainer());
level.playSound(null, blockPos, SoundEvents.BUCKET_FILL, SoundSource.BLOCKS, 1F, 1.0F);
return ItemInteractionResult.SUCCESS;
}
}
} else {
FluidStack fluidStack = fluidHandlerItem.getFluidInTank(0);
int insertAmt = cap.fill(fluidStack, IFluidHandler.FluidAction.SIMULATE);
if (insertAmt > 0) {
FluidStack extractedStack = fluidHandlerItem.drain(insertAmt, IFluidHandler.FluidAction.EXECUTE);
if (!extractedStack.isEmpty()) {
cap.fill(extractedStack, IFluidHandler.FluidAction.EXECUTE);
if (itemStack.getItem() instanceof BucketItem)
player.setItemSlot(hand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND, fluidHandlerItem.getContainer());
level.playSound(null, blockPos, SoundEvents.BUCKET_EMPTY, SoundSource.BLOCKS, 1F, 1.0F);
return ItemInteractionResult.SUCCESS;
}
}
}
}
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}

@Override
public boolean isValidBE(BlockEntity blockEntity) {
return blockEntity instanceof ExperienceHolderBE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.direwolf20.justdirethings.common.capabilities;

import com.direwolf20.justdirethings.common.blockentities.ExperienceHolderBE;
import com.direwolf20.justdirethings.setup.Registration;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;

import java.util.function.Predicate;

public class ExperienceHolderFluidTank extends FluidTank {
private final ExperienceHolderBE experienceHolderBE;

public ExperienceHolderFluidTank(ExperienceHolderBE experienceHolderBE, Predicate<FluidStack> validator) {
super(Integer.MAX_VALUE, validator);
this.experienceHolderBE = experienceHolderBE;
fluid = new FluidStack(Registration.XP_FLUID_SOURCE.get(), getFluidAmount());
}

public int getFluidAmount() {
// Prevent overflow by capping experienceHolderBE.exp at Integer.MAX_VALUE / 20
if (experienceHolderBE.exp > Integer.MAX_VALUE / 20) {
return Integer.MAX_VALUE; // If multiplying by 20 would overflow, return max int value
}

// Safe to multiply without overflow
return Math.min(experienceHolderBE.exp * 20, getCapacity());
}

public int getCapacity() {
return Integer.MAX_VALUE;
}

@Override
public int fill(FluidStack resource, FluidAction action) {
if (resource.isEmpty() || !isFluidValid(resource)) {
return 0;
}
if (action.simulate()) {
if (fluid.isEmpty()) {
return Math.min(capacity, resource.getAmount() - resource.getAmount() % 20);
}
if (!FluidStack.isSameFluidSameComponents(fluid, resource)) {
return 0;
}
return Math.min(capacity - getFluidAmount() - ((capacity - getFluidAmount()) % 20), resource.getAmount() - resource.getAmount() % 20);
}
if (fluid.isEmpty()) {
return resource.getAmount() - insertFluid(resource.getAmount());
}
if (!FluidStack.isSameFluidSameComponents(fluid, resource)) {
return 0;
}
int filled = resource.getAmount() - insertFluid(resource.getAmount());
if (filled > 0)
onContentsChanged();
return filled;
}

public int insertFluid(int amt) {
int remaining = experienceHolderBE.addExp(amt / 20);
int excessFluid = amt % 20; // Calculate remainder fluid (less than 1 XP)
return (remaining * 20) + excessFluid;
}

public int extractFluid(int amt) {
int expNeeded = amt / 20;
int unAvailable = experienceHolderBE.subExp(expNeeded);
return (unAvailable * 20) + (amt % 20);
}

@Override
public FluidStack drain(FluidStack resource, FluidAction action) {
if (resource.isEmpty() || !FluidStack.isSameFluidSameComponents(resource, fluid)) {
return FluidStack.EMPTY;
}
return drain(resource.getAmount(), action);
}

@Override
public FluidStack drain(int maxDrain, FluidAction action) {
int drained = maxDrain - (maxDrain % 20); //Trim remainder
if (getFluidAmount() < drained) {
drained = getFluidAmount();
}
FluidStack stack = fluid.copyWithAmount(drained);
if (action.execute() && drained > 0) {
extractFluid(drained);
onContentsChanged();
}
return stack;
}

@Override
protected void onContentsChanged() {
experienceHolderBE.markDirtyClient();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ protected void addTranslations() {
add("justdirethings.screen.targetexp", "Target Level");
add("justdirethings.screen.owneronly", "Owner Only");
add("justdirethings.screen.collectexp", "Collect Experience");
add("justdirethings.screen.pushfluids", "Push Fluids");
add("justdirethings.screen.pullfluids", "Pull Fluids");

//Buttons
//add("justdirethings.buttons.save", "Save");
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 07f9876

Please sign in to comment.