blockstacker without menu
Some checks failed
build / build (21) (push) Has been cancelled

This commit is contained in:
Jottyfan 2024-11-30 18:44:28 +01:00
parent f59ceb8883
commit 83267ea506
42 changed files with 986 additions and 53 deletions

View File

@ -9,7 +9,7 @@ yarn_mappings=1.21.3+build.2
loader_version=0.16.9 loader_version=0.16.9
# Mod Properties # Mod Properties
mod_version=1.21.3.0 mod_version=1.21.3.1
maven_group=de.jottyfan.quickiemod maven_group=de.jottyfan.quickiemod
archives_base_name=quickiemod archives_base_name=quickiemod

View File

@ -6,7 +6,6 @@ import java.util.Map;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import de.jottyfan.quickiemod.blockentity.DrillBlockEntity; import de.jottyfan.quickiemod.blockentity.DrillBlockEntity;
import de.jottyfan.quickiemod.blockentity.EnumDrillDirection;
import de.jottyfan.quickiemod.item.ModItems; import de.jottyfan.quickiemod.item.ModItems;
import net.minecraft.block.AbstractBlock; import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -24,12 +23,14 @@ import net.minecraft.item.Items;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.state.StateManager.Builder; import net.minecraft.state.StateManager.Builder;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.IntProperty; import net.minecraft.state.property.IntProperty;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
/** /**
@ -40,11 +41,11 @@ import net.minecraft.world.World;
public class BlockDrill extends FallingBlock implements BlockEntityProvider { public class BlockDrill extends FallingBlock implements BlockEntityProvider {
private static final Integer MAX_FUEL = 255; private static final Integer MAX_FUEL = 255;
public static final IntProperty FUEL = IntProperty.of("fuel", 0, MAX_FUEL); public static final IntProperty FUEL = IntProperty.of("fuel", 0, MAX_FUEL);
public static final IntProperty DIRECTION = IntProperty.of("direction", 0, 4); public static final EnumProperty<Direction> DIRECTION = EnumProperty.of("direction", Direction.class, Direction.values());
public BlockDrill(Identifier identifier, EnumDrillDirection direction) { public BlockDrill(Identifier identifier, Direction direction) {
super(AbstractBlock.Settings.create().hardness(2.5f).registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier))); super(AbstractBlock.Settings.create().hardness(2.5f).registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier)));
setDefaultState(getDefaultState().with(FUEL, 0).with(DIRECTION, direction.get())); setDefaultState(getDefaultState().with(FUEL, 0).with(DIRECTION, direction));
} }
@Override @Override

View File

@ -0,0 +1,117 @@
package de.jottyfan.quickiemod.block;
import com.mojang.serialization.MapCodec;
import de.jottyfan.quickiemod.blockentity.BlockStackerEntity;
import de.jottyfan.quickiemod.blockentity.ModBlockentity;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
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.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
/**
*
* @author jotty
*
*/
public class BlockStacker extends BlockWithEntity implements BlockEntityProvider {
private final Direction source;
private final Direction dest;
public BlockStacker(Identifier identifier, Direction source, Direction dest) {
super(AbstractBlock.Settings.create().hardness(2.5f).registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier)));
this.source = source;
this.dest = dest;
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
/**
* define the source offset
*
* @return the direction of the source offset (1 block beside)
*/
public Direction getSourceOffset() {
return source;
}
/**
* define the dest offset
*
* @return the direction of the dest offset (1 block beside)
*/
public Direction getDestOffset() {
return dest;
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new BlockStackerEntity(pos, state);
}
@Override
protected MapCodec<? extends BlockWithEntity> getCodec() {
// TODO Auto-generated method stub
return null;
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state,
BlockEntityType<T> type) {
return validateTicker(type, ModBlockentity.BLOCKSTACKER_BLOCKENTITY,
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
}
@Override
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
// if (!world.isClient) {
// NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
// if (screenHandlerFactory != null) {
// player.openHandledScreen(screenHandlerFactory);
// }
// }
return ActionResult.SUCCESS;
}
@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 BlockStackerEntity) {
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
// update comparators
world.updateComparators(pos, this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}
}
@Override
public boolean hasComparatorOutput(BlockState state) {
return true;
}
@Override
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
}
}

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.jottyfan.quickiemod.Quickiemod; import de.jottyfan.quickiemod.Quickiemod;
import de.jottyfan.quickiemod.blockentity.EnumDrillDirection;
import de.jottyfan.quickiemod.identifier.ModIdentifiers; import de.jottyfan.quickiemod.identifier.ModIdentifiers;
import de.jottyfan.quickiemod.item.ModItems; import de.jottyfan.quickiemod.item.ModItems;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -17,6 +16,7 @@ import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
/** /**
* *
@ -62,15 +62,27 @@ public class ModBlocks {
public static final Block BLOCK_CANOLAPLANT = registerBlock(ModIdentifiers.BLOCK_CANOLAPLANT, public static final Block BLOCK_CANOLAPLANT = registerBlock(ModIdentifiers.BLOCK_CANOLAPLANT,
new BlockPlant(ModIdentifiers.BLOCK_CANOLAPLANT, ModItems.ITEM_CANOLASEED, ModItems.ITEM_CANOLA), false); new BlockPlant(ModIdentifiers.BLOCK_CANOLAPLANT, ModItems.ITEM_CANOLASEED, ModItems.ITEM_CANOLA), false);
public static final Block BLOCK_DRILL_DOWN = registerBlock(ModIdentifiers.BLOCK_DRILLDOWN, public static final Block BLOCK_DRILL_DOWN = registerBlock(ModIdentifiers.BLOCK_DRILLDOWN,
new BlockDrill(ModIdentifiers.BLOCK_DRILLDOWN, EnumDrillDirection.DOWN)); new BlockDrill(ModIdentifiers.BLOCK_DRILLDOWN, Direction.DOWN));
public static final Block BLOCK_DRILL_EAST = registerBlock(ModIdentifiers.BLOCK_DRILLEAST, public static final Block BLOCK_DRILL_EAST = registerBlock(ModIdentifiers.BLOCK_DRILLEAST,
new BlockDrill(ModIdentifiers.BLOCK_DRILLEAST, EnumDrillDirection.EAST)); new BlockDrill(ModIdentifiers.BLOCK_DRILLEAST, Direction.EAST));
public static final Block BLOCK_DRILL_SOUTH = registerBlock(ModIdentifiers.BLOCK_DRILLSOUTH, public static final Block BLOCK_DRILL_SOUTH = registerBlock(ModIdentifiers.BLOCK_DRILLSOUTH,
new BlockDrill(ModIdentifiers.BLOCK_DRILLSOUTH, EnumDrillDirection.SOUTH)); new BlockDrill(ModIdentifiers.BLOCK_DRILLSOUTH, Direction.SOUTH));
public static final Block BLOCK_DRILL_WEST = registerBlock(ModIdentifiers.BLOCK_DRILLWEST, public static final Block BLOCK_DRILL_WEST = registerBlock(ModIdentifiers.BLOCK_DRILLWEST,
new BlockDrill(ModIdentifiers.BLOCK_DRILLWEST, EnumDrillDirection.WEST)); new BlockDrill(ModIdentifiers.BLOCK_DRILLWEST, Direction.WEST));
public static final Block BLOCK_DRILL_NORTH = registerBlock(ModIdentifiers.BLOCK_DRILLNORTH, public static final Block BLOCK_DRILL_NORTH = registerBlock(ModIdentifiers.BLOCK_DRILLNORTH,
new BlockDrill(ModIdentifiers.BLOCK_DRILLNORTH, EnumDrillDirection.NORTH)); new BlockDrill(ModIdentifiers.BLOCK_DRILLNORTH, Direction.NORTH));
public static final Block BLOCK_STACKER_DOWN = registerBlock(ModIdentifiers.BLOCK_STACKERDOWN,
new BlockStacker(ModIdentifiers.BLOCK_STACKERDOWN, Direction.UP, Direction.DOWN));
public static final Block BLOCK_STACKER_EAST = registerBlock(ModIdentifiers.BLOCK_STACKEREAST,
new BlockStacker(ModIdentifiers.BLOCK_STACKEREAST, Direction.WEST, Direction.EAST));
public static final Block BLOCK_STACKER_SOUTH = registerBlock(ModIdentifiers.BLOCK_STACKERSOUTH,
new BlockStacker(ModIdentifiers.BLOCK_STACKERSOUTH, Direction.NORTH, Direction.SOUTH));
public static final Block BLOCK_STACKER_WEST = registerBlock(ModIdentifiers.BLOCK_STACKERWEST,
new BlockStacker(ModIdentifiers.BLOCK_STACKERWEST, Direction.EAST, Direction.WEST));
public static final Block BLOCK_STACKER_NORTH = registerBlock(ModIdentifiers.BLOCK_STACKERNORTH,
new BlockStacker(ModIdentifiers.BLOCK_STACKERNORTH, Direction.SOUTH, Direction.NORTH));
public static final Block BLOCK_STACKER_UP = registerBlock(ModIdentifiers.BLOCK_STACKERUP,
new BlockStacker(ModIdentifiers.BLOCK_STACKERUP, Direction.DOWN, Direction.UP));
private static final Block registerBlock(Identifier identifier, Block block) { private static final Block registerBlock(Identifier identifier, Block block) {
return registerBlock(identifier, block, true); return registerBlock(identifier, block, true);
@ -109,6 +121,12 @@ public class ModBlocks {
blocks.add(BLOCK_DRILL_SOUTH); blocks.add(BLOCK_DRILL_SOUTH);
blocks.add(BLOCK_DRILL_WEST); blocks.add(BLOCK_DRILL_WEST);
blocks.add(BLOCK_DRILL_NORTH); blocks.add(BLOCK_DRILL_NORTH);
blocks.add(BLOCK_STACKER_DOWN);
blocks.add(BLOCK_STACKER_EAST);
blocks.add(BLOCK_STACKER_SOUTH);
blocks.add(BLOCK_STACKER_WEST);
blocks.add(BLOCK_STACKER_NORTH);
blocks.add(BLOCK_STACKER_UP);
return blocks; return blocks;
} }
} }

View File

@ -0,0 +1,261 @@
package de.jottyfan.quickiemod.blockentity;
import java.util.ArrayList;
import java.util.List;
import de.jottyfan.quickiemod.Quickiemod;
import de.jottyfan.quickiemod.block.BlockStacker;
import de.jottyfan.quickiemod.container.BlockStackerScreenHandler;
import de.jottyfan.quickiemod.container.ImplementedInventory;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.LootableContainerBlockEntity;
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.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
*
* @author jotty
*
*/
public class BlockStackerEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory {
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(BlockStackerScreenHandler.SLOTSIZE, ItemStack.EMPTY);
public BlockStackerEntity(BlockPos blockPos, BlockState blockState) {
super(ModBlockentity.BLOCKSTACKER_BLOCKENTITY, blockPos, blockState);
}
@Override
public DefaultedList<ItemStack> getItems() {
return inventory;
}
public List<ItemStack> getWhiteList() {
int counter = 0;
List<ItemStack> list = new ArrayList<>();
for (ItemStack stack : inventory) {
counter++;
if (counter < 10) { // first 9 items are whitelist items
list.add(stack);
}
}
return list;
}
public List<ItemStack> getBlackList() {
int counter = 0;
List<ItemStack> list = new ArrayList<>();
for (ItemStack stack : inventory) {
counter++;
if (counter > 9) { // second 9 items are blacklist items
list.add(stack);
}
}
return list;
}
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new BlockStackerScreenHandler(syncId, playerInventory, this);
}
@Override
public Text getDisplayName() {
return Text.translatable(getCachedState().getBlock().getTranslationKey());
}
@Override
protected void readNbt(NbtCompound nbt, WrapperLookup registryLookup) {
super.readNbt(nbt, registryLookup);
Inventories.readNbt(nbt, inventory, registryLookup);
}
@Override
protected void writeNbt(NbtCompound nbt, WrapperLookup registryLookup) {
Inventories.writeNbt(nbt, inventory, registryLookup);
super.writeNbt(nbt, registryLookup);
}
/**
* if whitelist, return true if current == pattern; return false otherwise
*
* @param current the current item stack
* @param pattern the item stack to compare with
* @param whitelist if true, filter only current == pattern, if false, filter
* all but that
* @return true or false
*/
public static final Boolean filter(ItemStack current, ItemStack pattern, Boolean whitelist) {
Boolean matches = pattern.getItem().equals(current.getItem());
return whitelist ? matches : !matches;
}
public static void tick(World world, BlockPos pos, BlockState state, BlockStackerEntity entity) {
if (!world.isClient) {
pos.down();
BlockStacker block = (BlockStacker) state.getBlock();
BlockEntity source = world.getBlockEntity(pos.offset(block.getSourceOffset()));
BlockEntity dest = world.getBlockEntity(pos.offset(block.getDestOffset()));
Boolean sourceIsLootable = source instanceof LootableContainerBlockEntity;
Boolean destIsLootable = dest instanceof LootableContainerBlockEntity;
if (sourceIsLootable && destIsLootable) {
LootableContainerBlockEntity lootableSource = (LootableContainerBlockEntity) source;
LootableContainerBlockEntity lootableDest = (LootableContainerBlockEntity) dest;
transferOneStack(lootableSource, lootableDest, entity.getWhiteList(), entity.getBlackList());
}
}
}
private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest, List<ItemStack> whiteList, List<ItemStack> blackList) {
// whitelist behaviour
List<Item> checked = new ArrayList<>();
// this way, we block whitelist items that are in the blacklist
for (ItemStack stack : blackList) {
if (stack != null && !stack.isEmpty()) {
checked.add(stack.getItem());
}
}
Boolean found = false;
if (hasItems(whiteList)) {
Item matchItem = findNextItem(whiteList, checked);
while(!found && matchItem != null) {
checked.add(matchItem);
List<Item> matchItems = new ArrayList<>();
matchItems.add(matchItem);
found = transferOneStack(source, dest, matchItems, true);
matchItem = findNextItem(whiteList, checked);
}
} else {
// transport all but the items of the blacklist
found = transferOneStack(source, dest, checked, false);
}
return found;
}
private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest,
List<Item> ignoreItems, Boolean whitelist) {
Boolean result = false;
Integer sourceSlot = findItemStackPos(source, ignoreItems, whitelist);
if (sourceSlot != null && !Items.AIR.equals(source.getStack(sourceSlot).getItem())) {
ItemStack sourceStack = source.getStack(sourceSlot);
Integer destSlot = findItemStackPos(dest, sourceStack);
if (destSlot != null) {
Integer occupied = dest.getStack(destSlot).getCount();
Integer free = dest.getStack(destSlot).getMaxCount() - occupied;
Integer candidates = source.getStack(sourceSlot).getCount();
Integer travellers = candidates > free ? free : candidates;
if (travellers > 0) {
Quickiemod.LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates,
source.getStack(sourceSlot).getItem().toString(), sourceSlot, destSlot, occupied);
source.getStack(sourceSlot).decrement(travellers);
if (source.getStack(sourceSlot).getCount() < 1) {
source.removeStack(sourceSlot); // make empty slots really empty
}
dest.getStack(destSlot).increment(travellers);
result = true;
}
} else {
Integer destFreeSlot = findItemStackPos(dest, true);
if (destFreeSlot != null) {
Quickiemod.LOGGER.debug("transfer all of {} from slot {} to slot {}", source.getStack(sourceSlot).getItem().toString(),
sourceSlot, destSlot);
dest.setStack(destFreeSlot, source.removeStack(sourceSlot));
result = true;
}
}
}
return result;
}
private static final Boolean hasItems(List<ItemStack> list) {
Boolean result = false;
for (ItemStack stack : list) {
result = result || (stack != null && !stack.isEmpty() && stack.getCount() > 0);
}
return result;
}
private static final Item findNextItem(List<ItemStack> inventory, List<Item> exclude) {
for (ItemStack stack : inventory) {
if (!stack.isEmpty()) {
Item item = stack.getItem();
if (!exclude.contains(item)) {
return item;
}
}
}
return null;
}
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, ItemStack sourceStack) {
Integer counter = lcbe.size();
while (counter > 0) {
counter--;
ItemStack stack = lcbe.getStack(counter);
if (sourceStack.getItem().equals(stack.getItem())) {
if (stack.getCount() < stack.getMaxCount()) {
return counter;
}
}
}
return null;
}
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, Boolean empty) {
Integer counter = lcbe.size();
while (counter > 0) {
counter--;
ItemStack stack = lcbe.getStack(counter);
if (empty.equals(ItemStack.EMPTY.equals(stack))) {
return counter;
}
}
return null;
}
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, List<Item> filterItems, Boolean whitelist) {
if (whitelist == null) {
whitelist = true;
Quickiemod.LOGGER.error("whitelist is null");
}
if (filterItems == null || filterItems.size() < 1) {
if (whitelist) {
return null;
} else {
return findItemStackPos(lcbe, false);
}
} else {
Integer counter = lcbe.size();
while (counter > 0) {
counter--;
ItemStack stack = lcbe.getStack(counter);
Boolean found = whitelist ? filterItems.contains(stack.getItem()) : !filterItems.contains(stack.getItem());
if (found) {
return counter;
}
}
return null;
}
}
@Override
public int size() {
return inventory.size();
}
}

