Skip to content

Commit

Permalink
fix Brewing Keg shift-click on the item moves the item to the cell wi…
Browse files Browse the repository at this point in the history
…th DISPLAY_SLOT or OUTPUT_SLOT (quickMove function)

adds buggy Brewing Keg recipe
adds ModRecipe register
update onInitialize
update crafting behavior in BrewingKegBlockEntity
added DISPLAY SLOT what save in NBT data container and filling with drinks
fix tick behavior
update en_us.json
  • Loading branch information
MEGATREX4 committed Jul 5, 2024
1 parent fd16ba8 commit 41ae1a1
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.megatrex4.ukrainian_dlight.item.ModItems;
import com.megatrex4.ukrainian_dlight.item.ToolTipHelper;
import com.megatrex4.ukrainian_dlight.networking.ModMessages;
import com.megatrex4.ukrainian_dlight.recipe.ModRecipes;
import com.megatrex4.ukrainian_dlight.screen.ModScreenHandlers;
import com.megatrex4.ukrainian_dlight.screen.ModScreens;
import net.fabricmc.api.ModInitializer;
Expand Down Expand Up @@ -42,6 +43,7 @@ public void onInitialize() {
ModBlockEntities.registerBLockEntities();
ModScreenHandlers.registerModScreenHandlers();
ModMessages.registerS2CPackets();
ModRecipes.registerRecipes();

ModScreens.registerScreens();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.megatrex4.ukrainian_dlight.block.DrinkBottleBlock;
import com.megatrex4.ukrainian_dlight.networking.ModMessages;
import com.megatrex4.ukrainian_dlight.recipe.BrewingRecipe;
import com.megatrex4.ukrainian_dlight.recipe.ModRecipes;
import com.megatrex4.ukrainian_dlight.screen.BrewingKegScreenHandler;
import com.megatrex4.ukrainian_dlight.util.FluidStack;
import io.netty.buffer.Unpooled;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class BrewingKegBlockEntity extends BlockEntity implements ExtendedScreen
protected final PropertyDelegate propertyDelegate;
private int progress;
private int maxProgress = 200; // Adjusted to match the brewing time in the JSON
private ItemStack drinkContainer = ItemStack.EMPTY;

public final SingleVariantStorage<FluidVariant> fluidStorage = new SingleVariantStorage<FluidVariant>() {
@Override
Expand All @@ -71,9 +73,10 @@ protected FluidVariant getBlankVariant() {

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


@Override
protected void onFinalCommit() {
markDirty();
Expand Down Expand Up @@ -126,6 +129,11 @@ protected void writeNbt(NbtCompound nbt) {
nbt.putInt("brewing_keg.progress", progress);
nbt.put("brewing_keg.fluid_variant", fluidStorage.variant.toNbt());
nbt.putLong("brewing_keg.fluid_amount", fluidStorage.amount);

// Save drinkContainer
NbtCompound containerTag = new NbtCompound();
drinkContainer.writeNbt(containerTag);
nbt.put("Container", containerTag);
}

@Override
Expand All @@ -135,9 +143,15 @@ public void readNbt(NbtCompound nbt) {
progress = nbt.getInt("brewing_keg.progress");
fluidStorage.variant = FluidVariant.fromNbt(nbt.getCompound("brewing_keg.fluid_variant"));
fluidStorage.amount = nbt.getLong("brewing_keg.fluid_amount");

// Load drinkContainer
NbtCompound containerTag = nbt.getCompound("Container");
drinkContainer = ItemStack.fromNbt(containerTag);
}




private void debugFluidLevel() {
System.out.println("Fluid: " + fluidStorage.variant.getFluid().toString());
System.out.println("Amount: " + fluidStorage.amount + " mB");
Expand Down Expand Up @@ -168,25 +182,73 @@ public void tick(World world, BlockPos pos, BlockState state) {
// Handle water bucket conversion
handleWaterBucket();

if (isOutputSlotEmptyOrReceivable()) {
if (this.hasRecipe() && hasEnoughFluid()) {
this.increaseCraftProgress();
// Check if a crafted item is ready to be moved to the OUTPUT_SLOT
ItemStack displayStack = getStack(DRINKS_DISPLAY_SLOT);
ItemStack containerStack = getStack(CONTAINER_SLOT);
ItemStack outputStack = getStack(OUTPUT_SLOT);

// Check if the container matches the saved drinkContainer item
if (!displayStack.isEmpty() && !containerStack.isEmpty() && containerStack.getItem() == drinkContainer.getItem()) {
// Only decrement the container if the OUTPUT_SLOT can receive more items
if (isOutputSlotEmptyOrReceivable(outputStack)) {
containerStack.decrement(1);

if (outputStack.isEmpty()) {
setStack(OUTPUT_SLOT, new ItemStack(displayStack.getItem(), 1));
displayStack.decrement(1);
} else if (ItemStack.canCombine(outputStack, displayStack)) {
int maxCount = outputStack.getMaxCount();
if (outputStack.getCount() < maxCount) {
outputStack.increment(1);
displayStack.decrement(1);
}
}

// Clear the DRINKS_DISPLAY_SLOT and drinkContainer if empty
if (displayStack.isEmpty()) {
setStack(DRINKS_DISPLAY_SLOT, ItemStack.EMPTY);
drinkContainer = ItemStack.EMPTY;
}

markDirty(world, pos, state);
}
}

if (hasCraftingFinished()) {
this.craftItem();
extractFluid();
Optional<BrewingRecipe> match = getCurrentRecipe();
if (match.isPresent()) {
BrewingRecipe recipe = match.get();
ItemStack output = recipe.craft(this, world.getRegistryManager());

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

if (hasCraftingFinished()) {
this.craftItem();
this.resetProgress();
}
} else {
this.resetProgress();
}
} else {
this.resetProgress();
markDirty(world, pos, state);
}
} else {
this.resetProgress();
markDirty(world, pos, state);
}
}


private boolean isOutputSlotEmptyOrReceivable(ItemStack output) {
ItemStack outputStack = this.getStack(OUTPUT_SLOT);
return outputStack.isEmpty() || (ItemStack.canCombine(outputStack, output) && outputStack.getCount() < outputStack.getMaxCount());
}






private void handleWaterBucket() {
ItemStack waterBucketStack = this.getStack(WATER_SLOT);

Expand All @@ -206,12 +268,6 @@ private void handleWaterBucket() {
}
}

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()) {
Expand All @@ -224,9 +280,15 @@ private static void transferFluidToFluidStorage(BrewingKegBlockEntity entity) {


private boolean hasEnoughFluid() {
return this.fluidStorage.amount >= 500; // mB amount!
Optional<BrewingRecipe> match = getCurrentRecipe();
if (match.isPresent()) {
BrewingRecipe recipe = match.get();
return fluidStorage.amount >= recipe.getWaterAmount();
}
return false;
}


private void sendFluidPacket() {
PacketByteBuf data = PacketByteBufs.create();
fluidStorage.variant.toPacket(data);
Expand All @@ -247,12 +309,6 @@ private void resetProgress() {
this.progress = 0;
}

private void craftItem() {
this.removeStack(INGREDIENT_SLOT_1, 1);
ItemStack result = new ItemStack(DrinkBottleBlock.WINE_BOTTLE);
this.setStack(OUTPUT_SLOT, new ItemStack(result.getItem(), getStack(OUTPUT_SLOT).getCount() + result.getCount()));
}

private boolean hasCraftingFinished() {
return progress >= maxProgress;
}
Expand All @@ -261,9 +317,86 @@ private void increaseCraftProgress() {
progress++;
}

private Optional<BrewingRecipe> getCurrentRecipe() {
if (world == null) return Optional.empty();
return world.getRecipeManager().getFirstMatch(ModRecipes.BREWING, this, world);
}

private boolean hasRecipe() {
Optional<BrewingRecipe> recipe = world.getRecipeManager().getFirstMatch(BrewingRecipe.Type.INSTANCE, this, world);
return recipe.isPresent() && canInsertAmountIntoOutputSlot(recipe.get().getResult()) && canInsertItemIntoOutputSlot(recipe.get().getResult().getItem());
Optional<BrewingRecipe> match = getCurrentRecipe();
if (match.isPresent()) {
BrewingRecipe recipe = match.get();
boolean hasWater = fluidStorage.amount >= recipe.getWaterAmount();
return hasWater && match.get().matches(this, world);
}
return false;
}


private void craftItem() {
Optional<BrewingRecipe> match = getCurrentRecipe();
if (match.isPresent()) {
BrewingRecipe recipe = match.get();
ItemStack output = recipe.craft(this, world.getRegistryManager());

// Check if all ingredient slots have enough items
for (int i = 0; i < 6; i++) {
ItemStack ingredientStack = getStack(i);
if (ingredientStack.getCount() <= 0) {
return; // Stop crafting if any ingredient slot is empty
}
}

// Ensure the crafting only starts if the DRINKS_DISPLAY_SLOT is empty or contains the same item
if (!getStack(DRINKS_DISPLAY_SLOT).isEmpty() && !ItemStack.canCombine(getStack(DRINKS_DISPLAY_SLOT), output)) {
return;
}

// Check if there's enough fluid for the recipe
if (hasEnoughFluid()) {
extractFluid(recipe.getWaterAmount());

// Decrement ingredients
for (int i = 0; i < 6; i++) {
getStack(i).decrement(1);
}

// Move the crafted item to the DRINKS_DISPLAY_SLOT
if (!output.isEmpty()) {
if (getStack(DRINKS_DISPLAY_SLOT).isEmpty()) {
setStack(DRINKS_DISPLAY_SLOT, new ItemStack(output.getItem(), 1)); // Only one bottle
drinkContainer = recipe.getContainer(); // Save the container item from the recipe
} else if (ItemStack.canCombine(getStack(DRINKS_DISPLAY_SLOT), output)) {
getStack(DRINKS_DISPLAY_SLOT).increment(1); // Only increment by one
} else {
// Handle case where items cannot combine but DRINKS_DISPLAY_SLOT is not empty
return;
}
}

// Mark the block entity as dirty after crafting
markDirty();
}
}
}













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

private boolean canInsertItemIntoOutputSlot(Item item) {
Expand All @@ -274,8 +407,9 @@ private boolean canInsertAmountIntoOutputSlot(ItemStack result) {
return this.getStack(OUTPUT_SLOT).getCount() + result.getCount() <= this.getStack(OUTPUT_SLOT).getMaxCount();
}

private boolean isOutputSlotEmptyOrReceivable() {
return this.getStack(OUTPUT_SLOT).isEmpty() || this.getStack(OUTPUT_SLOT).getCount() < this.getStack(OUTPUT_SLOT).getMaxCount();
private boolean isDisplaySlotEmptyOrReceivable(ItemStack output) {
ItemStack displayStack = this.getStack(DRINKS_DISPLAY_SLOT);
return displayStack.isEmpty() || (ItemStack.canCombine(displayStack, output) && displayStack.getCount() < displayStack.getMaxCount());
}

public void syncFluidToClient() {
Expand Down
Loading

0 comments on commit 41ae1a1

Please sign in to comment.