RuneHive-Game
Loading...
Searching...
No Matches
PersonalStore.java
Go to the documentation of this file.
1package com.runehive.content.store.impl;
2
3import com.runehive.Config;
4import com.runehive.content.dialogue.DialogueFactory;
5import com.runehive.content.store.*;
6import com.runehive.content.store.currency.CurrencyType;
7import com.runehive.game.world.World;
8import com.runehive.game.world.entity.mob.player.Player;
9import com.runehive.game.world.items.Item;
10import com.runehive.game.world.items.containers.ItemContainer;
11import com.runehive.net.packet.out.*;
12import com.runehive.util.GameSaver;
13import com.runehive.util.MessageColor;
14import com.runehive.util.Utility;
15
16import java.util.*;
17
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 PersonalStore extends Store {
23
24 /** The shops the player is currently viewing. */
25 public static final Map<Integer, PersonalStore> FEATURED_SHOPS = new HashMap<>();
26
27 /** A mapping of a player name with the amount of coins waiting for him. */
28 public static Map<String, Long> SOLD_ITEMS = new HashMap<>();
29
30 /** The rank of this shop on the featured list. */
31 public final int rank;
32
33 /** The title of this shop. */
34 public String title;
35
36 /** The caption of this shop. */
37 public String caption;
38
39 /** The flag is the shop is being updated by the owner. */
40 private boolean updating = false;
41
42 /** Creates a new {@link Store}. */
43 public PersonalStore(String name, Optional<StoreItem[]> items, int rank, String title, String caption, CurrencyType currency) {
45 this.rank = rank;
46 this.title = title;
47 this.caption = caption;
48 items.ifPresent(i -> this.container.setItems(i, false));
49 }
50
51 public static void add(Player player, PersonalStore store) {
52 STORES.put(player.getName(), store);
53 }
54
55 /** Handles claiming coins from the personal store. */
56 public static void claimCoins(Player player) {
57// DialogueFactory factory = player.dialogueFactory;
58// if (!SOLD_ITEMS.containsKey(player.getName())) {
59// factory.sendItem("Personal Store", "There are no coins available for you to collect.", Config.CURRENCY).execute();
60// return;
61// }
62// long amount = SOLD_ITEMS.get(player.getName());
63// boolean added = player.bankVault.add(amount);
64// if (added) {
65// SOLD_ITEMS.remove(player.getName());
66// }
67// String message = added ? "Your collected coins have been sent to your bank vault." : "There was not enough room inside your bank vault to hold your coins.";
68// player.send(new SendMessage(message, MessageColor.DARK_GREEN));
69// openMenu(player);
70// factory.sendItem("Personal Store", message, Config.CURRENCY).execute();
71 }
72
73 public static void openMenu(Player player) {
74 if (player == null) {
75 return;
76 }
77
78 if (player.getName() == null) {
79 return;
80 }
81
82 long collect = SOLD_ITEMS.get(player.getName()) == null ? 0 : SOLD_ITEMS.get(player.getName());
83 player.send(new SendString("<col=d38537>Active stores:</col> " + getPersonalShops().size(), 38210));
84 player.send(new SendString("<col=d38537>Total Items Sold:</col> " + Utility.formatPrice(GameSaver.ITEMS_SOLD), 38211));
85 player.send(new SendString("<col=d38537>Total Sold Worth:</col> " + Utility.formatPrice(GameSaver.PERSONAL_ITEM_WORTH), 38213));
86
87 player.send(new SendString(collect <= 0 ? "None" : Utility.formatDigits(collect), 38207));
88 player.interfaceManager.open(38200);
89 }
90
91 /** Creates the player's shops if non-existent or will enter. */
92 public static void myShop(Player player) {
93 if (!Store.STORES.containsKey(player.getName())) {
94 PersonalStore shop = new PersonalStore(player.getName(), Optional.empty(), player.right.getCrown(), player.getName() + "'s Store", "No caption set", CurrencyType.COINS);
95 Store.STORES.put(player.getName(), shop);
96 }
97
98 STORES.get(player.getName()).open(player);
99 }
100
101 /** Changes the name of the shop. */
102 public static void changeName(Player player, String input, boolean caption) {
103 if (!Store.STORES.containsKey(player.getName())) {
104 player.send(new SendMessage("You do not have a store. Set it up by first opening it from the previous menu."));
105 return;
106 }
107
108 String type = caption ? "caption" : "title";
109 if (Arrays.stream(Config.BAD_STRINGS).anyMatch(b -> input.contains(b))) {
110 player.send(new SendMessage("You have entered an invalid shop " + type + "."));
111 player.interfaceManager.close();
112 return;
113 }
114
115 PersonalStore shop = (PersonalStore) Store.STORES.get(player.getName());
116 String context = Utility.formatName(input);
117
118 if (caption) {
119 shop.caption = context;
120 } else {
121 shop.title = context;
122 player.send(new SendString(shop.title, 40002));
123 }
124
125 player.send(new SendMessage("You have changed your shop " + type + " to: " + context + "."));
126 }
127
128 /** Handles editing the personal store. */
129 public static void edit(Player player) {
131 f.sendStatement("Loading your shop details...").sendOption("Change shop name", () -> {
132 f.onAction(() -> {
133 player.send(new SendInputMessage("Enter the name of your shop:", 30, input -> {
134 changeName(player, input, false);
135 }));
136 });
137 }, "Change caption", () -> {
138 f.onAction(() -> {
139 player.send(new SendInputMessage("Enter the caption of your shop:", 30, input -> {
140 changeName(player, input, true);
141 }));
142 });
143 }).execute();
144 }
145
146 /** Opens the panel where a player can search for shops. */
147 public static void openPanel(Player player) {
148 List<PersonalStore> personalShops = getPersonalShops();
149 int size = personalShops.size() < 10 ? 10 : personalShops.size();
150 for (int string = 53031, index = 0; index < size; index++) {
151 PersonalStore shop = index >= personalShops.size() ? null : personalShops.get(index);
152 String tooltip = shop == null ? "" : "View <col=ffb000>" + shop.name + "<col=FFFFFF>'s shop";
153 String name = shop == null ? "" : shop.name;
154 String caption = shop == null ? "" : shop.caption;
155 if (shop != null)
156 player.viewing_shops.put(-(12505 - (index * 3)), shop);
157 player.send(new SendTooltip(tooltip, string));
158 string++;
159 player.send(new SendString(name, string));
160 string++;
161 player.send(new SendString(caption, string));
162 string++;
163 }
164
165 List<PersonalStore> featured_shops = getFeaturedShops();
166 for (int index = 0, string = 53008; index < 10; index++, string++) {
167 PersonalStore shop = index >= featured_shops.size() ? null : featured_shops.get(index);
168 String name = shop == null ? "" : shop.name;
169 String tooltip = shop == null ? "" : "View <col=ffb000>" + shop.name + "<col=FFFFFF>'s shop";
170 if (shop != null)
171 FEATURED_SHOPS.put(-(12528 + index), shop);
172
173 player.send(new SendTooltip(tooltip, string));
174 player.send(new SendString(name, string));
175 }
176 player.send(new SendString("Available stores: " + personalShops.size(), 53023));
177 player.send(new SendScrollbar(53030, (size * 28)));
178 player.interfaceManager.open(53000);
179 }
180
181 /** Handles adding an item to the player's personal shop. */
182 public void add(Player player, Item item, int slot, boolean addX) {
184 return;
185 }
186 if (!item.isTradeable()) {
187 player.send(new SendMessage("You can not sell untradeable items in your shop!"));
188 return;
189 }
190 if (CurrencyType.isCurrency(item.getId())) {
191 player.send(new SendMessage("You can not sell any currency in your shop!"));
192 return;
193 }
194
195 Item invItem = player.inventory.get(slot);
196 final StoreItem storeItem = new StoreItem(invItem.getId(), item.getAmount());
197
198 if (!addX) {
199 player.send(new SendInputAmount("What do you want to value your <col=027399>" + item.getName() + "</col>?", 10, value -> {
200 setValue(player, invItem, storeItem, Integer.parseInt(value), slot);
201 refresh(player);
202 }));
203 return;
204 }
205
206 player.send(new SendInputAmount("How much would you like to put in your shop?", 10, amount -> {
207 storeItem.setAmount(Integer.parseInt(amount));
208 player.send(new SendInputAmount("What do you want to value your <col=027399>" + item.getName() + "</col>?", 10, value -> {
209 setValue(player, invItem, storeItem, Integer.parseInt(value), slot);
210 refresh(player);
211 }));
212 }));
213 }
214
215 private void setValue(Player player, Item invItem, StoreItem storeItem, int value, int slot) {
217 return;
218 }
219 storeItem.setShopValue(value);
220 int amount = player.inventory.computeAmountForId(invItem.getId());
221
222 if (storeItem.getAmount() > amount && !storeItem.isStackable()) {
223 storeItem.setAmount(amount);
224 } else if (storeItem.getAmount() > player.inventory.get(slot).getAmount() && storeItem.isStackable()) {
225 storeItem.setAmount(player.inventory.get(slot).getAmount());
226 }
227
228 player.inventory.remove(storeItem, slot);
229 Optional<Item> contains = container.stream().filter(i -> i != null && storeItem.getId() == i.getId() && ((StoreItem) i).getShopValue() == storeItem.getShopValue()).findFirst();
230
231 if (contains.isPresent()) {
232 contains.get().incrementAmountBy(storeItem.getAmount());
233 } else {
234 if (!storeItem.isStackable() && storeItem.getAmount() > 1) {
235 container.add(storeItem, false, true);
236 } else {
237 container.add(storeItem);
238 }
239 }
240 }
241
242 /** Handles adding an item to the player's personal shop. */
243 public void remove(Player player, Item item, int slot) {
244 if (!player.interfaceManager.isInterfaceOpen(StoreConstant.INTERFACE_ID)) {
245 return;
246 }
247 final StoreItem storeItem = (StoreItem) this.container.retrieve(slot).orElse(null);
248
249 if (storeItem == null)
250 return;
251
252 if (item.getAmount() > storeItem.getAmount())
253 item.setAmount(storeItem.getAmount());
254 if (!player.inventory.hasCapacityFor(item)) {
255 item.setAmount(player.inventory.remaining());
256 if (item.getAmount() == 0) {
257 player.send(new SendMessage("You do not have enough space in your inventory to withdraw this item!"));
258 return;
259 }
260 }
261
262 if (player.inventory.remaining() >= item.getAmount() && !item.isStackable() || player.inventory.remaining() >= 1 && item.isStackable() || player.inventory.contains(item.getId()) && item.isStackable()) {
263 if ((storeItem.getAmount() - item.getAmount()) < 1) {
264 container.remove(item, slot, false, false);
265 container.shift();
266 } else {
267 storeItem.decrementAmountBy(item.getAmount());
268 }
269 player.inventory.add(item);
270 } else {
271 player.send(new SendMessage("You don't have enough space in your inventory."));
272 return;
273 }
274 refresh(player);
275 }
276
277 /** Modifies the player's shop item. */
278 private void modify(Player player, int slot) {
280 return;
281 }
282 DialogueFactory factory = player.dialogueFactory;
283 StoreItem item = (StoreItem) container.retrieve(slot).orElse(null);
284 if (item == null)
285 return;
286 updating = true;
287 factory.sendOption(
288 "Change value",
289 () -> factory.onAction(() -> player.send(new SendInputAmount("Enter new value", 10, input -> {
290 item.setShopValue(Integer.parseInt(input));
291 player.send(new SendMessage("You've changed " + item.getName() + "'s value to " + Utility.formatDigits(Integer.parseInt(input)) + " " + item.getShopCurrency(this)));
292 refresh(player);
293 player.dialogueFactory.clear();
294 updating = false;
295 }))),
296
297 "Change currency",
298 () -> factory.onAction(() -> updating = false),
299
300 "Nevermind",
301 () -> factory.onAction(() -> {
302 updating = false;
303 player.dialogueFactory.clear();
304 })).execute();
305 }
306
307 /** Checks if the player is the owner of the shop. */
308 private boolean isOwner(Player player) {
309 return this.name.equals(player.getName());
310 }
311
312 @Override
313 public void itemContainerAction(Player player, int id, int slot, int action, boolean purchase) {
314 switch (action) {
315 case 1:
316 if (purchase) {
317 if (this.isOwner(player)) {
318 this.modify(player, slot);
319 } else {
320 this.sendPurchaseValue(player, slot);
321 }
322 } else {
323 if (this.isOwner(player)) {
324 this.add(player, new Item(id, 1), slot, false);
325 }
326 }
327 break;
328 default:
329 int count = purchase ? this.container.retrieve(slot).orElse(null).getAmount() : player.inventory.retrieve(slot).orElse(null).getAmount();
330 int amount = action == 2 ? (purchase ? 1 : 5) : action == 3 ? 10 : action == 4 ? count : -100;
331
332 if (purchase) {
333 if (this.isOwner(player)) {
334 this.remove(player, new Item(id, amount), slot);
335 } else {
336 if (updating) {
337 player.send(new SendMessage("The owner is currently updating the shop, try again in a few seconds.", MessageColor.RED));
338 return;
339 }
340 this.purchase(player, new Item(id, amount), slot);
341 }
342 } else {
343 if (this.isOwner(player)) {
344 this.add(player, new Item(id, amount), slot, amount == -100);
345 }
346 }
347 break;
348 }
349 }
350
351 @Override
352 public void onPurchase(Player player, Item item) {
353 if (!SOLD_ITEMS.containsKey(name))
354 SOLD_ITEMS.put(name, 0L);
355
356 long amount = SOLD_ITEMS.get(name);
357 SOLD_ITEMS.replace(name, amount + item.getAmount());
360 World.search(name).ifPresent(p -> p.send(new SendMessage("You have coins to collect from your shop!", MessageColor.DARK_GREEN)));
361 }
362
363 @Override
364 public void refresh(Player player) {
365 for (Player p : players) {
366 if (p != null) {
367 open(p);
368 if (p != player)
369 p.send(new SendMessage("[" + title + "] The shop has been updated!"));
370 }
371 }
372 }
373
374 @Override
375 public void open(Player player) {
376 player.attributes.set("SHOP", name);
377 players.add(player);
378 StoreItem[] items = (StoreItem[]) this.container.getItems();
379
380 int lastItem = 0;
381 if (items.length != 0) {
382 for (int i = 0; i < items.length; i++) {
383 player.send(new SendString(items[i] == null ? "0" : items[i].getShopValue() + "," + 0, 40052 + i));
384 lastItem = i;
385 }
386 }
387 final int scrollBarSize = lastItem <= 32 ? 0 : (lastItem / 8) * 72;
388 player.send(new SendScrollbar(40050, scrollBarSize));
389 player.send(new SendString(title, 40002));
390 player.send(new SendItemOnInterface(40051, items));
391 player.send(new SendItemOnInterface(3823, player.inventory.toArray()));
392 player.send(new SendString("Store size: " + items.length, 40007));
394 }
395
396 @Override
397 public void close(Player player) {
398 players.remove(player);
399 player.attributes.remove("SHOP");
400 player.viewing_shops.clear();
401 }
402
403 @Override
404 public StoreType type() {
405 return StoreType.PERSONAL;
406 }
407
408 @Override
410 return SellType.NONE;
411 }
412}
The class that contains setting-related constants for the server.
Definition Config.java:24
static final String[] BAD_STRINGS
Strings that are classified as bad.
Definition Config.java:216
Represents a factory class that contains important functions for building dialogues.
final DialogueFactory execute()
Retrieves the next dialogue in the chain and executes it.
void clear()
Clears the current dialogue chain.
final DialogueFactory onAction(Runnable action)
Sets an action so this action can be executed after dialogues are done.
final DialogueFactory sendStatement(String... lines)
Appends a StatementDialogue to the current dialogue chain.
final DialogueFactory sendOption(String option1, Runnable action1, String option2, Runnable action2)
Appends the OptionDialogue onto the current dialogue chain.
Class to execute all constants for Shops.
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
static List< PersonalStore > getFeaturedShops()
Definition Store.java:81
static List< PersonalStore > getPersonalShops()
Definition Store.java:75
static Map< String, Store > STORES
A mapping of each shop by it's name.
Definition Store.java:23
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)
static void openPanel(Player player)
Opens the panel where a player can search for shops.
static Map< String, Long > SOLD_ITEMS
A mapping of a player name with the amount of coins waiting for him.
PersonalStore(String name, Optional< StoreItem[]> items, int rank, String title, String caption, CurrencyType currency)
Creates a new Store.
void add(Player player, Item item, int slot, boolean addX)
Handles adding an item to the player's personal shop.
static void changeName(Player player, String input, boolean caption)
Changes the name of the shop.
static void add(Player player, PersonalStore store)
final int rank
The rank of this shop on the featured list.
void modify(Player player, int slot)
Modifies the player's shop item.
static void myShop(Player player)
Creates the player's shops if non-existent or will enter.
static void claimCoins(Player player)
Handles claiming coins from the personal store.
void itemContainerAction(Player player, int id, int slot, int action, boolean purchase)
static void edit(Player player)
Handles editing the personal store.
String caption
The caption of this shop.
void onPurchase(Player player, Item item)
boolean isOwner(Player player)
Checks if the player is the owner of the shop.
static final Map< Integer, PersonalStore > FEATURED_SHOPS
The shops the player is currently viewing.
void setValue(Player player, Item invItem, StoreItem storeItem, int value, int slot)
boolean updating
The flag is the shop is being updated by the owner.
Represents the game world.
Definition World.java:46
static Optional< Player > search(String name)
Gets a player by name.
Definition World.java:147
final GenericAttributes attributes
Definition Mob.java:95
boolean isInterfaceOpen(int id)
Checks if a certain interface is enter.
void openInventory(int identification, int overlay)
Opens an inventory interface for the player.
void open(int identification)
Opens an interface for the player.
This class represents a character controlled by a player.
Definition Player.java:125
String getName()
Gets the name of this entity.
Definition Player.java:774
final Map< Integer, PersonalStore > viewing_shops
Definition Player.java:319
The container class that represents an item that can be interacted with.
Definition Item.java:21
final void setAmount(int amount)
Sets the quantity of this item.
Definition Item.java:351
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
int getValue(PriceType type)
Gets the value for this item.
Definition Item.java:98
final void decrementAmountBy(int amount)
Decrements the amount by amount @endiliteral.
Definition Item.java:302
An abstraction game representing a group of Items.
final int computeAmountForId(int id)
Computes the total quantity of the Items in this container with id.
boolean remove(Item item)
Attempts to withdraw item from this container.
final Item get(int index)
Gets the Item located on index.
final Optional< Item > retrieve(int index)
Retrieves the item located on index.
final Item[] toArray()
Returns a shallow copy of the backing array.
Sends a chatbox input prompt that accepts full text with spaces.
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.
Created by Daniel on 2017-11-05.
Handles miscellaneous methods.
Definition Utility.java:27
static String formatName(final String input)
Definition Utility.java:645
static String formatDigits(final int amount)
Formats digits for integers.
Definition Utility.java:41
static String formatPrice(final long amount)
Formats a price for longs.
Definition Utility.java:56
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
NONE
No items can be sold in the shop.
Definition SellType.java:13
The enumerated type whose elements represent constants that are used to differ between shops.
Definition StoreType.java:9
PERSONAL
The personal shop which is commonly owned by players.
The enumerated type whom holds all the currencies usable for a server.
static String getCrown(Player player)
Gets the crown display.
An enumerated type defining policies for stackable Items.
STANDARD
The STANDARD policy, items are only stacked if they are defined as stackable in their ItemDefinition ...
Holds an enum of colors for ease.