View File

@ -8,6 +8,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
/** /**
@ -29,17 +30,17 @@ public class DrillBlockEntity extends BlockEntity {
public static void tick(World world, BlockPos pos, BlockState state, BlockEntity be) { public static void tick(World world, BlockPos pos, BlockState state, BlockEntity be) {
if (be instanceof DrillBlockEntity dbe) { if (be instanceof DrillBlockEntity dbe) {
Integer dir = state.get(BlockDrill.DIRECTION); Direction dir = state.get(BlockDrill.DIRECTION);
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
if (EnumDrillDirection.DOWN.get().equals(dir)) { if (Direction.DOWN.equals(dir)) {
list = downFrom(pos); list = downFrom(pos);
} else if (EnumDrillDirection.EAST.get().equals(dir)) { } else if (Direction.EAST.equals(dir)) {
list = directedFrom(pos.east()); list = directedFrom(pos.east());
} else if (EnumDrillDirection.SOUTH.get().equals(dir)) { } else if (Direction.SOUTH.equals(dir)) {
list = directedFrom(pos.south()); list = directedFrom(pos.south());
} else if (EnumDrillDirection.WEST.get().equals(dir)) { } else if (Direction.WEST.equals(dir)) {
list = directedFrom(pos.west()); list = directedFrom(pos.west());
} else if (EnumDrillDirection.NORTH.get().equals(dir)) { } else if (Direction.NORTH.equals(dir)) {
list = directedFrom(pos.north()); list = directedFrom(pos.north());
} }
DrillBlockEntity.tick(world, pos, state, dbe, MAXDRILLSTEP, list); DrillBlockEntity.tick(world, pos, state, dbe, MAXDRILLSTEP, list);

View File

@ -1,36 +0,0 @@
package de.jottyfan.quickiemod.blockentity;
/**
*
* @author jotty
*
*/
public enum EnumDrillDirection {
DOWN(0), EAST(1), SOUTH(2), WEST(3), NORTH(4);
private final Integer value;
private EnumDrillDirection(Integer value) {
this.value = value;
}
@Override
public String toString() {
return String.format("%s: %d", EnumDrillDirection.lookupValue(value), value);
}
public static final String lookupValue(Integer value) {
return switch (value) {
case 0 -> "down";
case 1 -> "east";
case 2 -> "south";
case 3 -> "west";
case 4 -> "north";
default -> "not supported";
};
}
public Integer get() {
return value;
}
}

