Reimplement stack distribution and new WIP placement order preview
Some checks failed
build / build (push) Has been cancelled
Some checks failed
build / build (push) Has been cancelled
This commit is contained in:
parent
662aa41c63
commit
f588ac5de8
@ -153,15 +153,19 @@ public abstract class OrderedContainer extends BlockEntity implements Inventory
|
|||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushStack(ItemStack stack) {
|
public ItemStack pushStack(ItemStack stack) {
|
||||||
if(stack.isEmpty()) {
|
if(stack.isEmpty()) {
|
||||||
return;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasRoom()) {
|
if(hasRoom()) {
|
||||||
inventory.add(stack);
|
inventory.add(stack);
|
||||||
|
distributeStack(stack);
|
||||||
markDirty();
|
markDirty();
|
||||||
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack pullStack() {
|
public ItemStack pullStack() {
|
||||||
@ -212,4 +216,73 @@ public abstract class OrderedContainer extends BlockEntity implements Inventory
|
|||||||
public ItemStack topStack() {
|
public ItemStack topStack() {
|
||||||
return this.inventory.getLast();
|
return this.inventory.getLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public ItemStack topStackAlike(ItemStack comparisonStack) {
|
||||||
|
// for(ItemStack stack : inventory) {
|
||||||
|
// if(ItemStack.areItemsAndComponentsEqual(stack, comparisonStack)) {
|
||||||
|
// return stack;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return ItemStack.EMPTY;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public List<ItemStack> similarStacks(ItemStack comparisonStack) {
|
||||||
|
var out = new ArrayList<ItemStack>();
|
||||||
|
|
||||||
|
for(int i = 0; i < filledSlots(); i++) {
|
||||||
|
ItemStack stack = getStack(i);
|
||||||
|
|
||||||
|
if(ItemStack.areItemsAndComponentsEqual(stack, comparisonStack)) {
|
||||||
|
out.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void distributeStack(ItemStack target) {
|
||||||
|
distributeStack(target, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void distributeStack(ItemStack target, int amount) {
|
||||||
|
List<ItemStack> candidates = similarStacks(target);
|
||||||
|
|
||||||
|
if(candidates.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int total = amount;
|
||||||
|
int maxTotal = 0;
|
||||||
|
|
||||||
|
for(ItemStack candidate : candidates) {
|
||||||
|
total += candidate.getCount();
|
||||||
|
maxTotal += candidate.getMaxCount();
|
||||||
|
candidate.setCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int remainder = 0;
|
||||||
|
if(total > maxTotal) {
|
||||||
|
remainder = total - maxTotal;
|
||||||
|
total = maxTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int share = total / candidates.size();
|
||||||
|
|
||||||
|
for(ItemStack candidate : candidates) {
|
||||||
|
candidate.setCount(share);
|
||||||
|
total -= share;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(total > 0) {
|
||||||
|
candidates.get(i % candidates.size()).increment(1);
|
||||||
|
i++;
|
||||||
|
total--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(amount != 0) {
|
||||||
|
target.decrement(amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import net.minecraft.block.BlockState;
|
|||||||
import net.minecraft.block.CrafterBlock;
|
import net.minecraft.block.CrafterBlock;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
|
||||||
import net.minecraft.inventory.CraftingResultInventory;
|
import net.minecraft.inventory.CraftingResultInventory;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.inventory.RecipeInputInventory;
|
import net.minecraft.inventory.RecipeInputInventory;
|
||||||
@ -18,7 +17,6 @@ import net.minecraft.nbt.NbtCompound;
|
|||||||
import net.minecraft.recipe.RecipeMatcher;
|
import net.minecraft.recipe.RecipeMatcher;
|
||||||
import net.minecraft.recipe.input.CraftingRecipeInput;
|
import net.minecraft.recipe.input.CraftingRecipeInput;
|
||||||
import net.minecraft.registry.RegistryWrapper;
|
import net.minecraft.registry.RegistryWrapper;
|
||||||
import net.minecraft.screen.ScreenHandler;
|
|
||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
import net.minecraft.screen.slot.CraftingResultSlot;
|
import net.minecraft.screen.slot.CraftingResultSlot;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
@ -247,15 +245,23 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Gui extends SimpleGui {
|
public class Gui extends SimpleGui {
|
||||||
|
private static final Identifier GUI_FONT_ID = Identifier.of(Grafting.MOD_ID, "workbench_gui");
|
||||||
|
|
||||||
|
private static final Identifier SLOT_ORDER_OVERLAY_FONT_ID = Identifier.of(Grafting.MOD_ID, "slot_order_overlay");
|
||||||
|
private static final char[][] SLOT_ORDER_OVERLAY_FONT_MAP = {
|
||||||
|
{ '0', '1', '2', '3', '4', '5', '6', '7' },
|
||||||
|
{ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' },
|
||||||
|
{ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' }
|
||||||
|
};
|
||||||
|
|
||||||
private static final int BUTTON_COLUMN = 1;
|
private static final int BUTTON_COLUMN = 1;
|
||||||
private static final int GRID_START_COLUMN = BUTTON_COLUMN + 1;
|
private static final int GRID_START_COLUMN = BUTTON_COLUMN + 1;
|
||||||
private static final int RESULT_COLUMN = GRID_START_COLUMN + GRID_SIZE + 2;
|
private static final int RESULT_COLUMN = GRID_START_COLUMN + GRID_SIZE + 2;
|
||||||
private static final int BASE_HEIGHT = 3;
|
private static final int BASE_HEIGHT = 3;
|
||||||
|
|
||||||
private static final Identifier GUI_FONT_ID = Identifier.of(Grafting.MOD_ID, "workbench_gui");
|
|
||||||
|
|
||||||
private final CraftingResultInventory resultInventory = new CraftingResultInventory();
|
private final CraftingResultInventory resultInventory = new CraftingResultInventory();
|
||||||
private boolean attachedInventory;
|
private AttachedInventory attachedInventory;
|
||||||
|
private ItemStack knownCursorStack = ItemStack.EMPTY;
|
||||||
public Gui(ServerPlayerEntity player) {
|
public Gui(ServerPlayerEntity player) {
|
||||||
this(player, Optional.empty());
|
this(player, Optional.empty());
|
||||||
}
|
}
|
||||||
@ -268,13 +274,10 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
player,
|
player,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
attachedInventory.ifPresent(inventory -> this.attachedInventory = inventory);
|
||||||
guis.add(this);
|
guis.add(this);
|
||||||
|
|
||||||
setTitle(
|
updateTitle();
|
||||||
Text.empty()
|
|
||||||
.append(Text.literal(attachedInventory.isEmpty() ? "-0." : "-1.").setStyle(Style.EMPTY.withFont(GUI_FONT_ID).withColor(Formatting.WHITE)))
|
|
||||||
.append(Text.translatable("container.crafting"))
|
|
||||||
);
|
|
||||||
|
|
||||||
setSlot(BUTTON_COLUMN, new RotateGridButton(Icons.ROTATE_CLOCKWISE,1));
|
setSlot(BUTTON_COLUMN, new RotateGridButton(Icons.ROTATE_CLOCKWISE,1));
|
||||||
setSlot(BUTTON_COLUMN + 9, new RotateGridButton(Icons.ROTATE_COUNTER_CLOCKWISE, -1));
|
setSlot(BUTTON_COLUMN + 9, new RotateGridButton(Icons.ROTATE_COUNTER_CLOCKWISE, -1));
|
||||||
@ -297,24 +300,109 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
updateResult();
|
updateResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int getUnextendedSize() {
|
||||||
public void close() {
|
return BASE_HEIGHT * 9;
|
||||||
guis.remove(this);
|
|
||||||
super.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateResult() {
|
protected void updateResult() {
|
||||||
resultInventory.setStack(0, getResult(player));
|
resultInventory.setStack(0, getResult(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
guis.remove(this);
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onAnyClick(int index, ClickType type, SlotActionType action) {
|
||||||
|
ItemStack cursorStack = screenHandler.getCursorStack();
|
||||||
|
|
||||||
|
Slot slot = getSlotRedirectOrPlayer(index);
|
||||||
|
if(type.equals(ClickType.MOUSE_LEFT) && slot != null) {
|
||||||
|
cursorStack = slot.getStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cursorStack != knownCursorStack) {
|
||||||
|
knownCursorStack = cursorStack;
|
||||||
|
updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onAnyClick(index, type, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTitle() {
|
||||||
|
var title = Text.empty();
|
||||||
|
|
||||||
|
title.append(
|
||||||
|
Text.literal(attachedInventory != null ? "-1." : "-0.")
|
||||||
|
.setStyle(Style.EMPTY.withFont(GUI_FONT_ID).withColor(Formatting.WHITE))
|
||||||
|
);
|
||||||
|
|
||||||
|
title.append(
|
||||||
|
Text.literal(getSlotOrderLiteral())
|
||||||
|
.setStyle(Style.EMPTY.withFont(SLOT_ORDER_OVERLAY_FONT_ID).withColor(Formatting.WHITE))
|
||||||
|
);
|
||||||
|
|
||||||
|
title.append(Text.translatable("container.crafting"));
|
||||||
|
setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSlotOrderLiteral() {
|
||||||
|
StringBuilder out = new StringBuilder();
|
||||||
|
out.append(" ".repeat(GRID_START_COLUMN));
|
||||||
|
|
||||||
|
if(knownCursorStack.isEmpty()) {
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var placements = PlacementUtils.rotate(
|
||||||
|
PlacementUtils.getPlacements(knownCursorStack, (ServerWorld) world),
|
||||||
|
craftingOrientation
|
||||||
|
);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
boolean newCol = true;
|
||||||
|
for(int j = 0; j < 3; j++) {
|
||||||
|
int order = placements[j * 3 + i] - filledSlots() - 1;
|
||||||
|
|
||||||
|
if(order < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newCol) {
|
||||||
|
newCol = false;
|
||||||
|
out.append('.');
|
||||||
|
} else {
|
||||||
|
out.append('-');
|
||||||
|
}
|
||||||
|
|
||||||
|
out.append(SLOT_ORDER_OVERLAY_FONT_MAP[j][order]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newCol) {
|
||||||
|
out.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.append("___");
|
||||||
|
|
||||||
|
Grafting.LOGGER.info("Test: {}", out.toString());
|
||||||
|
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See: CraftingScreenHandler#quickMove
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ItemStack quickMove(int index) {
|
public ItemStack quickMove(int index) {
|
||||||
ItemStack returnStack = ItemStack.EMPTY;
|
ItemStack returnStack = ItemStack.EMPTY;
|
||||||
Slot slot = this.getSlotRedirectOrPlayer(index);
|
Slot slot = this.getSlotRedirectOrPlayer(index);
|
||||||
|
boolean isResultSlot = slot instanceof CraftingResultSlot;
|
||||||
|
|
||||||
if(slot != null && slot.hasStack() && !(slot instanceof VirtualSlot)) {
|
if(slot != null && slot.hasStack() && !(slot instanceof VirtualSlot)) {
|
||||||
ItemStack operatingStack;
|
ItemStack operatingStack;
|
||||||
|
|
||||||
if(slot instanceof GridSlot) {
|
if(slot instanceof GridSlot) {
|
||||||
operatingStack = topStack();
|
operatingStack = topStack();
|
||||||
} else {
|
} else {
|
||||||
@ -322,12 +410,24 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
}
|
}
|
||||||
returnStack = operatingStack.copy();
|
returnStack = operatingStack.copy();
|
||||||
|
|
||||||
if(index < this.getVirtualSize()) {
|
if(isResultSlot) {
|
||||||
|
operatingStack.getItem().onCraftByPlayer(operatingStack, world, player);
|
||||||
|
|
||||||
if(!this.insertItem(operatingStack, this.getVirtualSize(), this.getVirtualSize() + 36, true)) {
|
if(!this.insertItem(operatingStack, this.getVirtualSize(), this.getVirtualSize() + 36, true)) {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
} else if (!this.insertItem(operatingStack, 0, this.getVirtualSize(), false)) {
|
|
||||||
return ItemStack.EMPTY;
|
slot.onQuickTransfer(operatingStack, returnStack);
|
||||||
|
} else if(index < getUnextendedSize()) {
|
||||||
|
if(!this.insertItem(operatingStack, this.getUnextendedSize(), this.getVirtualSize() + 36, false)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(similarStacks(operatingStack).isEmpty() && hasRoom()) {
|
||||||
|
pushStack(operatingStack.copyAndEmpty());
|
||||||
|
} else {
|
||||||
|
distributeStack(operatingStack, operatingStack.getCount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operatingStack.isEmpty()) {
|
if (operatingStack.isEmpty()) {
|
||||||
@ -335,6 +435,15 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
} else {
|
} else {
|
||||||
slot.markDirty();
|
slot.markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(returnStack.getCount() == operatingStack.getCount()) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
slot.onTakeItem(player, returnStack);
|
||||||
|
if(isResultSlot) {
|
||||||
|
player.dropItem(returnStack, false);
|
||||||
|
}
|
||||||
} else if (slot instanceof VirtualSlot) {
|
} else if (slot instanceof VirtualSlot) {
|
||||||
return slot.getStack();
|
return slot.getStack();
|
||||||
}
|
}
|
||||||
@ -349,23 +458,36 @@ public class WorkbenchBlockEntity extends OrderedContainer {
|
|||||||
super(WorkbenchBlockEntity.this.recipeInventory, index, index, 0);
|
super(WorkbenchBlockEntity.this.recipeInventory, index, index, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public ItemStack insertStack(ItemStack stack, int count) {
|
public ItemStack insertStack(ItemStack stack, int count) {
|
||||||
//
|
if(stack.isEmpty()) {
|
||||||
// if(stack.isEmpty()) {
|
return stack;
|
||||||
// return stack;
|
}
|
||||||
// }
|
|
||||||
//
|
int allowedCount = Math.min(count, stack.getCount());
|
||||||
// int allowedCount = Math.min(count, stack.getCount());
|
if(
|
||||||
// if(
|
(getStack().isEmpty() || similarStacks(stack).isEmpty()) &&
|
||||||
// (!hasItemsLike(stack) || count == 1) &&
|
hasRoom()
|
||||||
// WorkbenchBlockEntity.this.hasRoom()
|
) { // Right click
|
||||||
// ) {
|
pushStack(stack.split(allowedCount));
|
||||||
// pushStack(stack.split(allowedCount));
|
} else {
|
||||||
// }
|
distributeStack(stack, allowedCount);
|
||||||
//
|
if(stack.isEmpty()) {
|
||||||
// return stack;
|
return ItemStack.EMPTY;
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack takeStack(int amount) {
|
||||||
|
var o = super.takeStack(amount);
|
||||||
|
if(!getStack().isEmpty()) {
|
||||||
|
distributeStack(getStack());
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CraftingResultGridSlot extends CraftingResultSlot {
|
public class CraftingResultGridSlot extends CraftingResultSlot {
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"type": "space",
|
||||||
|
"advances": {
|
||||||
|
".": -1,
|
||||||
|
"-": -19,
|
||||||
|
"_": -18,
|
||||||
|
" ": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bitmap",
|
||||||
|
"file": "grafting:gui/slots.png",
|
||||||
|
"ascent": -4,
|
||||||
|
"height": 64,
|
||||||
|
"chars": [
|
||||||
|
"0123456789abcdefghijklmn"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
"type": "space",
|
"type": "space",
|
||||||
"advances": {
|
"advances": {
|
||||||
".": -134,
|
".": -169,
|
||||||
"-": -8
|
"-": -8
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
BIN
src/main/resources/assets/grafting/textures/gui/slots.png
Normal file
BIN
src/main/resources/assets/grafting/textures/gui/slots.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/main/resources/assets/grafting/textures/gui/slots.xcf
Normal file
BIN
src/main/resources/assets/grafting/textures/gui/slots.xcf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user