1package com.runehive.game.world.items.containers;
3import com.google.common.base.Preconditions;
4import com.runehive.game.world.entity.mob.player.Player;
5import com.runehive.game.world.items.Item;
6import com.runehive.game.world.items.ItemDefinition;
7import com.runehive.game.world.items.containers.pricechecker.PriceType;
8import com.runehive.net.packet.out.SendItemOnInterface;
11import java.util.function.Consumer;
12import java.util.stream.Stream;
13import java.util.stream.StreamSupport;
15import static com.google.common.base.Preconditions.checkArgument;
16import static com.google.common.base.Preconditions.checkState;
52 checkState(
index <
container.capacity,
"no more elements left to iterate");
60 public void remove() {
61 checkState(
lastIndex != -1,
"can only be called once after 'next'");
98 private final List<ItemContainerListener>
listeners =
new ArrayList<>();
131 Objects.requireNonNull(
action);
141 return Spliterators.spliterator(
items, Spliterator.ORDERED);
165 return add(item, -1,
true);
188 public boolean add(
int id,
int amount) {
189 return add(
new Item(
id, amount));
197 return add(item, preferredIndex,
refresh,
false);
211 public boolean add(
Item item,
int preferredIndex,
boolean refresh,
boolean stack) {
212 checkArgument(preferredIndex >= -1,
"invalid index identifier");
218 if (stackable && !stack) {
220 }
else if (preferredIndex != -1) {
221 preferredIndex =
items[preferredIndex] !=
null ? -1 : preferredIndex;
224 preferredIndex = preferredIndex == -1 ?
computeFreeIndex() : preferredIndex;
226 if (preferredIndex == -1) {
239 for (
int index = 0; index < until; index++) {
241 if (preferredIndex == -1) {
246 items[preferredIndex] = item;
262 if (
items.size() == 1) {
263 Optional<? extends Item> item =
items.stream().
264 filter(Objects::nonNull).
266 return item.isPresent() &&
add(item.get());
271 boolean added =
false;
277 if (
add(item, -1,
false)) {
317 public boolean remove(
Item item) {
318 return remove(item, -1,
true);
331 public boolean remove(
Item item,
int preferredIndex) {
332 return remove(item, preferredIndex,
true);
335 public boolean remove(
int id) {
336 return remove(
new Item(
id, 1));
339 public boolean remove(
int id,
int amount) {
340 return remove(
new Item(
id, amount));
343 public boolean remove(
Item item,
int preferredIndex,
boolean refresh) {
344 return remove(item, preferredIndex,
refresh,
true);
362 checkArgument(preferredIndex >= -1,
"invalid index identifier");
376 preferredIndex = preferredIndex == -1 ?
computeIndexForId(item.getId()) : preferredIndex;
378 if (preferredIndex != -1 &&
items[preferredIndex] ==
null) {
384 if (preferredIndex == -1) {
390 if (current.
getAmount() > item.getAmount()) {
396 items[preferredIndex] =
null;
403 until = (item.getAmount() > until) ? until : item.getAmount();
405 for (
int index = 0; index < until && index <
capacity; index++) {
407 if (preferredIndex < 0 || preferredIndex >=
capacity) {
409 }
else if (
items[preferredIndex] ==
null) {
411 }
else if (
items[preferredIndex].
getId() != item.getId()) {
414 if (preferredIndex == -1) {
422 items[preferredIndex] =
null;
438 if (
items.size() == 1) {
439 Optional<? extends Item> item =
items.stream().
440 filter(Objects::nonNull).
442 return item.isPresent() &&
remove(item.get());
446 boolean removed =
false;
452 if (
remove(item, -1,
false)) {
498 int price = item.getValue(type);
500 if (value >= Long.MAX_VALUE - price * item.getAmount()) {
501 return Long.MAX_VALUE;
504 value += price * item.getAmount();
516 for (
int index = 0; index <
capacity; index++) {
517 if (
items[index] ==
null) {
532 for (
int index = 0; index <
capacity; index++) {
551 if (item ==
null || item.getId() !=
id)
553 amount += item.getAmount();
581 if (oldItem ==
null || !oldItem.
matchesId(oldId))
606 if (oldItem ==
null || !oldItem.
matchesId(oldId))
646 boolean replaced =
false;
650 while (
replace(oldId, newId,
false)) {
669 for (
Item item : forItems) {
682 if ((existing.
getAmount() + item.getAmount()) <= 0) {
686 indexCount += item.getAmount();
715 container.
removeAll(Arrays.copyOf(
remove,
remove.length));
728 if (item !=
null &&
id == item.getId()) {
743 for (
int id : identifiers) {
759 for (
int id : identifiers) {
773 public final boolean contains(
int id,
int amount) {
775 if (item !=
null &&
id == item.getId()) {
776 amount -= item.getAmount();
777 if (amount <= 0)
return true;
844 public final void swap(
int oldIndex,
int newIndex) {
845 swap(
false, oldIndex, newIndex,
true);
865 public final void swap(
int oldIndex,
int newIndex,
boolean refresh) {
866 checkArgument(oldIndex >= 0 && oldIndex <
capacity,
"[swap] oldIndex out of range - [old=" + oldIndex +
", new=" + newIndex +
", refresh=" +
refresh +
", size=" +
size() +
", capacity=" +
capacity +
"]");
867 checkArgument(newIndex >= 0 && newIndex <
capacity,
"[swap] newIndex out of range - [old=" + oldIndex +
", new=" + newIndex +
", refresh=" +
refresh +
", size=" +
size() +
", capacity=" +
capacity +
"]");
872 items[oldIndex] = itemNew;
873 items[newIndex] = itemOld;
880 checkArgument(oldIndex >= 0 && oldIndex <
capacity,
"[insert] oldIndex out of range - [old=" + oldIndex +
", new=" + newIndex +
", refresh=" +
refresh +
", size=" +
size() +
", capacity=" +
capacity +
"]");
881 checkArgument(newIndex >= 0 && newIndex <
capacity,
"[insert] newIndex out of range - [old=" + oldIndex +
", new=" + newIndex +
", refresh=" +
refresh +
", size=" +
size() +
", capacity=" +
capacity +
"]");
883 if (newIndex > oldIndex) {
884 for (
int index = oldIndex; index < newIndex; index++) {
887 }
else if (oldIndex > newIndex) {
888 for (
int index = oldIndex; index > newIndex; index--) {
895 checkArgument(firstIndex >= 0 && firstIndex <
capacity,
"[transfer] firstIndex out of range - [first=" + firstIndex +
", second=" + secondIndex +
", refresh=" +
refresh +
"]");
896 checkArgument(secondIndex >= 0 && secondIndex < other.
capacity,
"[transfer] secondIndex out of range - [first=" + firstIndex +
", second=" + secondIndex +
", refresh=" +
refresh +
"]");
897 Item first =
get(firstIndex);
898 Item second = other.
get(secondIndex);
899 set(firstIndex, second,
true);
900 other.
set(secondIndex, first,
true);
914 newItems[newIndex++] = item;
930 for (
int i = 0; i <
items.length; i++) {
940 public final void set(
Item[] toSet) {
959 final List<Item>
items =
new ArrayList<>(
size());
982 weight += item.getWeight();
1008 if (index >= 0 && index <
items.length)
1009 return Optional.ofNullable(
items[index]);
1010 return Optional.empty();
1020 if (index >= 0 && index <
items.length)
1031 if (index >= 0 && index <
items.length)
1032 return items[index];
1043 if (
items[index] ==
null) {
1046 return items[index].getId();
1057 return stream().filter(i -> i !=
null &&
id == i.getId()).findFirst();
1069 return stream().filter(i -> i !=
null && item.
getId() == i.getId() && item.
getAmount() == i.getAmount()).findFirst();
1076 return retrieve(index).isPresent();
1093 this.listeners.forEach(container::addListener);
1104 Arrays.fill(
items,
null);
1150 listeners.forEach(evt -> evt.itemUpdated(
this, Optional.ofNullable(oldItem), Optional.ofNullable(newItem), index,
refresh, login));
1160 listeners.forEach(evt -> evt.bulkItemsUpdated(
this));
1170 listeners.forEach(evt -> evt.capacityExceeded(
this));
1196 return (
int) Arrays.stream(
items).filter(Objects::nonNull).count();
1222 for (
int i = 0; i <
items.length; i++) {
1223 if (
items[i] ==
null) {
This class represents a character controlled by a player.
void send(OutgoingPacket encoder)
The container class that represents an item that can be interacted with.
final void setAmount(int amount)
Sets the quantity of this item.
final int getId()
Gets the identification of this item.
Item createWithId(int newId)
Creates a new item with newId and the same amount as this instance.
final int getAmount()
Gets the quantity of this item.
Item copy()
A substitute for Object#clone() that creates another 'copy' of this instance.
Item createAndIncrement(int addAmount)
Creates a new item with amount + addAmount and the same identifier.
Item createWithAmount(int newAmount)
Creates a new item with newAmount and the same identifier as this instance.
boolean matchesId(int id)
Item createAndDecrement(int removeAmount)
Creates a new item with amount - removeAmount and the same identifier.
An Iterator implementation for this container.
ItemContainerIterator(ItemContainer container)
Creates a new ItemContainerIterator.
final ItemContainer container
The container instance to iterate over.
int index
The current index being iterated over.
int lastIndex
The last index that was iterated over.
boolean addAll(ItemContainer items)
Attempts to deposit items in bulk into this container.
final boolean containsAny(Item... items)
final Item[] toNonNullArray()
final void swap(boolean insert, int oldIndex, int newIndex, boolean refresh)
Swaps the Items on oldIndex and newIndex.
final Stream< Item > stream()
final void fireItemUpdatedEvent(Item oldItem, Item newItem, int index, boolean refresh)
Fires the ItemContainerListener.itemUpdated(ItemContainer, int) event.
double getWeight()
Gets the weight of the container.
ItemContainer(int capacity, StackPolicy policy, Item[] items)
Creates a new ItemContainer.
void setFiringEvents(boolean firingEvents)
Sets the value for firingEvents.
final int computeAmountForId(int id)
Computes the total quantity of the Items in this container with id.
final void forEach(Consumer<? super Item > action)
Iterates through all of the Items within this container and performs action on them,...
final boolean replace(int oldId, int newId, boolean refresh)
Replaces the first occurrence of the Item having the identifier oldId with newId.
final Item get(int index)
Gets the Item located on index.
Item[] items
The Items within this container.
final void fireBulkItemsUpdatedEvent()
Fires the ItemContainerListener.bulkItemsUpdated(ItemContainer) event.
boolean add(Item item)
Attempts to deposit item into this container.
final Iterator< Item > iterator()
final boolean replace(int oldId, int newId, int index, boolean refresh)
Replaces the first occurrence of the Item having the identifier oldId with newId.
boolean add(Item item, int preferredIndex, boolean refresh)
final int capacity
The capacity of this container.
boolean add(int id, int amount)
Attempts to deposit item into this container.
void refresh(Player player, int widget)
Sends the items on the itemcontainer.
final void transfer(int firstIndex, int secondIndex, ItemContainer other, boolean refresh)
boolean firingEvents
If events are currently being fired.
final int getId(int index)
Gets the item id located on index.
final void setItems(Item[] items)
final int computeIndexForId(int id)
Computes the first index found that id is in.
final void setItems(Item[] items, boolean copy)
Sets the container of items to items.
final void insert(int oldIndex, int newIndex, boolean refresh)
boolean add(Item item, boolean refresh, boolean stack)
final boolean hasCapacityFor(Item... item)
Determines if this container has the capacity for item.
boolean addAll(Item... items)
Attempts to deposit items in bulk into this container.
final boolean contains(Item item)
final Optional< Integer > computeIdForIndex(int index)
Computes the identifier of the Item on index.
ItemContainer(int capacity, StackPolicy policy)
Creates a new ItemContainer.
final void fireCapacityExceededEvent()
Fires the ItemContainerListener.capacityExceeded(ItemContainer) event.
final boolean addListener(ItemContainerListener listener)
Adds an ItemContainerListener to this container.
final List< ItemContainerListener > listeners
An ArrayList of ItemContainerListeners listening for various events.
int getSlotById(int id)
Gets a slot by id.
final Optional< Item > retrieve(int index)
Retrieves the item located on index.
final int computeIndexCount(Item... forItems)
Computes the amount of indexes required to hold items in this container.
boolean addAll(Collection<? extends Item > items)
Attempts to deposit items in bulk into this container.
final void swap(int oldIndex, int newIndex, boolean refresh)
final void fireItemUpdatedEvent(Item oldItem, Item newItem, int index, boolean refresh, boolean login)
Optional< Item > search(Item item)
Searches and returns the first item found with id and amount.
boolean contains(int id)
Determines if this container contains id.
boolean removeAll(ItemContainer items)
Attempts to withdraw items in bulk from this container.
final boolean indexOccupied(int index)
Returns true if index is occupied (non-null).
final boolean removeListener(ItemContainerListener listener)
Removes an ItemContainerListener from this container.
final boolean replaceAll(int oldId, int newId)
Replaces all occurrences of Items having the identifier oldId with newId.
boolean add(Item item, int slot)
Attempts to deposit item into this container.
Optional< Item > search(int id)
Searches and returns the first item found with id.
boolean add(Item item, int preferredIndex, boolean refresh, boolean stack)
Attempts to deposit item into this container, preferably at preferredIndex.
void shift()
Percolates the null indices to the end of the stack.
void clear()
Removes all of the items from this container.
final boolean replace(Item first, Item second, boolean refresh)
Replaces the first occurrence of the Item having the identifier oldId with newId.
final boolean containsAny(int... identifiers)
Determines if this container contains any identifiers.
final boolean indexFree(int index)
Returns true if index is not occupied (null).
final void ifPresent(int index, Consumer< Item > action)
Consumes an action if the index is a valid item index in this container.
void onRefresh()
Any functionality that should occur when refreshed.
final void set(Item[] toSet)
final StackPolicy policy
The policy of this container.
final int computeFreeIndex()
Computes the next free (null) index in this container.
boolean removeAll(Item... items)
Attempts to withdraw items in bulk from this container.
final Spliterator< Item > spliterator()
boolean removeAll(Collection<? extends Item > items)
Attempts to withdraw items in bulk from this container.
final ItemContainer copy()
Creates a copy of the underlying item container.
final boolean hasCapacityAfter(Item[] add, Item... remove)
Creates a copy of the underlying container and removes the items specified from it and after tries to...
final boolean containsAny(Collection< Item > items)
final boolean contains(int id, int amount)
final boolean containsAll(Collection< Item > items)
long containerValue(PriceType type)
Gets the total worth of the container using the item's values.
final void clear(boolean refresh)
Removes all of the items from this container.
final boolean containsAll(Item... items)
final boolean containsAll(int... identifiers)
Determines if this container contains all identifiers.
final Item[] toArray()
Returns a shallow copy of the backing array.
final StackPolicy policy()
final void swap(int oldIndex, int newIndex)
Swaps the Items on oldIndex and newIndex.
An enumerated type defining policies for stackable Items.
ALWAYS
The ALWAYS policy, items are always stacked regardless of their ItemDefinition table.
NEVER
The NEVER policy, items are never stacked regardless of their ItemDefinition table.
STANDARD
The STANDARD policy, items are only stacked if they are defined as stackable in their ItemDefinition ...
A listener that is fired by ItemContainer.