View File

@ -20,6 +20,11 @@ public class ModBlockentity {
Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_DRILL, Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_DRILL,
FabricBlockEntityTypeBuilder.create(DrillBlockEntity::new, ModBlocks.BLOCK_DRILL_DOWN, ModBlocks.BLOCK_DRILL_EAST, FabricBlockEntityTypeBuilder.create(DrillBlockEntity::new, ModBlocks.BLOCK_DRILL_DOWN, ModBlocks.BLOCK_DRILL_EAST,
ModBlocks.BLOCK_DRILL_SOUTH, ModBlocks.BLOCK_DRILL_WEST, ModBlocks.BLOCK_DRILL_NORTH).build()); ModBlocks.BLOCK_DRILL_SOUTH, ModBlocks.BLOCK_DRILL_WEST, ModBlocks.BLOCK_DRILL_NORTH).build());
public static final BlockEntityType<BlockStackerEntity> BLOCKSTACKER_BLOCKENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_BLOCKSTACKER,
FabricBlockEntityTypeBuilder.create(BlockStackerEntity::new, ModBlocks.BLOCK_STACKER_DOWN,
ModBlocks.BLOCK_STACKER_EAST, ModBlocks.BLOCK_STACKER_SOUTH, ModBlocks.BLOCK_STACKER_WEST,
ModBlocks.BLOCK_STACKER_NORTH, ModBlocks.BLOCK_STACKER_UP).build());
public static final void registerModBlockentities() { public static final void registerModBlockentities() {
}; };

