Guest User

Untitled

a guest
Oct 23rd, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.74 KB | None | 0 0
  1. package org.hyperion.rs2.model.container;
  2.  
  3. import java.util.Collection;
  4. import java.util.Collections;
  5. import java.util.LinkedList;
  6. import java.util.List;
  7.  
  8. import org.hyperion.rs2.Constants;
  9. import org.hyperion.rs2.model.Item;
  10.  
  11. /**
  12.  * A container holds a group of items.
  13.  *
  14.  * @author Graham Edgecombe
  15.  *
  16.  */
  17. public class Container {
  18.  
  19.     /**
  20.      * The type of container.
  21.      *
  22.      * @author Graham Edgecombe
  23.      *
  24.      */
  25.     public enum Type {
  26.  
  27.         /**
  28.          * A standard container such as inventory.
  29.          */
  30.         STANDARD,
  31.  
  32.         /**
  33.          * A container which always stacks, e.g. the bank, regardless of the
  34.          * item.
  35.          */
  36.         ALWAYS_STACK,
  37.  
  38.     }
  39.  
  40.     /**
  41.      * The capacity of this container.
  42.      */
  43.     private int capacity;
  44.  
  45.     /**
  46.      * The items in this container.
  47.      */
  48.     private Item[] items;
  49.  
  50.     /**
  51.      * A list of listeners.
  52.      */
  53.     private List<ContainerListener> listeners = new LinkedList<ContainerListener>();
  54.  
  55.     /**
  56.      * The container type.
  57.      */
  58.     private Type type;
  59.  
  60.     /**
  61.      * Firing events flag.
  62.      */
  63.     private boolean firingEvents = true;
  64.  
  65.     /**
  66.      * Creates the container with the specified capacity.
  67.      *
  68.      * @param type
  69.      *            The type of this container.
  70.      * @param capacity
  71.      *            The capacity of this container.
  72.      */
  73.     public Container(Type type, int capacity) {
  74.         this.type = type;
  75.         this.capacity = capacity;
  76.         this.items = new Item[capacity];
  77.     }
  78.  
  79.     /**
  80.      * Sets the firing events flag.
  81.      *
  82.      * @param firingEvents
  83.      *            The flag.
  84.      */
  85.     public void setFiringEvents(boolean firingEvents) {
  86.         this.firingEvents = firingEvents;
  87.     }
  88.  
  89.     /**
  90.      * Checks the firing events flag.
  91.      *
  92.      * @return <code>true</code> if events are fired, <code>false</code> if not.
  93.      */
  94.     public boolean isFiringEvents() {
  95.         return firingEvents;
  96.     }
  97.  
  98.     /**
  99.      * Gets the listeners of this container.
  100.      *
  101.      * @return The listeners of this container.
  102.      */
  103.     public Collection<ContainerListener> getListeners() {
  104.         return Collections.unmodifiableCollection(listeners);
  105.     }
  106.  
  107.     /**
  108.      * Adds a listener.
  109.      *
  110.      * @param listener
  111.      *            The listener to add.
  112.      */
  113.     public void addListener(ContainerListener listener) {
  114.         listeners.add(listener);
  115.         listener.itemsChanged(this);
  116.     }
  117.  
  118.     /**
  119.      * Removes a listener.
  120.      *
  121.      * @param listener
  122.      *            The listener to remove.
  123.      */
  124.     public void removeListener(ContainerListener listener) {
  125.         listeners.remove(listener);
  126.     }
  127.  
  128.     /**
  129.      * Removes all listeners.
  130.      */
  131.     public void removeAllListeners() {
  132.         listeners.clear();
  133.     }
  134.  
  135.     /**
  136.      * Shifts all items to the top left of the container leaving no gaps.
  137.      */
  138.     public void shift() {
  139.         Item[] old = items;
  140.         items = new Item[capacity];
  141.         int newIndex = 0;
  142.         for (int i = 0; i < items.length; i++) {
  143.             if (old[i] != null) {
  144.                 items[newIndex] = old[i];
  145.                 newIndex++;
  146.             }
  147.         }
  148.         if (firingEvents) {
  149.             fireItemsChanged();
  150.         }
  151.     }
  152.  
  153.     /**
  154.      * Gets the next free slot.
  155.      *
  156.      * @return The slot, or <code>-1</code> if there are no available slots.
  157.      */
  158.     public int freeSlot() {
  159.         for (int i = 0; i < items.length; i++) {
  160.             if (items[i] == null) {
  161.                 return i;
  162.             }
  163.         }
  164.         return -1;
  165.     }
  166.  
  167.     /**
  168.      * Attempts to add an item into the next free slot.
  169.      *
  170.      * @param item
  171.      *            The item.
  172.      * @return <code>true</code> if the item was added, <code>false</code> if
  173.      *         not.
  174.      */
  175.     public boolean add(Item item) {
  176.         if (item.getDefinition().isStackable() || type.equals(Type.ALWAYS_STACK)) {
  177.             for (int i = 0; i < items.length; i++) {
  178.                 if (items[i] != null && items[i].getId() == item.getId()) {
  179.                     int totalCount = item.getCount() + items[i].getCount();
  180.                     if (totalCount >= Constants.MAX_ITEMS || totalCount < 1) {
  181.                         return false;
  182.                     }
  183.                     set(i, new Item(items[i].getId(), items[i].getCount() + item.getCount()));
  184.                     return true;
  185.                 }
  186.             }
  187.             int slot = freeSlot();
  188.             if (slot == -1) {
  189.                 return false;
  190.             } else {
  191.                 set(slot, item);
  192.                 return true;
  193.             }
  194.         } else {
  195.             int slots = freeSlots();
  196.             if (slots >= item.getCount()) {
  197.                 boolean b = firingEvents;
  198.                 firingEvents = false;
  199.                 try {
  200.                     for (int i = 0; i < item.getCount(); i++) {
  201.                         set(freeSlot(), new Item(item.getId()));
  202.                     }
  203.                     if (b) {
  204.                         fireItemsChanged();
  205.                     }
  206.                     return true;
  207.                 } finally {
  208.                     firingEvents = b;
  209.                 }
  210.             } else {
  211.                 return false;
  212.             }
  213.         }
  214.     }
  215.  
  216.     /**
  217.      * Gets the number of free slots.
  218.      *
  219.      * @return The number of free slots.
  220.      */
  221.     public int freeSlots() {
  222.         return capacity - size();
  223.     }
  224.  
  225.     /**
  226.      * Gets an item.
  227.      *
  228.      * @param index
  229.      *            The position in the container.
  230.      * @return The item.
  231.      */
  232.     public Item get(int index) {
  233.         return items[index];
  234.     }
  235.  
  236.     /**
  237.      * Gets an item by id.
  238.      *
  239.      * @param id
  240.      *            The id.
  241.      * @return The item, or <code>null</code> if it could not be found.
  242.      */
  243.     public Item getById(int id) {
  244.         for (int i = 0; i < items.length; i++) {
  245.             if (items[i] == null) {
  246.                 continue;
  247.             }
  248.             if (items[i].getId() == id) {
  249.                 return items[i];
  250.             }
  251.         }
  252.         return null;
  253.     }
  254.  
  255.     /**
  256.      * Gets a slot by id.
  257.      *
  258.      * @param id
  259.      *            The id.
  260.      * @return The slot, or <code>-1</code> if it could not be found.
  261.      */
  262.     public int getSlotById(int id) {
  263.         for (int i = 0; i < items.length; i++) {
  264.             if (items[i] == null) {
  265.                 continue;
  266.             }
  267.             if (items[i].getId() == id) {
  268.                 return i;
  269.             }
  270.         }
  271.         return -1;
  272.     }
  273.  
  274.     /**
  275.      * Sets an item.
  276.      *
  277.      * @param index
  278.      *            The position in the container.
  279.      * @param item
  280.      *            The item.
  281.      */
  282.     public void set(int index, Item item) {
  283.         items[index] = item;
  284.         if (firingEvents) {
  285.             fireItemChanged(index);
  286.         }
  287.     }
  288.  
  289.     /**
  290.      * Gets the capacity of this container.
  291.      *
  292.      * @return The capacity of this container.
  293.      */
  294.     public int capacity() {
  295.         return capacity;
  296.     }
  297.  
  298.     /**
  299.      * Gets the size of this container.
  300.      *
  301.      * @return The size of this container.
  302.      */
  303.     public int size() {
  304.         int size = 0;
  305.         for (int i = 0; i < items.length; i++) {
  306.             if (items[i] != null) {
  307.                 size++;
  308.             }
  309.         }
  310.         return size;
  311.     }
  312.  
  313.     /**
  314.      * Clears this container.
  315.      */
  316.     public void clear() {
  317.         items = new Item[items.length];
  318.         if (firingEvents) {
  319.             fireItemsChanged();
  320.         }
  321.     }
  322.  
  323.     /**
  324.      * Returns an array representing this container.
  325.      *
  326.      * @return The array.
  327.      */
  328.     public Item[] toArray() {
  329.         return items;
  330.     }
  331.  
  332.     /**
  333.      * Checks if a slot is used.
  334.      *
  335.      * @param slot
  336.      *            The slot.
  337.      * @return <code>true</code> if an item is present, <code>false</code>
  338.      *         otherwise.
  339.      */
  340.     public boolean isSlotUsed(int slot) {
  341.         return items[slot] != null;
  342.     }
  343.  
  344.     /**
  345.      * Checks if a slot is free.
  346.      *
  347.      * @param slot
  348.      *            The slot.
  349.      * @return <code>true</code> if an item is not present, <code>false</code>
  350.      *         otherwise.
  351.      */
  352.     public boolean isSlotFree(int slot) {
  353.         return items[slot] == null;
  354.     }
  355.  
  356.     /**
  357.      * Removes an item.
  358.      *
  359.      * @param item
  360.      *            The item to remove.
  361.      * @return The number of items removed.
  362.      */
  363.     public int remove(Item item) {
  364.         return remove(-1, item);
  365.     }
  366.  
  367.     /**
  368.      * Removes an item.
  369.      *
  370.      * @param item
  371.      *            The item to remove.
  372.      * @param slot
  373.      *            The slot of the item.
  374.      * @return The number of items removed.
  375.      */
  376.     public int remove(Item item, int slot) {
  377.         return remove(slot, item);
  378.     }
  379.  
  380.     /**
  381.      * Removes an item.
  382.      *
  383.      * @param preferredSlot
  384.      *            The preferred slot.
  385.      * @param item
  386.      *            The item to remove.
  387.      * @return The number of items removed.
  388.      */
  389.     public int remove(int preferredSlot, Item item) {
  390.         int removed = 0;
  391.         if (item.getDefinition().isStackable() || type.equals(Type.ALWAYS_STACK)) {
  392.             int slot = getSlotById(item.getId());
  393.             Item stack = get(slot);
  394.             if (stack.getCount() > item.getCount()) {
  395.                 removed = item.getCount();
  396.                 set(slot, new Item(stack.getId(), stack.getCount() - item.getCount()));
  397.             } else {
  398.                 removed = stack.getCount();
  399.                 set(slot, null);
  400.             }
  401.         } else {
  402.             for (int i = 0; i < item.getCount(); i++) {
  403.                 int slot = getSlotById(item.getId());
  404.                 if (i == 0 && preferredSlot != -1) {
  405.                     Item inSlot = get(preferredSlot);
  406.                     if (inSlot.getId() == item.getId()) {
  407.                         slot = preferredSlot;
  408.                     }
  409.                 }
  410.                 if (slot != -1) {
  411.                     removed++;
  412.                     set(slot, null);
  413.                 } else {
  414.                     break;
  415.                 }
  416.             }
  417.         }
  418.         return removed;
  419.     }
  420.  
  421.     /**
  422.      * Transfers an item from one container to another.
  423.      *
  424.      * @param from
  425.      *            The container to transfer from.
  426.      * @param to
  427.      *            The container to transfer to.
  428.      * @param fromSlot
  429.      *            The slot in the original container.
  430.      * @param id
  431.      *            The item id.
  432.      * @return A flag indicating if the transfer was successful.
  433.      */
  434.     public static boolean transfer(Container from, Container to, int fromSlot, int id) {
  435.         Item fromItem = from.get(fromSlot);
  436.         if (fromItem == null || fromItem.getId() != id) {
  437.             return false;
  438.         }
  439.         if (to.add(fromItem)) {
  440.             from.set(fromSlot, null);
  441.             return true;
  442.         } else {
  443.             return false;
  444.         }
  445.     }
  446.  
  447.     /**
  448.      * Swaps two items.
  449.      *
  450.      * @param fromSlot
  451.      *            From slot.
  452.      * @param toSlot
  453.      *            To slot.
  454.      */
  455.     public void swap(int fromSlot, int toSlot) {
  456.         Item temp = get(fromSlot);
  457.         boolean b = firingEvents;
  458.         firingEvents = false;
  459.         try {
  460.             set(fromSlot, get(toSlot));
  461.             set(toSlot, temp);
  462.             if (b) {
  463.                 fireItemsChanged(new int[]{fromSlot, toSlot});
  464.             }
  465.         } finally {
  466.             firingEvents = b;
  467.         }
  468.     }
  469.  
  470.     /**
  471.      * Gets the total amount of an item, including the items in stacks.
  472.      *
  473.      * @param id
  474.      *            The id.
  475.      * @return The amount.
  476.      */
  477.     public int getCount(int id) {
  478.         int total = 0;
  479.         for (int i = 0; i < items.length; i++) {
  480.             if (items[i] != null) {
  481.                 if (items[i].getId() == id) {
  482.                     total += items[i].getCount();
  483.                 }
  484.             }
  485.         }
  486.         return total;
  487.     }
  488.  
  489.     /**
  490.      * Inserts an item.
  491.      *
  492.      * @param fromSlot
  493.      *            The old slot.
  494.      * @param toSlot
  495.      *            The new slot.
  496.      */
  497.     public void insert(int fromSlot, int toSlot) {
  498.         // we reset the item in the from slot
  499.         Item from = items[fromSlot];
  500.         if (from == null) {
  501.             return;
  502.         }
  503.         items[fromSlot] = null;
  504.         // find which direction to shift in
  505.         if (fromSlot > toSlot) {
  506.             int shiftFrom = toSlot;
  507.             int shiftTo = fromSlot;
  508.             for (int i = (toSlot + 1); i < fromSlot; i++) {
  509.                 if (items[i] == null) {
  510.                     shiftTo = i;
  511.                     break;
  512.                 }
  513.             }
  514.             Item[] slice = new Item[shiftTo - shiftFrom];
  515.             System.arraycopy(items, shiftFrom, slice, 0, slice.length);
  516.             System.arraycopy(slice, 0, items, shiftFrom + 1, slice.length);
  517.         } else {
  518.             int sliceStart = fromSlot + 1;
  519.             int sliceEnd = toSlot;
  520.             for (int i = (sliceEnd - 1); i >= sliceStart; i--) {
  521.                 if (items[i] == null) {
  522.                     sliceStart = i;
  523.                     break;
  524.                 }
  525.             }
  526.             Item[] slice = new Item[sliceEnd - sliceStart + 1];
  527.             System.arraycopy(items, sliceStart, slice, 0, slice.length);
  528.             System.arraycopy(slice, 0, items, sliceStart - 1, slice.length);
  529.         }
  530.         // now fill in the target slot
  531.         items[toSlot] = from;
  532.         if (firingEvents) {
  533.             fireItemsChanged();
  534.         }
  535.     }
  536.  
  537.     /**
  538.      * Fires an item changed event.
  539.      *
  540.      * @param slot
  541.      *            The slot that changed.
  542.      */
  543.     public void fireItemChanged(int slot) {
  544.         for (ContainerListener listener : listeners) {
  545.             listener.itemChanged(this, slot);
  546.         }
  547.     }
  548.  
  549.     /**
  550.      * Fires an items changed event.
  551.      */
  552.     public void fireItemsChanged() {
  553.         for (ContainerListener listener : listeners) {
  554.             listener.itemsChanged(this);
  555.         }
  556.     }
  557.  
  558.     /**
  559.      * Fires an items changed event.
  560.      *
  561.      * @param slots
  562.      *            The slots that changed.
  563.      */
  564.     public void fireItemsChanged(int[] slots) {
  565.         for (ContainerListener listener : listeners) {
  566.             listener.itemsChanged(this, slots);
  567.         }
  568.     }
  569.  
  570.     /**
  571.      * Checks if the container contains the specified item.
  572.      *
  573.      * @param id
  574.      *            The item id.
  575.      * @return <code>true</code> if so, <code>false</code> if not.
  576.      */
  577.     public boolean contains(int id) {
  578.         return getSlotById(id) != -1;
  579.     }
  580.  
  581.     /**
  582.      * Checks if there is room in the inventory for an item.
  583.      *
  584.      * @param item
  585.      *            The item.
  586.      * @return <code>true</code> if so, <code>false</code> if not.
  587.      */
  588.     public boolean hasRoomFor(Item item) {
  589.         if (item.getDefinition().isStackable() || type.equals(Type.ALWAYS_STACK)) {
  590.             for (int i = 0; i < items.length; i++) {
  591.                 if (items[i] != null && items[i].getId() == item.getId()) {
  592.                     int totalCount = item.getCount() + items[i].getCount();
  593.                     if (totalCount >= Constants.MAX_ITEMS || totalCount < 1) {
  594.                         return false;
  595.                     }
  596.                     return true;
  597.                 }
  598.             }
  599.             int slot = freeSlot();
  600.             return slot != -1;
  601.         } else {
  602.             int slots = freeSlots();
  603.             return slots >= item.getCount();
  604.         }
  605.  
  606.     }
  607.  
  608. }
Add Comment
Please, Sign In to add comment