basic block stacker, but still with bugs
This commit is contained in:
84
src/main/java/de/jottyfan/minecraft/block/BlockStacker.java
Normal file
84
src/main/java/de/jottyfan/minecraft/block/BlockStacker.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package de.jottyfan.minecraft.block;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
|
||||
import de.jottyfan.minecraft.blockentity.BlockStackerEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class BlockStacker extends Block implements EntityBlock {
|
||||
public static final MapCodec<BlockStacker> CODEC = simpleCodec(BlockStacker::new);
|
||||
|
||||
public static final EnumProperty<Direction> SOURCE = EnumProperty.create("source", Direction.class, Direction.NORTH,
|
||||
Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN);
|
||||
public static final EnumProperty<Direction> DEST = EnumProperty.create("dest", Direction.class, Direction.NORTH,
|
||||
Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN);
|
||||
|
||||
public BlockStacker(Properties properties) {
|
||||
super(properties);
|
||||
registerDefaultState(stateDefinition.any().setValue(SOURCE, Direction.UP).setValue(DEST, Direction.DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(SOURCE, DEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return this.defaultBlockState().setValue(SOURCE, context.getNearestLookingDirection()).setValue(DEST, context.getNearestLookingDirection().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockEntity> @Nullable BlockEntityTicker<T> getTicker(Level level, BlockState blockState,
|
||||
BlockEntityType<T> type) {
|
||||
return (lambdaLevel, pos, state, blockEntity) -> BlockStackerEntity.tick(lambdaLevel, pos, state, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
return new BlockStackerEntity(pos, blockState);
|
||||
}
|
||||
|
||||
public static MapCodec<BlockStacker> getCodec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
public Direction getSource(BlockState state) {
|
||||
return state.getValue(SOURCE);
|
||||
}
|
||||
|
||||
public Direction getDest(BlockState state) {
|
||||
return state.getValue(DEST);
|
||||
}
|
||||
|
||||
public BlockPos getOffset(BlockState state, EnumProperty<Direction> sourceOrDest) {
|
||||
BlockPos pos = new BlockPos(0, 0, 0);
|
||||
return switch (state.getValue(sourceOrDest)) {
|
||||
case Direction.UP -> pos.above();
|
||||
case Direction.DOWN -> pos.below();
|
||||
case Direction.NORTH -> pos.north();
|
||||
case Direction.EAST -> pos.east();
|
||||
case Direction.SOUTH -> pos.south();
|
||||
case Direction.WEST -> pos.west();
|
||||
default -> pos;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.util.function.Function;
|
||||
|
||||
import de.jottyfan.minecraft.Quickly;
|
||||
import de.jottyfan.minecraft.blockentity.BlockEntityRegister;
|
||||
import de.jottyfan.minecraft.blockentity.BlockStackerEntity;
|
||||
import de.jottyfan.minecraft.blockentity.DrillBlockEntity;
|
||||
import de.jottyfan.minecraft.blockentity.ItemHoarderBlockEntity;
|
||||
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||
@@ -55,8 +56,8 @@ public class QuicklyBlocks {
|
||||
properties -> new Monsterhoarder(properties));
|
||||
public static final Block ITEMHOARDER = registerBlock("itemhoarder", properties -> new Itemhoarder(properties));
|
||||
public static final Block DRILL = registerBlock("drill", properties -> new BlockDrill(properties));
|
||||
public static final Block STACKER = registerBlock("blockstacker", properties -> new BlockStacker(properties.strength(2.5f)));
|
||||
|
||||
// TODO: add blockstacker
|
||||
// TODO: add salpeter ore, sulfor ore
|
||||
// TODO: merge lavahoarder and emptylavahoarder into one block using a BooleanProperty for the lava fill state
|
||||
|
||||
@@ -64,6 +65,8 @@ public class QuicklyBlocks {
|
||||
.registerBlockEntity("itemhoarderblockentity", ItemHoarderBlockEntity::new, ITEMHOARDER);
|
||||
public static final BlockEntityType<DrillBlockEntity> BLOCKENTITY_DRILL = new BlockEntityRegister<DrillBlockEntity>()
|
||||
.registerBlockEntity("drillblockentity", DrillBlockEntity::new, DRILL);
|
||||
public static final BlockEntityType<BlockStackerEntity> BLOCKSTACKER_BLOCKENTITY = new BlockEntityRegister<BlockStackerEntity>()
|
||||
.registerBlockEntity("blockstackerentity", BlockStackerEntity::new, STACKER);
|
||||
|
||||
private static final Block registerBlock(String name, Properties properties) {
|
||||
return QuicklyBlocks.registerBlock(name, properties, p -> new Block(p));
|
||||
@@ -95,6 +98,7 @@ public class QuicklyBlocks {
|
||||
block.accept(MONSTERHOARDER);
|
||||
block.accept(ITEMHOARDER);
|
||||
block.accept(DRILL);
|
||||
block.accept(STACKER);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package de.jottyfan.minecraft.blockentity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import de.jottyfan.minecraft.Quickly;
|
||||
import de.jottyfan.minecraft.block.BlockStacker;
|
||||
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.SlotAccess;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class BlockStackerEntity extends BlockEntity implements Container {
|
||||
|
||||
public static final Codec<Map<String, ItemStack>> ITEM_STACK_MAP_CODEC = Codec.unboundedMap(Codec.STRING,
|
||||
ItemStack.CODEC);
|
||||
|
||||
private List<ItemStack> inventory = new ArrayList<>();
|
||||
|
||||
public BlockStackerEntity(BlockPos pos, BlockState blockState) {
|
||||
super(QuicklyBlocks.BLOCKSTACKER_BLOCKENTITY, pos, blockState);
|
||||
}
|
||||
|
||||
public static <T extends BlockEntity> Object tick(Level level, BlockPos pos, BlockState state, T entity) {
|
||||
pos.below();
|
||||
BlockStacker block = (BlockStacker) state.getBlock();
|
||||
BlockEntity source = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.SOURCE)));
|
||||
BlockEntity dest = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.DEST)));
|
||||
Boolean sourceIsLootable = source instanceof BaseContainerBlockEntity;
|
||||
Boolean destIsLootable = dest instanceof BaseContainerBlockEntity;
|
||||
if (sourceIsLootable && destIsLootable) {
|
||||
BaseContainerBlockEntity lootableSource = (BaseContainerBlockEntity) source;
|
||||
BaseContainerBlockEntity lootableDest = (BaseContainerBlockEntity) dest;
|
||||
transferOneStack(lootableSource, lootableDest);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final Boolean transferOneStack(BaseContainerBlockEntity source, BaseContainerBlockEntity dest) {
|
||||
Boolean result = false;
|
||||
Integer sourceSlot = findItemStackPos(source, false);
|
||||
if (sourceSlot != null && !Items.AIR.equals(source.getSlot(sourceSlot).get().getItem())) {
|
||||
ItemStack sourceStack = source.getSlot(sourceSlot).get();
|
||||
Integer destSlot = findItemStackPos(dest, sourceStack);
|
||||
if (destSlot != null) {
|
||||
ItemStack destStack = dest.getSlot(destSlot).get();
|
||||
Integer occupied = destStack.getCount();
|
||||
Integer free = destStack.getCount() - occupied;
|
||||
Integer candidates = sourceStack.getCount();
|
||||
Integer travellers = candidates > free ? free : candidates;
|
||||
if (travellers > 0) {
|
||||
Quickly.LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates,
|
||||
sourceStack.getItem().toString(), sourceSlot, destSlot, occupied);
|
||||
sourceStack.shrink(travellers);
|
||||
destStack.grow(travellers);
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
Integer destFreeSlot = findItemStackPos(dest, true);
|
||||
if (destFreeSlot != null) {
|
||||
Quickly.LOGGER.debug("transfer all of {} from slot {} to slot {}", sourceStack.getItem().toString(),
|
||||
sourceSlot, destSlot);
|
||||
dest.setItem(destFreeSlot, new ItemStack(sourceStack.getItem(), sourceStack.getCount()));
|
||||
sourceStack.shrink(sourceSlot);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, ItemStack sourceStack) {
|
||||
Integer counter = blockEntity.getContainerSize();
|
||||
while (counter > 0) {
|
||||
counter--;
|
||||
@Nullable
|
||||
SlotAccess slotAccess = blockEntity.getSlot(counter);
|
||||
if (slotAccess != null) {
|
||||
ItemStack stack = slotAccess.get();
|
||||
if (sourceStack.getItem().equals(stack.getItem())) {
|
||||
if (stack.getCount() < stack.getCount()) {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, Boolean empty) {
|
||||
Integer counter = blockEntity.getContainerSize();
|
||||
while (counter > 0) {
|
||||
counter--;
|
||||
@Nullable
|
||||
SlotAccess slotAccess = blockEntity.getSlot(counter);
|
||||
if (slotAccess != null) {
|
||||
ItemStack stack = slotAccess.get();
|
||||
if (empty.equals(ItemStack.EMPTY.equals(stack))) {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
inventory.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return inventory.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
return inventory.get(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int count) {
|
||||
ItemStack stack = inventory.get(slot);
|
||||
stack.shrink(count);
|
||||
setChanged();
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int slot) {
|
||||
ItemStack stack = inventory.get(slot);
|
||||
stack.shrink(stack.getCount());
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack itemStack) {
|
||||
inventory.set(slot, itemStack);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"variants": {
|
||||
"dest=up": { "model": "quickly:block/blockstackerup" },
|
||||
"dest=down": { "model": "quickly:block/blockstackerdown" },
|
||||
"dest=east": { "model": "quickly:block/blockstackereast" },
|
||||
"dest=south": { "model": "quickly:block/blockstackersouth" },
|
||||
"dest=west": { "model": "quickly:block/blockstackerwest" },
|
||||
"dest=north": { "model": "quickly:block/blockstackernorth" }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "quickly:block/drilleast"
|
||||
"model": "quickly:block/blockstackerdown"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "quickly:block/drillnorth"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "quickly:block/drillsouth"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "quickly:block/drillwest"
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
"item.quickly.blockcottonplant": "Baumwollpflanze",
|
||||
"item.quickly.blockquickiepowder": "Eilpulverblock",
|
||||
"item.quickly.blockspeedpowder": "Fluchtpulverblock",
|
||||
"item.quickly.blockstacker": "Stapler",
|
||||
"item.quickly.blockturquoise": "Türkisblock",
|
||||
"item.quickly.canola": "Raps",
|
||||
"item.quickly.canolabottle": "Rapsöl",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"item.quickly.blockcottonplant": "cotton plant",
|
||||
"item.quickly.blockquickiepowder": "quickie powder block",
|
||||
"item.quickly.blockspeedpowder": "speed powder block",
|
||||
"item.quickly.blockstacker": "stacker",
|
||||
"item.quickly.blockturquoise": "block of turquoise",
|
||||
"item.quickly.canola": "canola",
|
||||
"item.quickly.canolabottle": "canola oil",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_bottom_top",
|
||||
"textures": {
|
||||
"bottom": "quickly:block/blockstackerout",
|
||||
"side": "quickly:block/blockstackerdown",
|
||||
"top": "quickly:block/blockstackerin"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "block/cube_directional",
|
||||
"textures": {
|
||||
"up": "quickly:block/blockstackerright",
|
||||
"down": "quickly:block/blockstackerleft",
|
||||
"north": "quickly:block/blockstackerleft",
|
||||
"east": "quickly:block/blockstackerout",
|
||||
"south": "quickly:block/blockstackerright",
|
||||
"west": "quickly:block/blockstackerin"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "block/cube_directional",
|
||||
"textures": {
|
||||
"up": "quickly:block/blockstackerup",
|
||||
"down": "quickly:block/blockstackerup",
|
||||
"north": "quickly:block/blockstackerout",
|
||||
"east": "quickly:block/blockstackerup",
|
||||
"south": "quickly:block/blockstackerin",
|
||||
"west": "quickly:block/blockstackerup"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "block/cube_directional",
|
||||
"textures": {
|
||||
"up": "quickly:block/blockstackerdown",
|
||||
"down": "quickly:block/blockstackerdown",
|
||||
"north": "quickly:block/blockstackerin",
|
||||
"east": "quickly:block/blockstackerdown",
|
||||
"south": "quickly:block/blockstackerout",
|
||||
"west": "quickly:block/blockstackerdown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "block/cube_bottom_top",
|
||||
"textures": {
|
||||
"bottom": "quickly:block/blockstackerin",
|
||||
"side": "quickly:block/blockstackerup",
|
||||
"top": "quickly:block/blockstackerout"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "block/cube_directional",
|
||||
"textures": {
|
||||
"up": "quickly:block/blockstackerleft",
|
||||
"down": "quickly:block/blockstackerright",
|
||||
"north": "quickly:block/blockstackerright",
|
||||
"east": "quickly:block/blockstackerin",
|
||||
"south": "quickly:block/blockstackerleft",
|
||||
"west": "quickly:block/blockstackerout"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"parent": "quickly:block/blockstackerdown",
|
||||
"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: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"s s",
|
||||
"scs",
|
||||
" s "
|
||||
],
|
||||
"key": {
|
||||
"s": "quickky:speedingot",
|
||||
"c": [
|
||||
"minecraft:chest",
|
||||
"minecraft:barrel"
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"id": "quickly:blockstacker",
|
||||
"count": 4
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user