improved bag seed usage
This commit is contained in:
@ -0,0 +1,84 @@
|
||||
package de.jottyfan.minecraft.quickiefabric.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class Neighborhood {
|
||||
|
||||
/**
|
||||
* find the same blocks that is next to the current position pos
|
||||
*
|
||||
* @param world the world to look for the blocks
|
||||
* @param pos the starting position
|
||||
* @param seekLimit the limit of seek operations
|
||||
* @param checkLambda check functionality
|
||||
* @return a set of found block positions
|
||||
*/
|
||||
public static final Set<BlockPos> findEqualBlock(World world, BlockPos pos, int seekLimit,
|
||||
BiFunction<World, BlockPos, Boolean> checkLambda) {
|
||||
Set<NeighborhoodBean> found = new HashSet<>();
|
||||
found.add(new NeighborhoodBean(pos, true));
|
||||
|
||||
while (pos != null && found.size() < seekLimit) {
|
||||
findNewNeihgbor(world, pos.east(), found, checkLambda);
|
||||
findNewNeihgbor(world, pos.south(), found, checkLambda);
|
||||
findNewNeihgbor(world, pos.west(), found, checkLambda);
|
||||
findNewNeihgbor(world, pos.north(), found, checkLambda);
|
||||
pos = findNextUncheckedField(found);
|
||||
}
|
||||
|
||||
Set<BlockPos> finals = new HashSet<>();
|
||||
for (NeighborhoodBean bean : found) {
|
||||
finals.add(bean.getPos());
|
||||
}
|
||||
return finals;
|
||||
}
|
||||
|
||||
private static final BlockPos findNextUncheckedField(Set<NeighborhoodBean> found) {
|
||||
Iterator<NeighborhoodBean> i = found.iterator();
|
||||
while (i.hasNext()) {
|
||||
NeighborhoodBean bean = i.next();
|
||||
if (!bean.isChecked()) {
|
||||
bean.setChecked(true);
|
||||
return bean.getPos();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* find new neighbor at pos
|
||||
*
|
||||
* @param world the world
|
||||
* @param pos the position
|
||||
* @param found the set with all already found positions
|
||||
* @return true or false
|
||||
*/
|
||||
private static final boolean findNewNeihgbor(World world, BlockPos pos, Set<NeighborhoodBean> found,
|
||||
BiFunction<World, BlockPos, Boolean> checkLambda) {
|
||||
NeighborhoodBean bean = new NeighborhoodBean(pos);
|
||||
if (found.contains(bean) || found.contains(bean.over()) || found.contains(bean.below())) {
|
||||
return false;
|
||||
} else if (checkLambda.apply(world, pos).booleanValue()) {
|
||||
found.add(bean);
|
||||
return true;
|
||||
} else if (checkLambda.apply(world, pos.up()).booleanValue()) {
|
||||
found.add(new NeighborhoodBean(pos.up()));
|
||||
return true;
|
||||
} else if (checkLambda.apply(world, pos.down()).booleanValue()) {
|
||||
found.add(new NeighborhoodBean(pos.down()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package de.jottyfan.minecraft.quickiefabric.api;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class NeighborhoodBean {
|
||||
private final BlockPos pos;
|
||||
private boolean checked;
|
||||
|
||||
public NeighborhoodBean(BlockPos pos, boolean checked) {
|
||||
super();
|
||||
this.pos = pos;
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public NeighborhoodBean(BlockPos pos) {
|
||||
super();
|
||||
this.pos = pos;
|
||||
this.checked = false;
|
||||
}
|
||||
|
||||
public NeighborhoodBean over() {
|
||||
return new NeighborhoodBean(pos.up(), checked);
|
||||
}
|
||||
|
||||
public NeighborhoodBean below() {
|
||||
return new NeighborhoodBean(pos.down(), checked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
Boolean result = null;
|
||||
if (this == obj) {
|
||||
result = true;
|
||||
} else if (obj == null) {
|
||||
result = false;
|
||||
} else if (getClass() != obj.getClass()) {
|
||||
result = false;
|
||||
} else {
|
||||
NeighborhoodBean other = (NeighborhoodBean) obj;
|
||||
result = Objects.equals(pos, other.pos);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the checked
|
||||
*/
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param checked the checked to set
|
||||
*/
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pos
|
||||
*/
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package de.jottyfan.minecraft.quickiefabric.items;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import de.jottyfan.minecraft.quickiefabric.api.Neighborhood;
|
||||
import de.jottyfan.minecraft.quickiefabric.container.BackpackInventory;
|
||||
import de.jottyfan.minecraft.quickiefabric.item.ModdedItemUsageContext;
|
||||
import net.minecraft.block.Blocks;
|
||||
@ -10,7 +11,6 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
@ -24,16 +24,16 @@ import net.minecraft.world.World;
|
||||
*/
|
||||
public class ItemBag extends ItemBackpack {
|
||||
|
||||
private Integer useItemsOfStack(ItemStack stack, List<BlockPos> posList, ItemUsageContext context, World world,
|
||||
private Integer useItemsOfStack(ItemStack stack, Set<BlockPos> posList, ItemUsageContext context, World world,
|
||||
PlayerEntity player, Item item) {
|
||||
for (BlockPos pos : posList) {
|
||||
Iterator<BlockPos> iterator = posList.iterator();
|
||||
while (iterator.hasNext() && stack.getCount() > 0) {
|
||||
BlockPos pos = iterator.next();
|
||||
BlockHitResult hit = new BlockHitResult(context.getHitPos(), context.getSide(), pos, context.hitsInsideBlock());
|
||||
ModdedItemUsageContext iuc = new ModdedItemUsageContext(world, player, Hand.MAIN_HAND, stack, hit);
|
||||
item.useOnBlock(iuc);
|
||||
stack.decrement(1);
|
||||
if (stack.getCount() < 1) { // interrupt if stack is empty
|
||||
break;
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
return stack.getCount();
|
||||
}
|
||||
@ -44,16 +44,13 @@ public class ItemBag extends ItemBackpack {
|
||||
World world = context.getWorld();
|
||||
PlayerEntity player = context.getPlayer();
|
||||
if (isFreeFarmland(world, pos)) {
|
||||
if (!world.isClient) {
|
||||
player.sendMessage(new TranslatableText("msg.notyetimplemented"), false);
|
||||
}
|
||||
BackpackInventory bi = new BackpackInventory(context.getStack());
|
||||
Set<BlockPos> posList = Neighborhood.findEqualBlock(world, pos, 4096, (w, p) -> {
|
||||
return Blocks.FARMLAND.equals(w.getBlockState(p).getBlock()) && w.getBlockState(p.up()).isAir();
|
||||
});
|
||||
for (int slot = 0; slot < ItemBackpack.SLOTSIZE; slot++) {
|
||||
ItemStack stack = bi.getStack(slot);
|
||||
if (stack.getCount() > 0) {
|
||||
// not yet working recursive calls of findFreeFields; do not use this now!
|
||||
// List<BlockPos> posList = findFreeFields(new ArrayList<>(), world, pos, stack.getCount());
|
||||
List<BlockPos> posList = hackedFindFields(world, pos);
|
||||
for (int i = stack.getCount(); i > 0; i--) {
|
||||
int beforeUsage = stack.getCount();
|
||||
int afterUsage = useItemsOfStack(stack, posList, context, world, player, stack.getItem());
|
||||
@ -75,72 +72,6 @@ public class ItemBag extends ItemBackpack {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add pos to list if it is farmland
|
||||
*
|
||||
* @param list the list
|
||||
* @param world the world
|
||||
* @param pos the pos
|
||||
* @return the added pos; might be up or down also; if null, no farmland was
|
||||
* found or the element has been already added or there are more
|
||||
* farmland fields than seed
|
||||
*/
|
||||
private BlockPos addToListIfNotYetDone(List<BlockPos> list, World world, BlockPos pos, Integer limit) {
|
||||
if (limit < list.size()) {
|
||||
return null; // interrupt here to reduce calculation time
|
||||
} else if (!list.contains(pos) && isFreeFarmland(world, pos)) {
|
||||
list.add(pos);
|
||||
return pos;
|
||||
} else if (!list.contains(pos.up()) && isFreeFarmland(world, pos.up())) {
|
||||
list.add(pos.up());
|
||||
return pos.up();
|
||||
} else if (!list.contains(pos.down()) && isFreeFarmland(world, pos.down())) {
|
||||
list.add(pos.down());
|
||||
return pos.down();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find the next free fields that can be used to set a sapling to...
|
||||
*
|
||||
* @param world the world
|
||||
* @param start the starting position
|
||||
* @return the next free blocks of farmland - might be even the one on start
|
||||
* @deprecated not yet safe abort condition; do not use it in the game
|
||||
*/
|
||||
@Deprecated
|
||||
private final List<BlockPos> findFreeFields(List<BlockPos> list, World world, BlockPos start, Integer limit) {
|
||||
addToListIfNotYetDone(list, world, start, limit);
|
||||
BlockPos east = addToListIfNotYetDone(list, world, start.east(), limit);
|
||||
if (east != null) {
|
||||
list.addAll(findFreeFields(list, world, east, limit));
|
||||
}
|
||||
BlockPos west = addToListIfNotYetDone(list, world, start.west(), limit);
|
||||
if (west != null) {
|
||||
list.addAll(findFreeFields(list, world, west, limit));
|
||||
}
|
||||
BlockPos south = addToListIfNotYetDone(list, world, start.south(), limit);
|
||||
if (south != null) {
|
||||
list.addAll(findFreeFields(list, world, south, limit));
|
||||
}
|
||||
BlockPos north = addToListIfNotYetDone(list, world, start.north(), limit);
|
||||
if (north != null) {
|
||||
list.addAll(findFreeFields(list, world, north, limit));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private final List<BlockPos> hackedFindFields(World world, BlockPos pos) {
|
||||
List<BlockPos> list = new ArrayList<>();
|
||||
if (isFreeFarmland(world, pos)) {
|
||||
list.add(pos);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the block on pos is farmland and the one above is air
|
||||
*
|
||||
|
Reference in New Issue
Block a user