Skip to content

Commit

Permalink
trying add crafting and water handling inside blockentity
Browse files Browse the repository at this point in the history
  • Loading branch information
MEGATREX4 committed Jul 4, 2024
1 parent f16bcb7 commit 693d362
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.megatrex4.ukrainian_dlight.block.custom;


import com.megatrex4.ukrainian_dlight.block.entity.BrewingKegBlockEntity;
import com.megatrex4.ukrainian_dlight.block.entity.ModBlockEntities;
import net.minecraft.block.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,45 @@
package com.megatrex4.ukrainian_dlight.block.entity;

import com.megatrex4.ukrainian_dlight.block.DrinkBottleBlock;
import com.megatrex4.ukrainian_dlight.block.ModBlocks;
import com.megatrex4.ukrainian_dlight.item.DrinkBlockItem;
import com.megatrex4.ukrainian_dlight.item.ModItems;
import com.megatrex4.ukrainian_dlight.networking.ModMessages;
import com.megatrex4.ukrainian_dlight.recipe.BrewingRecipe;
import com.megatrex4.ukrainian_dlight.screen.BrewingKegScreenHandler;
import com.megatrex4.ukrainian_dlight.util.FluidStack;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleVariantStorage;
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.fluid.Fluids;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

public class BrewingKegBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory, ImplementedInventory {
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(10, ItemStack.EMPTY);

Expand All @@ -39,21 +53,41 @@ public class BrewingKegBlockEntity extends BlockEntity implements ExtendedScreen
//adds container(like bottle of vial) input
public static final int CONTAINER_SLOT = 6;
//adds 1 input slot for water
public static final int INPUT_SLOT = 7;
public static final int WATER_SLOT = 7;
//adds 1 output slot and display slot
public static final int DRINKS_DISPLAY_SLOT = 8;
public static final int OUTPUT_SLOT = 9;

protected final PropertyDelegate propertyDelegate;
private int progress;
private int maxProgress = 72;
private int maxProgress = 200; // Adjusted to match the brewing time in the JSON

public final SingleVariantStorage<FluidVariant> fluidStorage = new SingleVariantStorage<FluidVariant>() {
@Override
protected FluidVariant getBlankVariant() {
return FluidVariant.blank();
}

@Override
protected long getCapacity(FluidVariant variant) {
return FluidStack.convertDropletsToMb(FluidConstants.BUCKET) * 20; // 20k mB
}

@Override
protected void onFinalCommit() {
markDirty();
if(!world.isClient()) {
sendFluidPacket();
}
}
};

public BrewingKegBlockEntity(BlockPos pos, BlockState state){
public BrewingKegBlockEntity(BlockPos pos, BlockState state) {
super(ModBlockEntities.BREWING_KEG_BLOCK_ENTITY, pos, state);
this.propertyDelegate = new PropertyDelegate() {
@Override
public int get(int index) {
return switch (index){
return switch (index) {
case 0 -> BrewingKegBlockEntity.this.progress;
case 1 -> BrewingKegBlockEntity.this.maxProgress;
default -> 0;
Expand All @@ -62,7 +96,7 @@ public int get(int index) {

@Override
public void set(int index, int value) {
switch (index){
switch (index) {
case 0 -> BrewingKegBlockEntity.this.progress = value;
case 1 -> BrewingKegBlockEntity.this.maxProgress = value;
}
Expand All @@ -85,13 +119,23 @@ protected void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
Inventories.writeNbt(nbt, inventory);
nbt.putInt("brewing_keg.progress", progress);
nbt.put("brewing_keg.fluid_variant", fluidStorage.variant.toNbt());
nbt.putLong("brewing_keg.fluid_amount", fluidStorage.amount);
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
Inventories.readNbt(nbt, inventory);
progress = nbt.getInt("brewing_keg.progress");
fluidStorage.variant = FluidVariant.fromNbt(nbt.getCompound("brewing_keg.fluid_variant"));
fluidStorage.amount = nbt.getLong("brewing_keg.fluid_amount");
}


private void debugFluidLevel() {
System.out.println("Fluid: " + fluidStorage.variant.getFluid().toString());
System.out.println("Amount: " + fluidStorage.amount + " mB");
}

@Override
Expand All @@ -107,21 +151,23 @@ public Text getDisplayName() {
@Nullable
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
sendFluidPacket();
return new BrewingKegScreenHandler(syncId, playerInventory, this, propertyDelegate);
}

public void tick(World world, BlockPos pos, BlockState state) {
if(world.isClient){
if (world.isClient) {
return;
}

if(isOutoutSlotEmptyOrReceivable()){
if(this.hasRecipe()){
if (isOutputSlotEmptyOrReceivable()) {
if (this.hasRecipe() && hasEnoughFluid()) {
this.increaseCraftProgress();
markDirty(world, pos, state);

if(hasCraftingFinished()){
if (hasCraftingFinished()) {
this.craftItem();
extractFluid();
this.resetProgress();
}
} else {
Expand All @@ -133,6 +179,43 @@ public void tick(World world, BlockPos pos, BlockState state) {
}
}

private void extractFluid() {
try (Transaction transaction = Transaction.openOuter()) {
this.fluidStorage.extract(FluidVariant.of(Fluids.WATER), 500, transaction);
transaction.commit();
}
}

private static void transferFluidToFluidStorage(BrewingKegBlockEntity entity) {
try(Transaction transaction = Transaction.openOuter()) {
entity.fluidStorage.insert(FluidVariant.of(Fluids.WATER),
FluidStack.convertDropletsToMb(FluidConstants.BUCKET), transaction);
transaction.commit();
entity.setStack(0, new ItemStack(Items.BUCKET));
}
}


private boolean hasEnoughFluid() {
return this.fluidStorage.amount >= 500; // mB amount!
}

private void sendFluidPacket() {
PacketByteBuf data = PacketByteBufs.create();
fluidStorage.variant.toPacket(data);
data.writeLong(fluidStorage.amount);
data.writeBlockPos(getPos());

for (ServerPlayerEntity player : PlayerLookup.tracking((ServerWorld) world, getPos())) {
ServerPlayNetworking.send(player, ModMessages.FLUID_SYNC, data);
}
}

public void setFluidLevel(FluidVariant fluidVariant, long fluidLevel) {
this.fluidStorage.variant = fluidVariant;
this.fluidStorage.amount = fluidLevel;
}

private void resetProgress() {
this.progress = 0;
}
Expand All @@ -152,21 +235,19 @@ private void increaseCraftProgress() {
}

private boolean hasRecipe() {
ItemStack result = new ItemStack(DrinkBottleBlock.WINE_BOTTLE);
boolean hasInput = getStack(INGREDIENT_SLOT_1).getItem() == ModItems.APPLE_SLICE;

return hasInput && canInsertAmoutIntoOutputSlot(result) && canInstertItemIntoOutputSlot(result.getItem());
Optional<BrewingRecipe> recipe = world.getRecipeManager().getFirstMatch(BrewingRecipe.Type.INSTANCE, this, world);
return recipe.isPresent() && canInsertAmountIntoOutputSlot(recipe.get().getResult()) && canInsertItemIntoOutputSlot(recipe.get().getResult().getItem());
}

private boolean canInstertItemIntoOutputSlot(Item item) {
return this.getStack(OUTPUT_SLOT).getItem() == item || this.getStack(OUTPUT_SLOT).isEmpty();
private boolean canInsertItemIntoOutputSlot(Item item) {
return this.getStack(OUTPUT_SLOT).getItem() == item || this.getStack(OUTPUT_SLOT).isEmpty();
}

private boolean canInsertAmoutIntoOutputSlot(ItemStack result) {
return this.getStack(OUTPUT_SLOT).getCount() + result.getCount() <= getStack(OUTPUT_SLOT).getMaxCount();
private boolean canInsertAmountIntoOutputSlot(ItemStack result) {
return this.getStack(OUTPUT_SLOT).getCount() + result.getCount() <= this.getStack(OUTPUT_SLOT).getMaxCount();
}

private boolean isOutoutSlotEmptyOrReceivable() {
private boolean isOutputSlotEmptyOrReceivable() {
return this.getStack(OUTPUT_SLOT).isEmpty() || this.getStack(OUTPUT_SLOT).getCount() < this.getStack(OUTPUT_SLOT).getMaxCount();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.megatrex4.ukrainian_dlight.networking;

import com.megatrex4.ukrainian_dlight.UkrainianDelight;
import com.megatrex4.ukrainian_dlight.networking.packet.FluidSyncS2CPacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.util.Identifier;

public class ModMessages {
public static final Identifier FLUID_SYNC = new Identifier(UkrainianDelight.MOD_ID, "fluid_sync");

public static void registerS2CPackets() {
ClientPlayNetworking.registerGlobalReceiver(FLUID_SYNC, FluidSyncS2CPacket::receive);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.megatrex4.ukrainian_dlight.networking.packet;

import com.megatrex4.ukrainian_dlight.block.entity.BrewingKegBlockEntity;
import com.megatrex4.ukrainian_dlight.screen.BrewingKegScreenHandler;
import com.megatrex4.ukrainian_dlight.util.FluidStack;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.math.BlockPos;

public class FluidSyncS2CPacket {
public static void receive(MinecraftClient client, ClientPlayNetworkHandler handler,
PacketByteBuf buf, PacketSender responseSender) {
FluidVariant variant = FluidVariant.fromPacket(buf);
long fluidLevel = buf.readLong();
BlockPos position = buf.readBlockPos();

if(client.world.getBlockEntity(position) instanceof BrewingKegBlockEntity blockEntity) {
blockEntity.setFluidLevel(variant, fluidLevel);

if(client.player.currentScreenHandler instanceof BrewingKegScreenHandler screenHandler &&
screenHandler.blockEntity.getPos().equals(position)) {
blockEntity.setFluidLevel(variant, fluidLevel);
screenHandler.setFluid(new FluidStack(variant, fluidLevel));
}
}
}
}
Loading

0 comments on commit 693d362

Please sign in to comment.