View File

@ -0,0 +1,30 @@
package de.jottyfan.quickiemod.container;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.sound.SoundEvents;
/**
*
* @author jotty
*
*/
public class BlockStackerInventory extends SimpleInventory {
public BlockStackerInventory(Integer slotsize) {
super(slotsize);
}
@Override
public void onOpen(PlayerEntity player) {
super.onOpen(player);
player.playSound(SoundEvents.BLOCK_CHEST_OPEN, 1f, 1f);
}
@Override
public void onClose(PlayerEntity player) {
super.onClose(player);
player.playSound(SoundEvents.BLOCK_CHEST_CLOSE, 1f, 1f);
}
}

View File

@ -0,0 +1,44 @@
package de.jottyfan.quickiemod.container;
import de.jottyfan.quickiemod.Quickiemod;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
/**
*
* @author jotty
*
*/
@Environment(EnvType.CLIENT)
public class BlockStackerScreen extends HandledScreen<BlockStackerScreenHandler>
implements ScreenHandlerProvider<BlockStackerScreenHandler> {
private final static Identifier TEXTURE = Identifier.of(Quickiemod.MOD_ID, "textures/gui/blockstacker.png");
private final Integer containerHeight = 222;
private final Integer containerWidth = 176;
public BlockStackerScreen(BlockStackerScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}
@Override
public void render(DrawContext drawContext, int mouseX, int mouseY, float partialTicks) {
this.renderInGameBackground(drawContext);
super.render(drawContext, mouseX, mouseY, partialTicks);
this.drawMouseoverTooltip(drawContext, mouseX, mouseY);
}
@Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
// context.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
int guiX = (this.width - this.containerWidth) / 2;
int guiY = (this.height - this.containerHeight) / 2;
super.renderInGameBackground(context);
// context.drawTexture(TEXTURE, guiX, guiY, 0f, 0f, containerWidth, containerHeight, 0, 0);
}
}

