Skip to content

Commit

Permalink
simple blockentity system
Browse files Browse the repository at this point in the history
  • Loading branch information
MEGATREX4 committed Jul 3, 2024
1 parent 485cb0a commit 3a43ead
Show file tree
Hide file tree
Showing 23 changed files with 775 additions and 13 deletions.
1 change: 1 addition & 0 deletions projectfiles/brewing_keg.bbmodel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"meta":{"format_version":"4.10","model_format":"java_block","box_uv":false},"name":"brewing_keg","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":32,"height":32},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,0,1],"to":[12,8,15],"autouv":0,"color":0,"origin":[1,0,1],"faces":{"north":{"uv":[0,16,8,24],"texture":0},"east":{"uv":[0,0,14,8],"texture":0},"south":{"uv":[22,0,30,8],"texture":0},"west":{"uv":[0,8,14,16],"texture":0},"up":{"uv":[22,14,14,0],"texture":0},"down":{"uv":[22,14,14,28],"texture":0}},"type":"cube","uuid":"ace94742-e271-d0f1-c39a-b273e03e79ba"}],"outliner":["ace94742-e271-d0f1-c39a-b273e03e79ba"],"textures":[{"path":"D:\\Users\\EUGENE\\Desktop\\brewing_keg.png","name":"brewing_keg.png","folder":"","namespace":"ukrainian_delight","id":"0","width":32,"height":32,"uv_width":32,"uv_height":32,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"9b067532-71e6-c92f-d4ce-2481db24007f","relative_path":"brewing_keg.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAPNJREFUWEdjdH7R+5+BDFD4JgSvLhfOiXjlOZT7GEEKGEEOsBAXI8kJJ16+YgA5wEJFBqu+E3eeMIAcwC6tjlX+59ObDKMOGA2BwRUCJGUBqGJicgE+c+Eh8KWtjaxy4IBfNN5s6KMjD87nhAAjyAHcinKE1KHIf73/iGHUAaMhAAoBfIDmiTD+9ju8Dlg7v4f4XEBSFoAqBjlAWlwCq9anL18wEO2A6D1f8JYDS114sPokOLHkP9UcoCDBjdUnD158ZRh1wGgIjIwQwFcO0DwEyCmEQHqoVg6MOoCSEMCnl+i6gFwHUEsfUVUmtSzDZs6oAwAxWzww+MGyEgAAAABJRU5ErkJggg=="}]}
Binary file added projectfiles/interface.psd
Binary file not shown.
Binary file added projectfiles/interface2.psd
Binary file not shown.
15 changes: 11 additions & 4 deletions src/main/java/com/megatrex4/ukrainian_dlight/UkrainianDelight.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.megatrex4.ukrainian_dlight.block.DrinkBottleBlock;
import com.megatrex4.ukrainian_dlight.block.FoodJarBlocks;
import com.megatrex4.ukrainian_dlight.block.ModBlock;
import com.megatrex4.ukrainian_dlight.block.ModBlocks;
import com.megatrex4.ukrainian_dlight.block.entity.ModBlockEntities;
import com.megatrex4.ukrainian_dlight.item.ModItemGroups;
import com.megatrex4.ukrainian_dlight.item.ModItems;
import com.megatrex4.ukrainian_dlight.item.ToolTipHelper;
import com.megatrex4.ukrainian_dlight.util.Config;
import com.megatrex4.ukrainian_dlight.screen.ModScreenHandlers;
import com.megatrex4.ukrainian_dlight.screen.ModScreens;
import net.fabricmc.api.ModInitializer;

import net.minecraft.entity.damage.DamageType;
Expand All @@ -15,7 +17,6 @@
import net.minecraft.util.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects;

