diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/CursorHUD.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/CursorHUD.java index fc9e446..c581909 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/CursorHUD.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/CursorHUD.java @@ -28,7 +28,7 @@ import ru.windcorp.progressia.client.world.entity.SpeciesRender; import ru.windcorp.progressia.client.world.entity.SpeciesRenderRegistry; import ru.windcorp.progressia.common.world.entity.EntityDataPlayer; import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand; -import ru.windcorp.progressia.common.world.item.ItemContainerHand; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerHand; public class CursorHUD extends Component { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDManager.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDManager.java index 20437d6..73fae80 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDManager.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDManager.java @@ -28,8 +28,8 @@ import ru.windcorp.progressia.client.world.item.inventory.InventoryRender; import ru.windcorp.progressia.client.world.item.inventory.InventoryRenderRegistry; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.item.inventory.Inventory; -import ru.windcorp.progressia.common.world.item.inventory.InventoryClosingEvent; -import ru.windcorp.progressia.common.world.item.inventory.InventoryOpenedEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryClosingEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryOpenedEvent; public class HUDManager implements HUDWorkspace { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDWorkspace.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDWorkspace.java index 466af63..afc9a94 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDWorkspace.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/HUDWorkspace.java @@ -21,7 +21,7 @@ import ru.windcorp.progressia.client.Client; import ru.windcorp.progressia.client.graphics.world.LocalPlayer; import ru.windcorp.progressia.client.world.item.inventory.InventoryComponent; import ru.windcorp.progressia.common.world.entity.EntityDataPlayer; -import ru.windcorp.progressia.common.world.item.ItemContainerHand; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerHand; public interface HUDWorkspace { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/InteractiveSlotComponent.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/InteractiveSlotComponent.java index eba3dc4..bdf87d0 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/InteractiveSlotComponent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/InteractiveSlotComponent.java @@ -24,47 +24,48 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill; import ru.windcorp.progressia.client.graphics.input.KeyMatcher; import ru.windcorp.progressia.client.graphics.input.WheelScrollEvent; import ru.windcorp.progressia.common.Units; -import ru.windcorp.progressia.common.world.item.ItemContainer; import ru.windcorp.progressia.common.world.item.ItemDataContainer; -import ru.windcorp.progressia.common.world.item.ItemSlot; import ru.windcorp.progressia.common.world.item.Items; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerMixed; +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; public class InteractiveSlotComponent extends Button { private static final double MIN_PICK_ALL_DELAY = Units.get("0.5 s"); private double lastMainAction = Double.NEGATIVE_INFINITY; - + private final SlotComponent slotComponent; private final HUDWorkspace workspace; public InteractiveSlotComponent(String name, ItemContainer container, int index, HUDWorkspace workspace) { this(name, new SlotComponent(name, container, index), workspace); } - + public InteractiveSlotComponent(SlotComponent component, HUDWorkspace workspace) { this(component.getName() + ".Interactive", component, workspace); } - + public InteractiveSlotComponent(String name, SlotComponent component, HUDWorkspace workspace) { super(name, null, null); this.slotComponent = component; this.workspace = workspace; - + Vec2i size = slotComponent.getPreferredSize().add(2 * BORDER); setPreferredSize(size); - + addChild(this.slotComponent); setLayout(new LayoutFill(MARGIN)); - + addListeners(); } private void addListeners() { addAction(button -> onMainAction()); - + addListener(KeyMatcher.ofRightMouseButton(), this::onAltAction); - + addListener(WheelScrollEvent.class, event -> { if (event.hasVerticalMovement()) { onSingleMoveAction(event.isDown()); @@ -73,10 +74,13 @@ public class InteractiveSlotComponent extends Button { return false; }); } - + private void onMainAction() { ItemSlot handSlot = workspace.getHand().slot(); - ItemSlot invSlot = getSlot(); + ItemSlot invSlot = getSlotOrAllocate(); + if (invSlot == null) { + return; + } boolean success = false; @@ -104,6 +108,8 @@ public class InteractiveSlotComponent extends Button { if (success) { requestReassembly(); } + + cleanContainerUpIfNecessary(); } private void pickAll(ItemSlot handSlot) { @@ -114,13 +120,16 @@ public class InteractiveSlotComponent extends Button { } } } - + private void onAltAction() { ItemSlot handSlot = workspace.getHand().slot(); - ItemSlot invSlot = getSlot(); - - boolean success = false; + ItemSlot invSlot = getSlotOrAllocate(); + if (invSlot == null) { + return; + } + boolean success = false; + if (handSlot.isEmpty()) { success = tryToOpen(invSlot); } @@ -140,6 +149,8 @@ public class InteractiveSlotComponent extends Button { if (success) { requestReassembly(); } + + cleanContainerUpIfNecessary(); } private boolean tryToOpen(ItemSlot invSlot) { @@ -149,7 +160,7 @@ public class InteractiveSlotComponent extends Button { if (!(invSlot.getContents() instanceof ItemDataContainer)) { return false; } - + ItemDataContainer item = (ItemDataContainer) invSlot.getContents(); return item.open(workspace.getPlayerEntity()) != null; } @@ -170,4 +181,38 @@ public class InteractiveSlotComponent extends Button { return slotComponent.getSlot(); } + private ItemSlot getSlotOrAllocate() { + ItemSlot slot = slotComponent.getSlot(); + + if (slot == null) { + + int slotIndex = slotComponent.getSlotIndex(); + ItemContainer uncastContainer = slotComponent.getSlotContainer(); + + assert slotIndex >= 0 : "Slot index is negative: " + slotIndex; + assert slotIndex >= uncastContainer.getSlotCount() + : "Slot index is valid (" + slotIndex + ") but container does not provide a slot"; + + if (uncastContainer instanceof ItemContainerMixed) { + ItemContainerMixed container = (ItemContainerMixed) uncastContainer; + container.addSlots(slotIndex - container.getSlotCount() + 1); + + slot = slotComponent.getSlot(); + assert slot != null : "Could not allocate slot for index " + slotIndex; + } else { + // Leave slot null + } + + } + + return slot; + } + + private void cleanContainerUpIfNecessary() { + ItemContainer container = slotComponent.getSlotContainer(); + if (container instanceof ItemContainerMixed) { + ((ItemContainerMixed) container).cleanUpSlots(); + } + } + } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/SlotComponent.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/SlotComponent.java index 772c1af..f3df4d1 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/SlotComponent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/hud/SlotComponent.java @@ -33,14 +33,20 @@ import ru.windcorp.progressia.client.graphics.model.Shapes.PgmBuilder; import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.world.item.ItemRenderRegistry; import ru.windcorp.progressia.client.world.item.ItemRenderable; -import ru.windcorp.progressia.common.world.item.ItemContainer; import ru.windcorp.progressia.common.world.item.ItemData; import ru.windcorp.progressia.common.world.item.ItemDataContainer; -import ru.windcorp.progressia.common.world.item.ItemSlot; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; public class SlotComponent extends Component { static final float TEXTURE_SIZE = 24; + + private static boolean drawVirtualSlots; + static { + String key = SlotComponent.class.getName() + ".drawVirtualSlots"; + drawVirtualSlots = Boolean.parseBoolean(System.getProperty(key, "true")); + } private static Renderable containerOpenDecoration = null; private static Renderable containerOpenableDecoration = null; @@ -84,6 +90,20 @@ public class SlotComponent extends Component { ).setSize(TEXTURE_SIZE + 2).setOrigin(-1, -1, 0).create(); } } + + /** + * @return the container + */ + public ItemContainer getSlotContainer() { + return container; + } + + /** + * @return the index + */ + public int getSlotIndex() { + return index; + } public ItemSlot getSlot() { return container.getSlot(index); @@ -121,7 +141,15 @@ public class SlotComponent extends Component { } private void updateItemRenderer() { - ItemData contents = getSlot().getContents(); + ItemData contents; + + ItemSlot slot = getSlot(); + + if (slot == null) { + contents = null; + } else { + contents = slot.getContents(); + } if (contents == null) { itemRenderer = null; @@ -132,7 +160,7 @@ public class SlotComponent extends Component { itemRenderer = ItemRenderRegistry.getInstance().get(contents.getId()).createRenderable(contents); } - int newAmount = getSlot().getAmount(); + int newAmount = slot.getAmount(); if (newAmount != amountDisplayInt) { amountDisplayInt = newAmount; amountDisplayString = newAmount == 1 ? "" : Integer.toString(newAmount); @@ -145,6 +173,13 @@ public class SlotComponent extends Component { target.addCustomRenderer(renderer -> { updateItemRenderer(); + + if (drawVirtualSlots && getSlot() == null) { + renderer.pushColorMultiplier().set(Colors.DEBUG_GREEN); + containerOpenDecoration.render(renderer); + renderer.popColorMultiplier(); + return; + } if (itemRenderer != null) { itemRenderer.render(renderer); diff --git a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponent.java b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponent.java index a66a634..fc085cd 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponent.java +++ b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponent.java @@ -21,7 +21,7 @@ import java.util.Collection; import ru.windcorp.progressia.client.graphics.gui.Component; import ru.windcorp.progressia.client.graphics.world.hud.InteractiveSlotComponent; -import ru.windcorp.progressia.common.world.item.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; public abstract class ContainerComponent extends Component { diff --git a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponentSimple.java b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponentSimple.java index 4de4363..ed3daa3 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponentSimple.java +++ b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/ContainerComponentSimple.java @@ -20,6 +20,8 @@ package ru.windcorp.progressia.client.world.item.inventory; import java.util.ArrayList; import java.util.Collection; +import com.google.common.eventbus.Subscribe; + import glm.vec._2.i.Vec2i; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.gui.Component; @@ -30,7 +32,9 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutGrid; import ru.windcorp.progressia.client.graphics.world.hud.Bar; import ru.windcorp.progressia.client.graphics.world.hud.HUDWorkspace; import ru.windcorp.progressia.client.graphics.world.hud.InteractiveSlotComponent; -import ru.windcorp.progressia.common.world.item.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotAddedEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotRemovedEvent; public class ContainerComponentSimple extends ContainerComponent { @@ -42,6 +46,10 @@ public class ContainerComponentSimple extends ContainerComponent { public ContainerComponentSimple(ItemContainer container, HUDWorkspace workspace) { super("Inventory"); this.container = container; + + if (container.getInventory() != null) { + container.getInventory().subscribe(this); + } setLayout(new LayoutBorderHorizontal(15)); @@ -94,5 +102,15 @@ public class ContainerComponentSimple extends ContainerComponent { public Collection getSlots() { return slotCollection; } + + @Subscribe + private void onSlotAdded(ItemSlotAddedEvent e) { + + } + + @Subscribe + private void onSlotAdded(ItemSlotRemovedEvent e) { + + } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/InventoryComponentSimple.java b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/InventoryComponentSimple.java index 6110e8e..2fbc3ba 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/item/inventory/InventoryComponentSimple.java +++ b/src/main/java/ru/windcorp/progressia/client/world/item/inventory/InventoryComponentSimple.java @@ -22,8 +22,8 @@ import java.util.Collection; import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill; import ru.windcorp.progressia.client.graphics.world.hud.HUDWorkspace; -import ru.windcorp.progressia.common.world.item.ItemContainer; import ru.windcorp.progressia.common.world.item.inventory.Inventory; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; public class InventoryComponentSimple extends InventoryComponent { diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataPlayer.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataPlayer.java index 9c282a6..28c6fea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataPlayer.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataPlayer.java @@ -23,11 +23,11 @@ import com.google.common.eventbus.Subscribe; import ru.windcorp.progressia.common.state.IntStateField; import ru.windcorp.progressia.common.state.ObjectStateField; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; -import ru.windcorp.progressia.common.world.item.ItemContainerEquipment; -import ru.windcorp.progressia.common.world.item.ItemContainerHand; -import ru.windcorp.progressia.common.world.item.inventory.InventoryClosingEvent; -import ru.windcorp.progressia.common.world.item.inventory.InventoryOpenedEvent; import ru.windcorp.progressia.common.world.item.inventory.InventoryUser; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerEquipment; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerHand; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryClosingEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryOpenedEvent; public class EntityDataPlayer extends EntityData implements InventoryUser { diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/SpeciesDatalet.java b/src/main/java/ru/windcorp/progressia/common/world/entity/SpeciesDatalet.java index 672f848..0ef1dbb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/SpeciesDatalet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/SpeciesDatalet.java @@ -25,8 +25,8 @@ import ru.windcorp.progressia.common.state.Encodable; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.world.entity.SpeciesData.EquipmentSlot; import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand; -import ru.windcorp.progressia.common.world.item.ItemContainerEquipment; -import ru.windcorp.progressia.common.world.item.ItemContainerHand; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerEquipment; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerHand; public class SpeciesDatalet implements Encodable { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataContainer.java b/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataContainer.java index adf7f83..71dde1a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataContainer.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataContainer.java @@ -20,6 +20,7 @@ package ru.windcorp.progressia.common.world.item; import ru.windcorp.progressia.common.state.ObjectStateField; import ru.windcorp.progressia.common.world.item.inventory.InventorySimple; import ru.windcorp.progressia.common.world.item.inventory.InventoryUser; +import ru.windcorp.progressia.common.world.item.inventory.ItemContainerMixedSimple; public class ItemDataContainer extends ItemData { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/Items.java b/src/main/java/ru/windcorp/progressia/common/world/item/Items.java index e8ab5c6..d6e8324 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/Items.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/Items.java @@ -17,6 +17,8 @@ */ package ru.windcorp.progressia.common.world.item; +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; + public class Items { /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/Inventory.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/Inventory.java index c997d2a..250233b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/Inventory.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/Inventory.java @@ -31,7 +31,8 @@ import ru.windcorp.progressia.common.state.Encodable; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.item.ItemContainer; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryClosingEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.InventoryOpenedEvent; public class Inventory extends Namespaced implements Encodable { @@ -77,6 +78,13 @@ public class Inventory extends Namespaced implements Encodable { eventBus.unregister(listener); } + /** + * @return the eventBus + */ + public EventBus getEventBus() { + return eventBus; + } + public synchronized boolean isUser(InventoryUser user) { return users.contains(user); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventorySimple.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventorySimple.java index 04e974f..f0e70c1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventorySimple.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventorySimple.java @@ -17,8 +17,6 @@ */ package ru.windcorp.progressia.common.world.item.inventory; -import ru.windcorp.progressia.common.world.item.ItemContainer; - public class InventorySimple extends Inventory { public InventorySimple(String id, ItemContainer container) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainer.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainer.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainer.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainer.java index b8daa2a..9255fdd 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainer.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import java.util.Iterator; import java.util.NoSuchElementException; @@ -23,7 +23,6 @@ import java.util.function.Consumer; import ru.windcorp.progressia.common.state.Encodable; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.item.inventory.Inventory; /** * A collection of {@link ItemSlot}s representing a single storage unit. A @@ -46,7 +45,7 @@ public abstract class ItemContainer extends Namespaced implements Encodable, Ite return inventory; } - public void setInventory(Inventory inventory) { + protected void setInventory(Inventory inventory) { this.inventory = inventory; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerEquipment.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerEquipment.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerEquipment.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerEquipment.java index 2328374..1b356d0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerEquipment.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerEquipment.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.world.entity.SpeciesData; diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerHand.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerHand.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerHand.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerHand.java index 33fb9aa..0671173 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerHand.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerHand.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.world.entity.SpeciesData; diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixed.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixed.java similarity index 65% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixed.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixed.java index 0f0a6c9..63881e2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixed.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixed.java @@ -15,16 +15,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.function.Consumer; +import com.google.common.eventbus.Subscribe; + import ru.windcorp.progressia.common.state.Encodable; import ru.windcorp.progressia.common.state.IOContext; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotAddedEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotChangedEvent; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotRemovedEvent; /** * An {@link ItemContainer} capable of storing multiple item stacks. The set @@ -32,18 +39,25 @@ import ru.windcorp.progressia.common.state.IOContext; * at will. */ public abstract class ItemContainerMixed extends ItemContainer { + + private final List slots = new ArrayList<>(); public ItemContainerMixed(String id) { super(id); } - - /** - * Retrieves the modifiable {@link List} of all slots. Edits commissioned - * through the returned object update the state of the container. - * - * @return a list view of this container - */ - protected abstract List getSlots(); + + @Override + protected void setInventory(Inventory inventory) { + if (getInventory() != null) { + getInventory().unsubscribe(this); + } + + super.setInventory(inventory); + + if (getInventory() != null) { + getInventory().subscribe(this); + } + } /** * Appends additional empty slots to the end of this container. @@ -51,12 +65,16 @@ public abstract class ItemContainerMixed extends ItemContainer { * @param amount the amount of slots to add */ public synchronized void addSlots(int amount) { - List slots = getSlots(); + Inventory inventory = getInventory(); for (int i = 0; i < amount; ++i) { ItemSlot slot = createSlot(slots.size()); slots.add(slot); slot.setContainer(this); + + if (inventory != null) { + inventory.getEventBus().post(new ItemSlotAddedEvent(slot)); + } } } @@ -68,24 +86,58 @@ public abstract class ItemContainerMixed extends ItemContainer { */ protected abstract ItemSlot createSlot(int index); + @Subscribe + private void onSlotChanged(ItemSlotChangedEvent e) { + cleanUpSlots(); + } + + public void cleanUpSlots() { + Inventory inventory = getInventory(); + Collection events = null; + + // Do not remove slot 0 + for (int i = slots.size() - 1; i > 0; --i) { + ItemSlot slot = slots.get(i); + if (slot.isEmpty()) { + slots.remove(i); + + if (inventory != null) { + if (events == null) { + events = new ArrayList<>(slots.size() - i); + } + events.add(new ItemSlotRemovedEvent(slot)); + } + } else { + break; + } + } + + if (events != null) { + // events != null only if inventory != null + events.forEach(inventory.getEventBus()::post); + } + } + @Override public ItemSlot getSlot(int index) { - return getSlots().get(index); + if (index < 0 || index >= slots.size()) { + return null; + } + return slots.get(index); } @Override public int getSlotCount() { - return getSlots().size(); + return slots.size(); } @Override public void forEach(Consumer action) { - getSlots().forEach(action); + slots.forEach(action); } @Override public synchronized void read(DataInput input, IOContext context) throws IOException { - List slots = getSlots(); synchronized (slots) { int needSlots = input.readInt(); @@ -99,7 +151,7 @@ public abstract class ItemContainerMixed extends ItemContainer { addSlots(needSlots); } else { while (slots.size() > needSlots) { - getSlots().remove(slots.size() - 1); + slots.remove(slots.size() - 1); } if (slots.size() < needSlots) { @@ -116,7 +168,6 @@ public abstract class ItemContainerMixed extends ItemContainer { @Override public synchronized void write(DataOutput output, IOContext context) throws IOException { - List slots = getSlots(); synchronized (slots) { output.writeInt(slots.size()); @@ -130,8 +181,8 @@ public abstract class ItemContainerMixed extends ItemContainer { @Override public void copy(Encodable destination) { ItemContainerMixed container = (ItemContainerMixed) destination; - List mySlots = this.getSlots(); - List containerSlots = container.getSlots(); + List mySlots = this.slots; + List containerSlots = container.slots; synchronized (mySlots) { synchronized (containerSlots) { @@ -147,7 +198,7 @@ public abstract class ItemContainerMixed extends ItemContainer { container.addSlots(needSlots); } else { while (containerSlots.size() > needSlots) { - getSlots().remove(containerSlots.size() - 1); + slots.remove(containerSlots.size() - 1); } if (containerSlots.size() < needSlots) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixedSimple.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixedSimple.java similarity index 85% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixedSimple.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixedSimple.java index 8853a76..7a3ef15 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerMixedSimple.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerMixedSimple.java @@ -15,15 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; - -import java.util.ArrayList; -import java.util.List; +package ru.windcorp.progressia.common.world.item.inventory; public class ItemContainerMixedSimple extends ItemContainerMixed { - private final List list; - private final float massLimit; private final float volumeLimit; @@ -33,17 +28,11 @@ public class ItemContainerMixedSimple extends ItemContainerMixed { public ItemContainerMixedSimple(String id, float massLimit, float volumeLimit, int startingSlots) { super(id); - this.list = new ArrayList<>(); this.massLimit = massLimit; this.volumeLimit = volumeLimit; addSlots(startingSlots); } - - @Override - protected List getSlots() { - return list; - } @Override public ItemSlot createSlot(int index) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerSingle.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerSingle.java similarity index 97% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerSingle.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerSingle.java index b8b430c..b8e95c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemContainerSingle.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemContainerSingle.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import java.io.DataInput; import java.io.DataOutput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemSlot.java similarity index 90% rename from src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemSlot.java index 662683f..47860ba 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/ItemSlot.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item; +package ru.windcorp.progressia.common.world.item.inventory; import java.io.DataInput; import java.io.DataOutput; @@ -23,6 +23,9 @@ import java.io.IOException; import ru.windcorp.progressia.common.state.Encodable; import ru.windcorp.progressia.common.state.IOContext; +import ru.windcorp.progressia.common.world.item.ItemData; +import ru.windcorp.progressia.common.world.item.ItemDataRegistry; +import ru.windcorp.progressia.common.world.item.inventory.event.ItemSlotChangedEvent; /** * An entity optionally containing an {@link ItemData}. Item slots are typically @@ -42,6 +45,10 @@ public class ItemSlot implements Encodable { return container; } + public Inventory getInventory() { + return getContainer().getInventory(); + } + /** * @param container the container to set */ @@ -76,6 +83,11 @@ public class ItemSlot implements Encodable { this.amount = amount; checkState(); + + Inventory inventory = getInventory(); + if (inventory != null) { + inventory.getEventBus().post(new ItemSlotChangedEvent(this)); + } } /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryClosingEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryClosingEvent.java similarity index 83% rename from src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryClosingEvent.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryClosingEvent.java index d0a49e0..2f4301d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryClosingEvent.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryClosingEvent.java @@ -15,7 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item.inventory; +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.Inventory; +import ru.windcorp.progressia.common.world.item.inventory.InventoryUser; public class InventoryClosingEvent extends InventoryEvent { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryEvent.java similarity index 87% rename from src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryEvent.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryEvent.java index dac07b0..47013c6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryEvent.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryEvent.java @@ -15,7 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item.inventory; +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.Inventory; public abstract class InventoryEvent { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryOpenedEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryOpenedEvent.java similarity index 83% rename from src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryOpenedEvent.java rename to src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryOpenedEvent.java index 92edec0..80bf112 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/InventoryOpenedEvent.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/InventoryOpenedEvent.java @@ -15,7 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.item.inventory; +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.Inventory; +import ru.windcorp.progressia.common.world.item.inventory.InventoryUser; public class InventoryOpenedEvent extends InventoryEvent { diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemContainerEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemContainerEvent.java new file mode 100644 index 0000000..ff4e677 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemContainerEvent.java @@ -0,0 +1,38 @@ +/* + * 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 . + */ +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.ItemContainer; + +public abstract class ItemContainerEvent extends InventoryEvent { + + private final ItemContainer container; + + public ItemContainerEvent(ItemContainer container) { + super(container.getInventory()); + this.container = container; + } + + /** + * @return the container + */ + public ItemContainer getContainer() { + return container; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotAddedEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotAddedEvent.java new file mode 100644 index 0000000..fa07ac6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotAddedEvent.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; + +public class ItemSlotAddedEvent extends ItemSlotEvent { + + public ItemSlotAddedEvent(ItemSlot slot) { + super(slot); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotChangedEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotChangedEvent.java new file mode 100644 index 0000000..9b34114 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotChangedEvent.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; + +public class ItemSlotChangedEvent extends ItemSlotEvent { + + public ItemSlotChangedEvent(ItemSlot slot) { + super(slot); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotEvent.java new file mode 100644 index 0000000..07521c6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotEvent.java @@ -0,0 +1,38 @@ +/* + * 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 . + */ +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; + +public abstract class ItemSlotEvent extends ItemContainerEvent { + + private final ItemSlot slot; + + public ItemSlotEvent(ItemSlot slot) { + super(slot.getContainer()); + this.slot = slot; + } + + /** + * @return the slot + */ + public ItemSlot getSlot() { + return slot; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotRemovedEvent.java b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotRemovedEvent.java new file mode 100644 index 0000000..cd2ead7 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/item/inventory/event/ItemSlotRemovedEvent.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package ru.windcorp.progressia.common.world.item.inventory.event; + +import ru.windcorp.progressia.common.world.item.inventory.ItemSlot; + +public class ItemSlotRemovedEvent extends ItemSlotEvent { + + public ItemSlotRemovedEvent(ItemSlot slot) { + super(slot); + } + +}