View File

@ -0,0 +1,97 @@
package de.jottyfan.quickiemod.container;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
/**
*
* @author jotty
*
*/
public class BlockStackerScreenHandler extends ScreenHandler {
public static final Integer SLOTSIZE = 18;
private final Inventory inventory;
/**
* client constructor
*
* @param syncId
* @param playerInventory
*/
public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory) {
this(syncId, playerInventory, new BlockStackerInventory(SLOTSIZE));
}
/**
* server constructor
*
* @param syncId
* @param playerInventory
* @param inventory
*/
public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
super(ScreenHandlerTypes.BLOCKSTACKER_SCREEN_HANDLER, syncId);
checkSize(inventory, SLOTSIZE);
this.inventory = inventory;
inventory.onOpen(playerInventory.player);
int m;
int l;
// whitelist
for (m = 0; m < 3; ++m) {
for (l = 0; l < 3; ++l) {
this.addSlot(new Slot(inventory, l + m * 3, 8 + l * 18, 17 + m * 18));
}
}
// blacklist
for (m = 0; m < 3; ++m) {
for (l = 0; l < 3; ++l) {
this.addSlot(new Slot(inventory, l + m * 3 + 9, 116 + l * 18, 17 + m * 18));
}
}
for (m = 0; m < 3; ++m) {
for (l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18));
}
}
for (m = 0; m < 9; ++m) {
this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 142));
}
}
@Override
public boolean canUse(PlayerEntity player) {
return this.inventory.canPlayerUse(player);
}
@Override
public ItemStack quickMove(PlayerEntity player, int invSlot) {
ItemStack newStack = ItemStack.EMPTY;
Slot slot = this.slots.get(invSlot);
if (slot != null && slot.hasStack()) {
ItemStack originalStack = slot.getStack();
newStack = originalStack.copy();
if (invSlot < this.inventory.size()) {
if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) {
return ItemStack.EMPTY;
}
if (originalStack.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();
}
}
return newStack;
}
}

