diff --git a/src/main/java/com/acethewildfire/acesbs/AcesBS.java b/src/main/java/com/acethewildfire/acesbs/AcesBS.java index 8ce599f..4cf66c9 100644 --- a/src/main/java/com/acethewildfire/acesbs/AcesBS.java +++ b/src/main/java/com/acethewildfire/acesbs/AcesBS.java @@ -10,6 +10,7 @@ import com.acethewildfire.acesbs.entity.custom.FrenEntity; import com.acethewildfire.acesbs.item.ModItemGroups; import com.acethewildfire.acesbs.item.ModItems; import com.acethewildfire.acesbs.potion.ModPotions; +import com.acethewildfire.acesbs.recipe.ModRecipies; import com.acethewildfire.acesbs.screen.ModScreenHandlers; import com.acethewildfire.acesbs.sounds.ModSounds; import com.acethewildfire.acesbs.util.HammerUsageEvent; @@ -56,6 +57,7 @@ public class AcesBS implements ModInitializer { ModEntities.registerModEntities(); ModBlockEntities.registerBlockEntities(); ModScreenHandlers.registerScreenHandlers(); + ModRecipies.registerRecipes(); ModDataComponentTypes.registerDataComponentsTypes(); diff --git a/src/main/java/com/acethewildfire/acesbs/block/custom/EntropicStabilizer.java b/src/main/java/com/acethewildfire/acesbs/block/custom/EntropicStabilizer.java index 5f56b95..3121db6 100644 --- a/src/main/java/com/acethewildfire/acesbs/block/custom/EntropicStabilizer.java +++ b/src/main/java/com/acethewildfire/acesbs/block/custom/EntropicStabilizer.java @@ -1,12 +1,16 @@ package com.acethewildfire.acesbs.block.custom; +import com.acethewildfire.acesbs.block.entity.ModBlockEntities; import com.acethewildfire.acesbs.block.entity.custom.EntropicStabilizerEntity; import com.mojang.serialization.MapCodec; import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; +import net.minecraft.screen.NamedScreenHandlerFactory; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.state.StateManager; @@ -60,31 +64,25 @@ public class EntropicStabilizer extends BlockWithEntity implements BlockEntityPr @Override protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if(world.getBlockEntity(pos) instanceof EntropicStabilizerEntity entropicStabilizerEntity) { -// if(entropicStabilizerEntity.isEmpty() && !stack.isEmpty()) { -// entropicStabilizerEntity.setStack(0, stack.copyWithCount(1)); -// world.playSound(player, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1f, 2f); -// stack.decrement(1); -// -// entropicStabilizerEntity.markDirty(); -// world.updateListeners(pos, state, state, 0); -// } -// else if(!entropicStabilizerEntity.isEmpty() && stack.isEmpty() && !player.isSneaking()) { -// ItemStack stackOnPedestal = entropicStabilizerEntity.getStack(0); -// player.setStackInHand(Hand.MAIN_HAND, stackOnPedestal); -// world.playSound(player, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1f, 1f); -// entropicStabilizerEntity.clear(); -// -// entropicStabilizerEntity.markDirty(); -// world.updateListeners(pos, state, state, 0); -// } - if(!player.isSneaking() && !world.isClient()) { - player.openHandledScreen(entropicStabilizerEntity); + if (!world.isClient) { + NamedScreenHandlerFactory screenHandlerFactory = ((EntropicStabilizerEntity) world.getBlockEntity(pos)); + if (screenHandlerFactory != null) { + player.openHandledScreen(screenHandlerFactory); } + } + return ItemActionResult.SUCCESS; + } + + @Nullable + @Override + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + if(world.isClient()) { + return null; } - return ItemActionResult.SUCCESS; + return validateTicker(type, ModBlockEntities.E_STABILIZER_BE, + (world1, pos, state1, blockEntity) -> blockEntity.tick(world1, pos, state1)); } @Override diff --git a/src/main/java/com/acethewildfire/acesbs/block/entity/custom/EntropicStabilizerEntity.java b/src/main/java/com/acethewildfire/acesbs/block/entity/custom/EntropicStabilizerEntity.java index 378f247..7e4e582 100644 --- a/src/main/java/com/acethewildfire/acesbs/block/entity/custom/EntropicStabilizerEntity.java +++ b/src/main/java/com/acethewildfire/acesbs/block/entity/custom/EntropicStabilizerEntity.java @@ -3,6 +3,10 @@ package com.acethewildfire.acesbs.block.entity.custom; import com.acethewildfire.acesbs.block.custom.EntropicStabilizer; import com.acethewildfire.acesbs.block.entity.ImplementedInventory; import com.acethewildfire.acesbs.block.entity.ModBlockEntities; +import com.acethewildfire.acesbs.item.ModItems; +import com.acethewildfire.acesbs.recipe.EntropicStabilizerRecipe; +import com.acethewildfire.acesbs.recipe.EntropicStabilizerRecipeInput; +import com.acethewildfire.acesbs.recipe.ModRecipies; import com.acethewildfire.acesbs.screen.custom.EntropicStabilizerScreenHandler; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.block.BlockState; @@ -10,12 +14,16 @@ import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.listener.ClientPlayPacketListener; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.recipe.RecipeEntry; import net.minecraft.registry.RegistryWrapper; +import net.minecraft.screen.PropertyDelegate; import net.minecraft.screen.ScreenHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; @@ -23,15 +31,61 @@ import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + public class EntropicStabilizerEntity extends BlockEntity implements ImplementedInventory, ExtendedScreenHandlerFactory { private final DefaultedList inventory = DefaultedList.ofSize(3, ItemStack.EMPTY); private Direction facing; + private static final int INPUT_SLOT = 0; + private static final int FUEL_SLOT = 1; + private static final int OUTPUT_SLOT = 2; + + private static final int FUEL_PROGRESS = 0; + private static final int FUEL_MAX_PROGRESS = 1; + private static final int STABILIZE_PROGRESS = 2; + private static final int STABILIZE_MAX_PROGRESS = 3; + + private int fuel_progress = -1; + private int fuel_max_progress = 400; + private int stabilize_progress = 0; + private int stabilize_max_progress = 200; + + protected final PropertyDelegate propertyDelegate; + public EntropicStabilizerEntity(BlockPos pos, BlockState state) { super(ModBlockEntities.E_STABILIZER_BE, pos, state); this.facing = state.get(EntropicStabilizer.FACING); + this.propertyDelegate = new PropertyDelegate() { + @Override + public int get(int index) { + return switch (index) { + case 0 -> EntropicStabilizerEntity.this.fuel_progress; + case 1 -> EntropicStabilizerEntity.this.fuel_max_progress; + case 2 -> EntropicStabilizerEntity.this.stabilize_progress; + case 3 -> EntropicStabilizerEntity.this.stabilize_max_progress; + default -> 0; + }; + } + + @Override + public void set(int index, int value) { + switch (index) { + case 0 -> EntropicStabilizerEntity.this.fuel_progress = value; + case 1 -> EntropicStabilizerEntity.this.fuel_max_progress = value; + case 2 -> EntropicStabilizerEntity.this.stabilize_progress = value; + case 3 -> EntropicStabilizerEntity.this.stabilize_max_progress = value; + } + } + + @Override + public int size() { + return 4; + } + }; } public Direction getFacing() { @@ -52,13 +106,21 @@ public class EntropicStabilizerEntity extends BlockEntity implements Implemented super.writeNbt(nbt, registryLookup); Inventories.writeNbt(nbt, inventory, registryLookup); nbt.putInt("Facing", facing.getId()); + nbt.putInt("stabilizer.fuel_progress", fuel_progress); + nbt.putInt("stabilizer.fuel_max_progress", fuel_max_progress); + nbt.putInt("stabilizer.stabilize_progress", stabilize_progress); + nbt.putInt("stabilizer.stabilize_max_progress", stabilize_max_progress); } @Override protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { - super.readNbt(nbt, registryLookup); Inventories.readNbt(nbt, inventory, registryLookup); this.facing = Direction.byId(nbt.getInt("Facing")); + this.fuel_progress = nbt.getInt("stabilizer.fuel_progress"); + this.fuel_max_progress = nbt.getInt("stabilizer.fuel_max_progress"); + this.stabilize_progress = nbt.getInt("stabilizer.stabilize_progress"); + this.stabilize_max_progress = nbt.getInt("stabilizer.stabilize_max_progress"); + super.readNbt(nbt, registryLookup); } @Override @@ -73,12 +135,124 @@ public class EntropicStabilizerEntity extends BlockEntity implements Implemented @Override public Text getDisplayName() { - return Text.literal("Entropic Stabilizer"); + return Text.translatable("block.acesbs.entropic_stabilizer"); } @Override public @Nullable ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) { - return new EntropicStabilizerScreenHandler(syncId, playerInventory, this.pos); + return new EntropicStabilizerScreenHandler(syncId, playerInventory, this, propertyDelegate); + } + + public float getCookProgress() { + int i = this.propertyDelegate.get(STABILIZE_PROGRESS); + int j = this.propertyDelegate.get(STABILIZE_MAX_PROGRESS); + return j != 0 && i != 0 ? MathHelper.clamp((float)i / (float)j, 0.0F, 1.0F) : 0.0F; + } + + public float getFuelProgress() { + int i = this.propertyDelegate.get(FUEL_MAX_PROGRESS); + if (i == 0) { + i = 200; + } + + return MathHelper.clamp((float)this.propertyDelegate.get(FUEL_PROGRESS) / (float) i, 0.0F, 1.0F); + } + +// public boolean canInsertIntoSlot(int index) { +// return index != 1; +// } + + public void tick(World world, BlockPos pos, BlockState state) { + if(hasRecipe()) { + if (hasFuel()){ + if (this.fuel_progress == -1){ + // No fuel has been used yet + consumeFuel(); + resetFuelProgress(); + } + increaseCraftingProgress(); + markDirty(world, pos, state); + + if(hasCraftingFinished()) { + craftItem(); + resetProgress(); + } + + if(hasFuelFinished()) { + consumeFuel(); + resetFuelProgress(); + } + } + } else { + resetProgress(); + } + } + + private boolean hasFuel() { + return this.getStack(FUEL_SLOT).isOf(Items.SNOWBALL); + } + + private void resetProgress() { + this.stabilize_progress = 0; + this.stabilize_max_progress = 200; + } + + private void resetFuelProgress() { + this.fuel_progress = 0; + this.fuel_max_progress = 400; + } + + private void craftItem() { + Optional> recipe = getCurrentRecipe(); + ItemStack output = recipe.get().value().output(); + + this.removeStack(INPUT_SLOT, 1); + this.setStack(OUTPUT_SLOT, new ItemStack(output.getItem(), + this.getStack(OUTPUT_SLOT).getCount() + output.getCount())); + } + + private void consumeFuel() { + this.setStack(FUEL_SLOT, new ItemStack(this.getStack(FUEL_SLOT).getItem(), + this.getStack(FUEL_SLOT).getCount() - 1)); + } + + private boolean hasCraftingFinished() { + return this.stabilize_progress >= this.stabilize_max_progress; + } + + private boolean hasFuelFinished() { + return this.fuel_progress >= this.fuel_max_progress; + } + + private void increaseCraftingProgress() { + this.stabilize_progress++; + this.fuel_progress++; + } + + private boolean hasRecipe() { + Optional> recipe = getCurrentRecipe(); + + if (recipe.isEmpty()){ return false; } + + ItemStack output = new ItemStack(ModItems.STABLE_ENTROPY, 1); + + return canInsertAmountIntoOutputSlot(output.getCount()) && canInsertItemIntoOutputSlot(output); + } + + private Optional> getCurrentRecipe() { + return this.getWorld().getRecipeManager() + .getFirstMatch(ModRecipies.ENTROPIC_STABILIZER_TYPE, new EntropicStabilizerRecipeInput(inventory.get(INPUT_SLOT)), this.getWorld()); + } + + private boolean canInsertItemIntoOutputSlot(ItemStack output) { + return this.getStack(OUTPUT_SLOT).isEmpty() || this.getStack(OUTPUT_SLOT).getItem() == output.getItem(); + } + + private boolean canInsertAmountIntoOutputSlot(int count) { + int maxCount = this.getStack(OUTPUT_SLOT).isEmpty() ? 64 : this.getStack(OUTPUT_SLOT).getMaxCount(); + int currentCount = this.getStack(OUTPUT_SLOT).getCount(); + + return maxCount >= currentCount + count; } @Nullable @@ -91,23 +265,4 @@ public class EntropicStabilizerEntity extends BlockEntity implements Implemented public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) { return createNbt(registryLookup); } - -// public float getCookProgress() { -// int i = this.propertyDelegate.get(2); -// int j = this.propertyDelegate.get(3); -// return j != 0 && i != 0 ? MathHelper.clamp((float)i / (float)j, 0.0F, 1.0F) : 0.0F; -// } -// -// public float getFuelProgress() { -// int i = this.propertyDelegate.get(1); -// if (i == 0) { -// i = 200; -// } -// -// return MathHelper.clamp((float)this.propertyDelegate.get(0) / (float)i, 0.0F, 1.0F); -// } - - public boolean canInsertIntoSlot(int index) { - return index != 1; - } } diff --git a/src/main/java/com/acethewildfire/acesbs/item/ModItems.java b/src/main/java/com/acethewildfire/acesbs/item/ModItems.java index f04f41c..af010b1 100644 --- a/src/main/java/com/acethewildfire/acesbs/item/ModItems.java +++ b/src/main/java/com/acethewildfire/acesbs/item/ModItems.java @@ -2,7 +2,7 @@ package com.acethewildfire.acesbs.item; import com.acethewildfire.acesbs.AcesBS; import com.acethewildfire.acesbs.block.ModBlocks; -import com.acethewildfire.acesbs.block.custom.CombustibleLemon; +import com.acethewildfire.acesbs.item.custom.CombustibleLemon; import com.acethewildfire.acesbs.entity.ModEntities; import com.acethewildfire.acesbs.item.custom.HammerItem; import com.acethewildfire.acesbs.item.custom.ModArmorItem; diff --git a/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipe.java b/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipe.java new file mode 100644 index 0000000..f3a8a02 --- /dev/null +++ b/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipe.java @@ -0,0 +1,84 @@ +package com.acethewildfire.acesbs.recipe; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.RecipeType; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.world.World; + +public record EntropicStabilizerRecipe(Ingredient inputItem, ItemStack output) implements Recipe { + + @Override + public DefaultedList getIngredients() { + DefaultedList list = DefaultedList.of(); + list.add(this.inputItem); + return list; + } + + // Read JSON Files + // Turns into new EntropicStabilizerRecipe + + @Override + public boolean matches(EntropicStabilizerRecipeInput input, World world) { + if(world.isClient()) { + return false; + } + + return inputItem.test(input.getStackInSlot(0)); + } + + @Override + public ItemStack craft(EntropicStabilizerRecipeInput input, RegistryWrapper.WrapperLookup lookup) { + return output.copy(); + } + + @Override + public boolean fits(int width, int height) { + return true; + } + + @Override + public ItemStack getResult(RegistryWrapper.WrapperLookup registriesLookup) { + return output; + } + + @Override + public RecipeSerializer getSerializer() { + return ModRecipies.ENTROPIC_STABILIZER_SERIALIZER; + } + + @Override + public RecipeType getType() { + return ModRecipies.ENTROPIC_STABILIZER_TYPE; + } + + public static class Serializer implements RecipeSerializer { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("ingredient").forGetter(EntropicStabilizerRecipe::inputItem), + ItemStack.CODEC.fieldOf("result").forGetter(EntropicStabilizerRecipe::output) + ).apply(inst, EntropicStabilizerRecipe::new)); + + public static final PacketCodec STREAM_CODEC = + PacketCodec.tuple( + Ingredient.PACKET_CODEC, EntropicStabilizerRecipe::inputItem, + ItemStack.PACKET_CODEC, EntropicStabilizerRecipe::output, + EntropicStabilizerRecipe::new); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public PacketCodec packetCodec() { + return STREAM_CODEC; + } + } +} diff --git a/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipeInput.java b/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipeInput.java new file mode 100644 index 0000000..61864a4 --- /dev/null +++ b/src/main/java/com/acethewildfire/acesbs/recipe/EntropicStabilizerRecipeInput.java @@ -0,0 +1,16 @@ +package com.acethewildfire.acesbs.recipe; + +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.input.RecipeInput; + +public record EntropicStabilizerRecipeInput(ItemStack input) implements RecipeInput { + @Override + public ItemStack getStackInSlot(int slot) { + return input; + } + + @Override + public int getSize() { + return 2; + } +} diff --git a/src/main/java/com/acethewildfire/acesbs/recipe/ModRecipies.java b/src/main/java/com/acethewildfire/acesbs/recipe/ModRecipies.java new file mode 100644 index 0000000..47f5301 --- /dev/null +++ b/src/main/java/com/acethewildfire/acesbs/recipe/ModRecipies.java @@ -0,0 +1,27 @@ +package com.acethewildfire.acesbs.recipe; + +import com.acethewildfire.acesbs.AcesBS; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.RecipeType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +public class ModRecipies { + public static final RecipeSerializer ENTROPIC_STABILIZER_SERIALIZER = + Registry.register(Registries.RECIPE_SERIALIZER, Identifier.of(AcesBS.MOD_ID, "entropic_stabilizer"), + new EntropicStabilizerRecipe.Serializer()); + + public static final RecipeType ENTROPIC_STABILIZER_TYPE = + Registry.register(Registries.RECIPE_TYPE, Identifier.of(AcesBS.MOD_ID, "entropic_stabilizer"), + new RecipeType() { + @Override + public String toString() { + return "entropic_stabilizer"; + } + }); + + public static void registerRecipes() { + AcesBS.LOGGER.info("Registering Custom Recipes for " + AcesBS.MOD_ID); + } +} diff --git a/src/main/java/com/acethewildfire/acesbs/screen/custom/EntropicStabilizerScreen.java b/src/main/java/com/acethewildfire/acesbs/screen/custom/EntropicStabilizerScreen.java index ab45c22..d86f439 100644 --- a/src/main/java/com/acethewildfire/acesbs/screen/custom/EntropicStabilizerScreen.java +++ b/src/main/java/com/acethewildfire/acesbs/screen/custom/EntropicStabilizerScreen.java @@ -13,6 +13,10 @@ public class EntropicStabilizerScreen extends HandledScreen 0; + } + + public boolean isCooking() { + return propertyDelegate.get(0) > 0; + } + + public int getScaledArrowProgress() { + int progress = this.propertyDelegate.get(2); + int maxProgress = this.propertyDelegate.get(3); // Max Progress + int arrowPixelSize = 24; // This is the width in pixels of your arrow + + return maxProgress != 0 && progress != 0 ? progress * arrowPixelSize / maxProgress : 0; + } + + public int getScaledStabilizeProgress() { + int progress = this.propertyDelegate.get(0); + int maxProgress = this.propertyDelegate.get(1); // Max Progress + int stabilizePixelSize = 16; // This is the width in pixels of your bar + + return maxProgress != 0 && progress != 0 ? progress * stabilizePixelSize / maxProgress : 0; } @Override diff --git a/src/main/resources/assets/acesbs/textures/gui/arrow_progress.png b/src/main/resources/assets/acesbs/textures/gui/arrow_progress.png new file mode 100644 index 0000000..a745f74 Binary files /dev/null and b/src/main/resources/assets/acesbs/textures/gui/arrow_progress.png differ diff --git a/src/main/resources/assets/acesbs/textures/gui/stabilize_progress.png b/src/main/resources/assets/acesbs/textures/gui/stabilize_progress.png new file mode 100644 index 0000000..d37a2ba Binary files /dev/null and b/src/main/resources/assets/acesbs/textures/gui/stabilize_progress.png differ diff --git a/src/main/resources/data/acesbs/recipe/stable_endtropy_from_entropic_stabilizer.json b/src/main/resources/data/acesbs/recipe/stable_endtropy_from_entropic_stabilizer.json new file mode 100644 index 0000000..a242032 --- /dev/null +++ b/src/main/resources/data/acesbs/recipe/stable_endtropy_from_entropic_stabilizer.json @@ -0,0 +1,10 @@ +{ + "type": "acesbs:entropic_stabilizer", + "ingredient": { + "item": "acesbs:raw_endtropy" + }, + "result": { + "count": 1, + "id": "acesbs:stable_endtropy" + } +} \ No newline at end of file diff --git a/src/main/resources/data/acesbs/recipe/stable_entropy_from_entropic_stabilizer.json b/src/main/resources/data/acesbs/recipe/stable_entropy_from_entropic_stabilizer.json new file mode 100644 index 0000000..62fae14 --- /dev/null +++ b/src/main/resources/data/acesbs/recipe/stable_entropy_from_entropic_stabilizer.json @@ -0,0 +1,10 @@ +{ + "type": "acesbs:entropic_stabilizer", + "ingredient": { + "item": "acesbs:raw_entropy" + }, + "result": { + "count": 1, + "id": "acesbs:stable_entropy" + } +} \ No newline at end of file