public class UkrainianDelight implements ModInitializer {
public static final String MOD_ID = "ukrainian_delight";
Expand All @@ -33,11 +34,17 @@ public void onInitialize() {

FoodJarBlocks.registerFoodBlocks();
DrinkBottleBlock.registerDrinkBlock();
ModBlock.registerModBlocks();
ModBlocks.registerModBlocks();
ModItems.registerModItems();
ModItemGroups.registerItemGroups();
ToolTipHelper.registerTooltip();
ModBlockEntities.registerBLockEntities();
ModScreenHandlers.registerModScreenHandlers();

ModScreens.registerScreens();

LOGGER.info("Hello Fabric world it's " + MOD_ID + "!");
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.megatrex4.ukrainian_dlight;

import com.megatrex4.ukrainian_dlight.screen.BrewingKegScreen;
import com.megatrex4.ukrainian_dlight.screen.ModScreenHandlers;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.client.render.RenderLayer;

public class UkrainianDeligthClient implements ClientModInitializer {

@Override
public void onInitializeClient() {
HandledScreens.register(ModScreenHandlers.BREWING_KEG_SCREEN_HANDLER, BrewingKegScreen::new);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.megatrex4.ukrainian_dlight.block;

import com.megatrex4.ukrainian_dlight.UkrainianDelight;
import com.megatrex4.ukrainian_dlight.block.custom.CustomSaltBlock;
import com.megatrex4.ukrainian_dlight.block.custom.BrewingKegBlock;
import com.megatrex4.ukrainian_dlight.block.custom.SaltBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
Expand All @@ -12,17 +13,20 @@
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;

public class ModBlock {
public class ModBlocks {

public static final Block SALT_BLOCK = registerBlock("salt_block",
new CustomSaltBlock(Block.Settings.copy(Blocks.STONE).sounds(BlockSoundGroup.STONE)));
new SaltBlock(Block.Settings.copy(Blocks.STONE).sounds(BlockSoundGroup.STONE)));

public static final Block SALT_BAG = registerBlock("salt_bag",
new Block(FabricBlockSettings.copyOf(Blocks.WHITE_WOOL).sounds(BlockSoundGroup.WOOL)));

public static final Block CUCUMBER_CRATE = registerBlock("cucumber_crate",
new Block(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).sounds(BlockSoundGroup.WOOD)));

public static final Block BREWING_KEG = registerBlock("brewing_keg",
new BrewingKegBlock(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).sounds(BlockSoundGroup.WOOD).nonOpaque()));

private static Block registerBlock(String name, Block block){
registerBlockItem(name, block);
return Registry.register(Registries.BLOCK, new Identifier(UkrainianDelight.MOD_ID, name), block);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
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.*;
import net.minecraft.block.BlockWithEntity;
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.screen.NamedScreenHandlerFactory;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class BrewingKegBlock extends BlockWithEntity implements BlockEntityProvider {
private static final VoxelShape SHAPE = Block.createCuboidShape(0, 0, 0, 16, 12, 16);

public BrewingKegBlock (Settings settings) {
super(settings);
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
}

@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new BrewingKegBlockEntity(pos, state);
}

@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof BrewingKegBlockEntity) {
ItemScatterer.spawn(world, pos, (BrewingKegBlockEntity)blockEntity);
world.updateComparators(pos,this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}
}

@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!world.isClient) {
NamedScreenHandlerFactory screenHandlerFactory = ((BrewingKegBlockEntity) world.getBlockEntity(pos));

if (screenHandlerFactory != null) {
player.openHandledScreen(screenHandlerFactory);
}
}

return ActionResult.SUCCESS;
}

@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return checkType(type, ModBlockEntities.BREWING_KEG_BLOCK_ENTITY,
(world1, pos, state1, blockEntity) -> blockEntity.tick(world1, pos, state1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import net.minecraft.util.math.random.Random;
import net.minecraft.world.World;

public class CustomSaltBlock extends Block {
public class SaltBlock extends Block {
private static final int SCHEDULED_TICK_DELAY = 20;

public CustomSaltBlock(Settings settings) {
public SaltBlock(Settings settings) {
super(settings);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
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.screen.BrewingKegScreenHandler;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
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.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
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.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

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

//adds 6 input ingredients slot
public static final int INGREDIENT_SLOT_1 = 0;
public static final int INGREDIENT_SLOT_2 = 1;
public static final int INGREDIENT_SLOT_3 = 2;
public static final int INGREDIENT_SLOT_4 = 3;
public static final int INGREDIENT_SLOT_5 = 4;
public static final int INGREDIENT_SLOT_6 = 5;
//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;
//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;

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){
case 0 -> BrewingKegBlockEntity.this.progress;
case 1 -> BrewingKegBlockEntity.this.maxProgress;
default -> 0;
};
}

@Override
public void set(int index, int value) {
switch (index){
case 0 -> BrewingKegBlockEntity.this.progress = value;
case 1 -> BrewingKegBlockEntity.this.maxProgress = value;
}
}

@Override
public int size() {
return 2;
}
};
}

@Override
public DefaultedList<ItemStack> getItems() {
return inventory;
}

@Override
protected void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
Inventories.writeNbt(nbt, inventory);
nbt.putInt("brewing_keg.progress", progress);
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
Inventories.readNbt(nbt, inventory);
progress = nbt.getInt("brewing_keg.progress");
}

@Override
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
buf.writeBlockPos(this.pos);
}

@Override
public Text getDisplayName() {
return Text.translatable("gui.ukrainian_delight.brewing_keg");
}

@Nullable
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new BrewingKegScreenHandler(syncId, playerInventory, this, propertyDelegate);
}

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

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

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

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;
}

private void increaseCraftProgress() {
progress++;
}

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());
}

private boolean canInstertItemIntoOutputSlot(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 isOutoutSlotEmptyOrReceivable() {
return this.getStack(OUTPUT_SLOT).isEmpty() || this.getStack(OUTPUT_SLOT).getCount() < this.getStack(OUTPUT_SLOT).getMaxCount();
}
}
Loading

0 comments on commit 3a43ead

Please sign in to comment.