View File

@ -0,0 +1,133 @@
package de.jottyfan.quickiemod.container;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
/**
*
* @author jotty
*
* @see https://fabricmc.net/wiki/tutorial:inventory
*
*/
public interface ImplementedInventory extends Inventory {
/**
* Retrieves the item list of this inventory.
* Must return the same instance every time it's called.
*/
DefaultedList<ItemStack> getItems();
/**
* Creates an inventory from the item list.
*/
static ImplementedInventory of(DefaultedList<ItemStack> items) {
return () -> items;
}
/**
* Creates a new inventory with the specified size.
*/
static ImplementedInventory ofSize(int size) {
return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
}
/**
* Returns the inventory size.
*/
@Override
default int size() {
return getItems().size();
}
/**
* Checks if the inventory is empty.
* @return true if this inventory has only empty stacks, false otherwise.
*/
@Override
default boolean isEmpty() {
for (int i = 0; i < size(); i++) {
ItemStack stack = getStack(i);
if (!stack.isEmpty()) {
return false;
}
}
return true;
}
/**
* Retrieves the item in the slot.
*/
@Override
default ItemStack getStack(int slot) {
return getItems().get(slot);
}
/**
* Removes items from an inventory slot.
* @param slot The slot to remove from.
* @param count How many items to remove. If there are less items in the slot than what are requested,
* takes all items in that slot.
*/
@Override
default ItemStack removeStack(int slot, int count) {
ItemStack result = Inventories.splitStack(getItems(), slot, count);
if (!result.isEmpty()) {
markDirty();
}
return result;
}
/**
* Removes all items from an inventory slot.
* @param slot The slot to remove from.
*/
@Override
default ItemStack removeStack(int slot) {
return Inventories.removeStack(getItems(), slot);
}
/**
* Replaces the current stack in an inventory slot with the provided stack.
* @param slot The inventory slot of which to replace the itemstack.
* @param stack The replacing itemstack. If the stack is too big for
* this inventory ({@link Inventory#getMaxCountPerStack()}),
* it gets resized to this inventory's maximum amount.
*/
@Override
default void setStack(int slot, ItemStack stack) {
getItems().set(slot, stack);
if (stack.getCount() > stack.getMaxCount()) {
stack.setCount(stack.getMaxCount());
}
}
/**
* Clears the inventory.
*/
@Override
default void clear() {
getItems().clear();
}
/**
* Marks the state as dirty.
* Must be called after changes in the inventory, so that the game can properly save
* the inventory contents and notify neighboring blocks of inventory changes.
*/
@Override
default void markDirty() {
// Override if you want behavior.
}
/**
* @return true if the player can use the inventory, false otherwise.
*/
@Override
default boolean canPlayerUse(PlayerEntity player) {
return true;
}
}

