Added stack merging, RMB actions, Sticks and fixed an unholy bug
- Added Test:Stick - When left-clicking, stacks that can merge will - Added right-clicking behavior straight from Minecraft - hooooooly sh*t man StatefulObject.equals was totally broken omfg how tf i did notice :o
This commit is contained in:
parent
b3ac7b6afe
commit
040a4f7fd7
@ -235,7 +235,7 @@ public abstract class StatefulObject extends Namespaced implements Encodable {
|
||||
|
||||
StatefulObject statefulObj = (StatefulObject) obj;
|
||||
|
||||
if (statefulObj.getId().equals(this.getId()))
|
||||
if (!statefulObj.getId().equals(this.getId()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -94,6 +94,21 @@ public class ItemSlot implements Encodable {
|
||||
return amount == 0;
|
||||
}
|
||||
|
||||
public synchronized boolean canInsert(ItemData contents, int amount) {
|
||||
|
||||
// Ignore amount
|
||||
|
||||
if (this.contents == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.contents.equals(contents);
|
||||
}
|
||||
|
||||
public synchronized boolean canRemove(int amount) {
|
||||
return this.amount >= amount;
|
||||
}
|
||||
|
||||
private synchronized void checkState() {
|
||||
if ((contents == null) != (amount == 0)) {
|
||||
if (contents == null) {
|
||||
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.common.world.item;
|
||||
|
||||
public class Items {
|
||||
|
||||
/**
|
||||
* Attempts to transfer as many items as possible, but no more than
|
||||
* {@code max}, between two slots. The origin of the items is {@code from},
|
||||
* the destination is {@code into}. This method does nothing if the items
|
||||
* could not be removed from origin or could not be inserted into
|
||||
* destination, such as when {@code into} contains different items.
|
||||
*
|
||||
* @param from the slot to transfer item from
|
||||
* @param into the destination of the items
|
||||
* @param max the maximum amount of items to transfer. Use
|
||||
* {@code Integer.MAX_VALUE} to remove the limit
|
||||
* @return the actual amount of items moved between slots
|
||||
*/
|
||||
public static int pour(ItemSlot from, ItemSlot into, int max) {
|
||||
synchronized (from) {
|
||||
synchronized (into) {
|
||||
|
||||
ItemData item = from.getContents();
|
||||
|
||||
int originalAmount = from.getAmount();
|
||||
int transferAmount = Math.min(originalAmount, max);
|
||||
|
||||
while (transferAmount > 0 && !into.canInsert(item, transferAmount)) {
|
||||
transferAmount--;
|
||||
}
|
||||
|
||||
if (transferAmount == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!from.canRemove(transferAmount)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
into.setContents(item, into.getAmount() + transferAmount);
|
||||
from.setAmount(originalAmount - transferAmount);
|
||||
|
||||
return transferAmount;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transfer as many items as possible between two slots. The
|
||||
* origin of the items is {@code from}, the destination is {@code into}.
|
||||
* This method does nothing if the items could not be removed from origin or
|
||||
* could not be inserted into destination, such as when {@code into}
|
||||
* contains different items.
|
||||
*
|
||||
* @param from the slot to transfer item from
|
||||
* @param into the destination of the items
|
||||
* @return the actual amount of items moved between slots
|
||||
*/
|
||||
public static int pour(ItemSlot from, ItemSlot into) {
|
||||
return pour(from, into, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to swap the contents of the two slots.
|
||||
*
|
||||
* @param a one of the slots
|
||||
* @param b the other slot
|
||||
*
|
||||
* @return whether the swap succeeded
|
||||
*/
|
||||
public static boolean swap(ItemSlot a, ItemSlot b) {
|
||||
synchronized (a) {
|
||||
synchronized (b) {
|
||||
|
||||
ItemData aItem = a.getContents();
|
||||
int aAmount = a.getAmount();
|
||||
|
||||
ItemData bItem = b.getContents();
|
||||
int bAmount = b.getAmount();
|
||||
|
||||
a.clear();
|
||||
b.clear();
|
||||
|
||||
if (a.canInsert(bItem, bAmount) && b.canInsert(aItem, aAmount)) {
|
||||
a.setContents(bItem, bAmount);
|
||||
b.setContents(aItem, aAmount);
|
||||
return true;
|
||||
} else {
|
||||
a.setContents(aItem, aAmount);
|
||||
b.setContents(bItem, bAmount);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Items() {
|
||||
}
|
||||
|
||||
}
|
@ -65,7 +65,8 @@ public class PlayerManager {
|
||||
|
||||
player.getInventory().addSlots(10);
|
||||
|
||||
player.getInventory().getSlot(3).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"), 5);
|
||||
player.getInventory().getSlot(3).setContents(ItemDataRegistry.getInstance().create("Test:Stick"), 5);
|
||||
player.getInventory().getSlot(5).setContents(ItemDataRegistry.getInstance().create("Test:Stick"), 4);
|
||||
player.getInventory().getSlot(6).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"), 1);
|
||||
|
||||
player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation());
|
||||
|
@ -244,6 +244,7 @@ public class TestContent {
|
||||
|
||||
private static void registerItems() {
|
||||
registerSimplestItem("MoonTypeIceCream", Units.get("200 g"), Units.get("1 L"));
|
||||
registerSimplestItem("Stick", Units.get("260 g"), Units.get("0.5 L"));
|
||||
}
|
||||
|
||||
private static void registerSimplestBlock(String name) {
|
||||
|
@ -18,6 +18,7 @@
|
||||
package ru.windcorp.progressia.test.inv;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
@ -33,11 +34,13 @@ import ru.windcorp.progressia.client.graphics.gui.Layout;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Panel;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill;
|
||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||
import ru.windcorp.progressia.client.graphics.input.bus.InputListener;
|
||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||
import ru.windcorp.progressia.common.world.item.ItemContainer;
|
||||
import ru.windcorp.progressia.common.world.item.ItemData;
|
||||
import ru.windcorp.progressia.common.world.item.ItemSlot;
|
||||
import ru.windcorp.progressia.common.world.item.Items;
|
||||
|
||||
public class InventoryScreen extends Component {
|
||||
|
||||
@ -131,34 +134,72 @@ public class InventoryScreen extends Component {
|
||||
}
|
||||
|
||||
private void addListeners(InventoryComponent mainInventory) {
|
||||
Consumer<BasicButton> pickIntoLeft = createPickAction(leftHand.getSlot(0), rightHand.getSlot(0));
|
||||
|
||||
for (DecoratedSlotComponent component : mainInventory.getSlots()) {
|
||||
component.addAction(pickIntoLeft);
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<BasicButton> createPickAction(ItemSlot toWithoutCtrl, ItemSlot toWithCtrl) {
|
||||
return button -> {
|
||||
ItemSlot left = leftHand.getSlot(0);
|
||||
ItemSlot right = rightHand.getSlot(0);
|
||||
|
||||
Supplier<ItemSlot> handSlot = () -> {
|
||||
boolean hasCtrl = InputTracker.isKeyPressed(GLFW.GLFW_KEY_LEFT_CONTROL)
|
||||
|| InputTracker.isKeyPressed(GLFW.GLFW_KEY_RIGHT_CONTROL);
|
||||
|
||||
ItemSlot to = hasCtrl ? toWithCtrl : toWithoutCtrl;
|
||||
ItemSlot from = ((DecoratedSlotComponent) button).getSlot();
|
||||
return hasCtrl ? left : right;
|
||||
};
|
||||
|
||||
ItemData fromData = from.getContents();
|
||||
int fromAmount = from.getAmount();
|
||||
Consumer<BasicButton> pickAll = createPickAllAction(handSlot);
|
||||
|
||||
ItemData toData = to.getContents();
|
||||
int toAmount = to.getAmount();
|
||||
for (DecoratedSlotComponent component : mainInventory.getSlots()) {
|
||||
component.addAction(pickAll);
|
||||
component.addListener(KeyEvent.class, createRMBAction(component.getSlot(), handSlot));
|
||||
}
|
||||
}
|
||||
|
||||
from.setContents(toData, toAmount);
|
||||
to.setContents(fromData, fromAmount);
|
||||
private Consumer<BasicButton> createPickAllAction(Supplier<ItemSlot> handSlotChooser) {
|
||||
return button -> {
|
||||
|
||||
ItemSlot handSlot = handSlotChooser.get();
|
||||
ItemSlot invSlot = ((DecoratedSlotComponent) button).getSlot();
|
||||
|
||||
if (Items.pour(handSlot, invSlot) == 0) {
|
||||
if (!Items.swap(handSlot, invSlot)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
requestReassembly();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private InputListener<KeyEvent> createRMBAction(ItemSlot invSlot, Supplier<ItemSlot> handSlotChooser) {
|
||||
return input -> {
|
||||
|
||||
if (input.isPress() && input.isRightMouseButton()) {
|
||||
ItemSlot handSlot = handSlotChooser.get();
|
||||
|
||||
boolean success = false;
|
||||
|
||||
if (handSlot.isEmpty()) {
|
||||
success = Items.pour(invSlot, handSlot, invSlot.getAmount() / 2) != 0;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
success = Items.pour(handSlot, invSlot, 1) != 0;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
success = Items.swap(handSlot, invSlot);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
requestReassembly();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
src/main/resources/assets/textures/items/Stick.png
Normal file
BIN
src/main/resources/assets/textures/items/Stick.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 775 B |
Reference in New Issue
Block a user