RuneHive-Game
Loading...
Searching...
No Matches
DefaultStore.java
Go to the documentation of this file.
1package com.runehive.content.store.impl;
2
3import com.runehive.content.store.*;
4import com.runehive.content.store.currency.CurrencyType;
5import com.runehive.game.task.TickableTask;
6import com.runehive.game.world.World;
7import com.runehive.game.world.entity.mob.player.Player;
8import com.runehive.game.world.entity.mob.player.PlayerRight;
9import com.runehive.game.world.items.Item;
10import com.runehive.game.world.items.containers.ItemContainer;
11import com.runehive.net.packet.out.*;
12
13import java.util.Arrays;
14import java.util.Objects;
15
16/**
17 * The default shop which are owned by the server.
18 *
19 * @author <a href="http://www.rune-server.org/members/stand+up/">Stand Up</a>
20 * @since 4-1-2017.
21 */
22public final class DefaultStore extends Store {
23
24 /** The items in this shop. */
25 public final StoreItem[] items;
26
27 /** The original item container this shop started with. */
29
30 /** Determines if this shop restocks. */
31 final boolean restock;
32
33 private final SellType sellType;
34
35 /** The shop restock task that will restock the shops. */
37
38 /** Creates a new {@link Store}. */
41 this.items = items;
42 this.restock = restock;
43 this.sellType = sellType;
44 this.original = new ItemContainer(items.length, ItemContainer.StackPolicy.ALWAYS);
45 this.original.setItems(items, false);
46 this.container.setItems(items, false);
47 Arrays.stream(items).filter(Objects::nonNull).forEach(item -> itemCache.put(item.getId(), item.getAmount()));
48 }
49
50 /** Determines if the items in the container need to be restocked. */
51 private boolean needsRestock() {
52 return container.stream().filter(Objects::nonNull).anyMatch(i -> !itemCache.containsKey(i.getId()) || (itemCache.containsKey(i.getId()) && i.getAmount() < itemCache.get(i.getId())));
53 }
54
55 /** Determines if the items in the container no longer need to be restocked. */
56 boolean restockCompleted() {
57 return container.stream().filter(Objects::nonNull).allMatch(i -> {
58 if (itemCache.containsKey(i.getId()) && i.getAmount() >= itemCache.get(i.getId())) {//shop item.
59 return true;
60 } else if (!itemCache.containsKey(i.getId())) {//unique item.
61 return false;
62 }
63 return false;
64 });
65 }
66
67 @Override
68 public void itemContainerAction(Player player, int id, int slot, int action, boolean purchase) {
69 switch (action) {
70 case 1:
71 if (purchase) {
72 this.sendPurchaseValue(player, slot);
73 } else {
74 this.sendSellValue(player, slot);
75 }
76 break;
77 case 5:
78 player.send(new SendInputAmount("Enter amount", 10, amount -> {
79 if (purchase) {
80 this.purchase(player, new Item(id, Integer.parseInt(amount)), slot);
81 } else {
82 this.sell(player, new Item(id, Integer.parseInt(amount)), slot, true);
83 }
84 }));
85 break;
86 default:
87 int amount = 0;
88
89 if (action == 2) {
90 amount = 1;
91 }
92 if (action == 3) {
93 amount = 10;
94 }
95 if (action == 4) {
96 amount = 100;
97 }
98
99 if (purchase) {
100 this.purchase(player, new Item(id, amount), slot);
101 } else {
102 this.sell(player, new Item(id, amount), slot, false);
103 }
104 break;
105 }
106 }
107
108 @Override
109 public void open(Player player) {
110 if (PlayerRight.isIronman(player)) {
111 if (Arrays.stream(StoreConstant.IRON_MAN_STORES).noneMatch(s -> s.equalsIgnoreCase(name))) {
112 player.send(new SendMessage("As an iron man you do not have access to this store!"));
113 return;
114 }
115 }
116
117 player.attributes.set("SHOP", name);
118
119 if (!STORES.containsKey(name)) {
120 STORES.put(name, this);
121 }
122
123 players.add(player);
124 player.inventory.refresh();
125 refresh(player);
126 player.send(new SendString(name, 47502));
128 }
129
130 @Override
131 public void close(Player player) {
132 players.remove(player);
133 player.attributes.remove("SHOP");
134 }
135
136 @Override
137 public void refresh(Player player) {
138 player.send(new SendString("Store size: " + items.length, 47507));
139 player.send(new SendString(CurrencyType.getValue(player, currencyType), 47508));
140
141 final Item[] items = container.toArray();
142
143 int lastItem = 0;
144 for (int i = 0; i < items.length; i++) {
145 Item item = items[i];
146
147 if (item == null) {
148 continue;
149 }
150
151 if (item instanceof StoreItem) {
152 StoreItem storeItem = (StoreItem) items[i];
153 player.send(new SendString(storeItem.getShopValue() + "," + storeItem.getShopCurrency(this).getId(), 47552 + i));
154 lastItem = i;
155 }
156 }
157
158 final int scrollBarSize = lastItem <= 32 ? 0 : (lastItem / 8) * 72;
159 player.send(new SendScrollbar(47550, scrollBarSize));
160 player.send(new SendItemOnInterface(3823, player.inventory.toArray()));
161 players.stream().filter(Objects::nonNull).forEach(p -> player.send(new SendItemOnInterface(47551, container.toArray())));
162 if (restock) {
163 if (restockTask != null && restockTask.isRunning()) {
164 return;
165 }
166 if (!needsRestock()) {
167 return;
168 }
169 restockTask = new StoreRestockTask(this);
171 }
172 }
173
174 @Override
175 public StoreType type() {
176 return StoreType.DEFAULT;
177 }
178
179 @Override
181 return sellType;
182 }
183
184
185 /** The task that will restock items in shop containers when needed. */
186 private static final class StoreRestockTask extends TickableTask {
187
188 /** The container that will be restocked. */
189 private final DefaultStore container;
190
191 /** Creates a new {@link StoreRestockTask}. */
193 super(false, 0);
194 this.container = container;
195 }
196
197 @Override
198 protected void tick() {
199 if (container.restockCompleted() || !container.restock) {
200 this.cancel();
201 return;
202 }
203
204 if (tick >= 15) {
205 final Item[] items = container.container.toArray();
206 boolean restocked = false;
207 for (Item item : items) {
208 if (item == null) {
209 continue;
210 }
211 if (item instanceof StoreItem) {
212 if (restock((StoreItem) item)) {
213 restocked = true;
214 }
215 }
216 }
217 if (restocked) {
218 for (Player player : container.players) {
219 if (player != null) {
220 player.send(new SendItemOnInterface(47551, container.container.toArray()));
221 }
222 }
223 }
224 tick = 0;
225 }
226
227 }
228
229 /** Attempts to restock {@code item} for the container. */
230 private boolean restock(StoreItem item) {
231 if (!item.canReduce()) {
232 return false;
233 }
234
235 final int reduceAmount = item.getAmount() > 100 ? (int) ((double) item.getAmount() * 0.05D) : 1;
236
237 // if the item is not an original item
238 if (!container.original.contains(item.getId())) {
239 if (item.getAmount() - 1 <= 0) {
240 container.container.remove(item);
241 } else {
242 item.decrementAmountBy(reduceAmount);
243 }
244 return true;
245 } else {
246 // the item is an original item
247 final boolean originalItem = container.itemCache.containsKey(item.getId());
248 final int originalAmount = container.itemCache.get(item.getId());
249 // increment the original item if its not fully stocked
250 if (originalItem && item.getAmount() < originalAmount) {
251 item.incrementAmount();
252 return true;
253 } else if (originalItem && item.getAmount() > originalAmount) { // decrement original item if its over stocked
254 item.decrementAmountBy(reduceAmount);
255 return true;
256 }
257 }
258 return false;
259 }
260 }
261}
Class to execute all constants for Shops.
static final String[] IRON_MAN_STORES
Allowed shops for Iron man accounts.
static final int INTERFACE_ID
The identification for the shop itemcontainer.
void sendPurchaseValue(Player player, int slot)
Definition Store.java:277
final String name
The name of this shop.
Definition Store.java:26
Store(String name, ItemContainer.StackPolicy policy, CurrencyType currencyType, int capacity)
Definition Store.java:40
final Set< Player > players
The set of players that are currently viewing this shop.
Definition Store.java:38
Map< Integer, Integer > itemCache
The map of cached shop item identifications and their amounts.
Definition Store.java:35
final void sell(Player player, Item item, int slot, boolean addX)
Definition Store.java:176
final void sendSellValue(Player player, int slot)
Definition Store.java:249
static Map< String, Store > STORES
A mapping of each shop by it's name.
Definition Store.java:23
final CurrencyType currencyType
The currency for this shop.
Definition Store.java:32
ItemContainer container
The current item container which contains the current items from this shop.
Definition Store.java:29
boolean purchase(Player player, Item item, int slot)
Definition Store.java:89
A simple wrapper class which holds extra attributes for the item object.
CurrencyType getShopCurrency(Store store)
The task that will restock items in shop containers when needed.
boolean restock(StoreItem item)
Attempts to restock item for the container.
final DefaultStore container
The container that will be restocked.
StoreRestockTask(DefaultStore container)
Creates a new StoreRestockTask.
final ItemContainer original
The original item container this shop started with.
final StoreItem[] items
The items in this shop.
DefaultStore(StoreItem[] items, String name, SellType sellType, boolean restock, CurrencyType currency)
Creates a new Store.
void itemContainerAction(Player player, int id, int slot, int action, boolean purchase)
boolean needsRestock()
Determines if the items in the container need to be restocked.
boolean restockCompleted()
Determines if the items in the container no longer need to be restocked.
final boolean restock
Determines if this shop restocks.
StoreRestockTask restockTask
The shop restock task that will restock the shops.
synchronized final void cancel()
Cancels all subsequent executions.
Definition Task.java:113
TickableTask(boolean instant, int delay)
Represents the game world.
Definition World.java:46
static void schedule(Task task)
Submits a new event.
Definition World.java:247
final GenericAttributes attributes
Definition Mob.java:95
void openInventory(int identification, int overlay)
Opens an inventory interface for the player.
This class represents a character controlled by a player.
Definition Player.java:125
The container class that represents an item that can be interacted with.
Definition Item.java:21
final int getId()
Gets the identification of this item.
Definition Item.java:324
final int getAmount()
Gets the quantity of this item.
Definition Item.java:342
final void decrementAmountBy(int amount)
Decrements the amount by amount @endiliteral.
Definition Item.java:302
final void incrementAmount()
Increments the amount by 1.
Definition Item.java:277
An abstraction game representing a group of Items.
final void setItems(Item[] items, boolean copy)
Sets the container of items to items.
final Item[] toArray()
Returns a shallow copy of the backing array.
void refresh()
Refreshes the players inventory.
The OutgoingPacket that sends a message to a Players chatbox in the client.
The OutgoingPacket that sends a string to a Players itemcontainer in the client.
public< K > void remove(K key)
Removes a generic attribute.
public< K, E > void set(K key, E attribute)
Sets a generic attribute.
Represents ways items can be sold in a shop.
Definition SellType.java:8
ANY
Can sell any items to the shop.
Definition SellType.java:23
The enumerated type whose elements represent constants that are used to differ between shops.
Definition StoreType.java:9
DEFAULT
The default shop which is commonly owned by the server.
The enumerated type whom holds all the currencies usable for a server.
static String getValue(Player player, CurrencyType currency)
static boolean isIronman(Player player)
Checks if the player is an ironman.
An enumerated type defining policies for stackable Items.
ALWAYS
The ALWAYS policy, items are always stacked regardless of their ItemDefinition table.