View File

@ -0,0 +1,14 @@
package de.jottyfan.quickiemod.container;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.screen.ScreenHandlerType;
/**
*
* @author jotty
*
*/
public class ScreenHandlerTypes {
public static final ScreenHandlerType<BlockStackerScreenHandler> BLOCKSTACKER_SCREEN_HANDLER = new ScreenHandlerType<>(BlockStackerScreenHandler::new,
FeatureFlags.VANILLA_FEATURES);
}

View File

@ -63,8 +63,15 @@ public class ModIdentifiers {
public static final Identifier BLOCK_DRILLSOUTH = Identifier.of(Quickiemod.MOD_ID, "drillsouth"); public static final Identifier BLOCK_DRILLSOUTH = Identifier.of(Quickiemod.MOD_ID, "drillsouth");
public static final Identifier BLOCK_DRILLWEST = Identifier.of(Quickiemod.MOD_ID, "drillwest"); public static final Identifier BLOCK_DRILLWEST = Identifier.of(Quickiemod.MOD_ID, "drillwest");
public static final Identifier BLOCK_DRILLNORTH = Identifier.of(Quickiemod.MOD_ID, "drillnorth"); public static final Identifier BLOCK_DRILLNORTH = Identifier.of(Quickiemod.MOD_ID, "drillnorth");
public static final Identifier BLOCK_STACKERDOWN = Identifier.of(Quickiemod.MOD_ID, "blockstackerdown");
public static final Identifier BLOCK_STACKEREAST = Identifier.of(Quickiemod.MOD_ID, "blockstackereast");
public static final Identifier BLOCK_STACKERSOUTH = Identifier.of(Quickiemod.MOD_ID, "blockstackersouth");
public static final Identifier BLOCK_STACKERWEST = Identifier.of(Quickiemod.MOD_ID, "blockstackerwest");
public static final Identifier BLOCK_STACKERNORTH = Identifier.of(Quickiemod.MOD_ID, "blockstackernorth");
public static final Identifier BLOCK_STACKERUP = Identifier.of(Quickiemod.MOD_ID, "blockstackerup");
public static final Identifier BLOCKENTITY_ITEMHOARDER = Identifier.of(Quickiemod.MOD_ID, "itemhoarderblockentity"); public static final Identifier BLOCKENTITY_ITEMHOARDER = Identifier.of(Quickiemod.MOD_ID, "itemhoarderblockentity");
public static final Identifier BLOCKENTITY_BLOCKSTACKER = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity"); public static final Identifier BLOCKENTITY_BLOCKSTACKER = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity");
public static final Identifier BLOCKENTITY_DRILL = Identifier.of(Quickiemod.MOD_ID, "drillblockentity"); public static final Identifier BLOCKENTITY_DRILL = Identifier.of(Quickiemod.MOD_ID, "drillblockentity");
public static final Identifier BLOCKSTACKERUP = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity");
} }

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackerdown"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackereast"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackernorth"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackersouth"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackerup"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "quickiemod:block/blockstackerwest"
}
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/cube_bottom_top",
"textures": {
"bottom": "quickiemod:block/blockstackerout",
"side": "quickiemod:block/blockstackerdown",
"top": "quickiemod:block/blockstackerin"
}
}

View File

@ -0,0 +1,11 @@
{
"parent": "block/cube_directional",
"textures": {
"up": "quickiemod:block/blockstackerright",
"down": "quickiemod:block/blockstackerleft",
"north": "quickiemod:block/blockstackerleft",
"east": "quickiemod:block/blockstackerout",
"south": "quickiemod:block/blockstackerright",
"west": "quickiemod:block/blockstackerin"
}
}

View File

@ -0,0 +1,11 @@
{
"parent": "block/cube_directional",
"textures": {
"up": "quickiemod:block/blockstackerup",
"down": "quickiemod:block/blockstackerup",
"north": "quickiemod:block/blockstackerout",
"east": "quickiemod:block/blockstackerup",
"south": "quickiemod:block/blockstackerin",
"west": "quickiemod:block/blockstackerup"
}
}

View File

@ -0,0 +1,11 @@
{
"parent": "block/cube_directional",
"textures": {
"up": "quickiemod:block/blockstackerdown",
"down": "quickiemod:block/blockstackerdown",
"north": "quickiemod:block/blockstackerin",
"east": "quickiemod:block/blockstackerdown",
"south": "quickiemod:block/blockstackerout",
"west": "quickiemod:block/blockstackerdown"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "block/cube_bottom_top",
"textures": {
"bottom": "quickiemod:block/blockstackerin",
"side": "quickiemod:block/blockstackerup",
"top": "quickiemod:block/blockstackerout"
}
}

View File

@ -0,0 +1,11 @@
{
"parent": "block/cube_directional",
"textures": {
"up": "quickiemod:block/blockstackerleft",
"down": "quickiemod:block/blockstackerright",
"north": "quickiemod:block/blockstackerright",
"east": "quickiemod:block/blockstackerin",
"south": "quickiemod:block/blockstackerleft",
"west": "quickiemod:block/blockstackerout"
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackerdown",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackerwest",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackernorth",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackersouth",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackerup",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "quickiemod:block/blockstackereast",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

View File

@ -0,0 +1,19 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"s s",
"scs",
" s "
],
"key": {
"s": "quickiemod:speedingot",
"c": [
"minecraft:chest",
"minecraft:barrel"
]
},
"result": {
"id": "quickiemod:blockstackerdown",
"count": 4
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackerup"
],
"result": {
"id": "quickiemod:blockstackerdown",
"count": 1
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackerdown"
],
"result": {
"id": "quickiemod:blockstackereast",
"count": 1
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackerwest"
],
"result": {
"id": "quickiemod:blockstackernorth",
"count": 1
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackereast"
],
"result": {
"id": "quickiemod:blockstackersouth",
"count": 1
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackernorth"
],
"result": {
"id": "quickiemod:blockstackerup",
"count": 1
}
}

View File

@ -0,0 +1,10 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
"quickiemod:blockstackersouth"
],
"result": {
"id": "quickiemod:blockstackerwest",
"count": 1
}
}