RuneHive-Game
Loading...
Searching...
No Matches
TradeSession.java
Go to the documentation of this file.
1package com.runehive.game.world.entity.mob.player.exchange.trade;
2
3import com.runehive.game.event.impl.log.TradeLogEvent;
4import com.runehive.game.world.InterfaceConstants;
5import com.runehive.game.world.World;
6import com.runehive.game.world.entity.mob.player.Player;
7import com.runehive.game.world.entity.mob.player.PlayerRight;
8import com.runehive.game.world.entity.mob.player.exchange.ExchangeCompletionType;
9import com.runehive.game.world.entity.mob.player.exchange.ExchangeSession;
10import com.runehive.game.world.entity.mob.player.exchange.ExchangeSessionType;
11import com.runehive.game.world.items.Item;
12import com.runehive.game.world.items.containers.pricechecker.PriceType;
13import com.runehive.net.packet.out.SendItemOnInterface;
14import com.runehive.net.packet.out.SendMessage;
15import com.runehive.net.packet.out.SendMinimapState;
16import com.runehive.net.packet.out.SendString;
17import com.runehive.util.MessageColor;
18import com.runehive.util.Stopwatch;
19import com.runehive.util.Utility;
20
21/**
22 * @author <a href="http://www.rune-server.org/members/stand+up/">Stand Up</a>
23 * @since 25-1-2017.
24 */
25public final class TradeSession extends ExchangeSession {
26
27 /**
28 * The stopwatch which blocks the player from further continueing the
29 * session if a second hasn't passed after the last item has been added.
30 */
32
33 /**
34 * Constructs a new {@link ExchangeSession}.
35 *
36 * @param player the player this exchange session is for.
37 * @param other the other player in this exchange session.
38 */
42
43 @Override
44 public boolean onRequest() {
45 if(player.playTime < 6000) {
46 player.send(new SendMessage("You must have over one hour of play time to trade."));
47 return false;
48 }
49 if(player.getUsername().contains("nicholas") || player.getUsername().contains("muntuna")) {
50 player.send(new SendMessage("You cannot trade as a " +player.getPlayer().right));
51 return false;
52 }
53 this.player.face(other.getPosition());
54 this.player.exchangeSession.requested_players.add(other);
55 if (!other.exchangeSession.requested_players.contains(player)) {
56 player.send(new SendMessage("Sending trade request..."));
57 other.send(new SendMessage(player.getName() + ":tradereq:", MessageColor.PURPLE));
58 return false;
59 }
60 SESSIONS.add(this);
61 this.forEach(p -> {
62 p.exchangeSession.resetRequests();
64 p.attributes.set("TRADE_KEY", true);
65 });
66 updateMainComponents("FIRST_SCREEN");
67 return true;
68 }
69
70 @Override
71 public boolean canAddItem(Player player, Item item, int slot) {
72 return true;
73 }
74
75 @Override
76 public boolean canRemoveItem(Player player, Item item, int slot) {
77 return true;
78 }
79
80 @Override
81 public boolean onButtonClick(Player p, int button) {
82 switch (button) {
83
84 case -32513:
85 if (!player.interfaceManager.isInterfaceOpen(InterfaceConstants.FIRST_TRADE_SCREEN)) {
86 return false;
87 }
88
89 depositeAll(p);
90 return true;
91
92 case -32510:
93 if (!player.interfaceManager.isInterfaceOpen(InterfaceConstants.FIRST_TRADE_SCREEN)) {
94 return false;
95 }
96
97 withdrawAll(p);
98 return true;
99
100 case -32524:
101 case -32530:
102 case -32324:
103 case -32332:
105 return true;
106
107 case -32527:
108 if (!player.interfaceManager.isInterfaceOpen(InterfaceConstants.FIRST_TRADE_SCREEN)) {
109 return false;
110 }
111
112 accept(p, "OFFER_ITEMS");
113 return true;
114
115 case -32327:
116 if (!player.interfaceManager.isInterfaceOpen(InterfaceConstants.SECOND_TRADE_SCREEN)) {
117 return false;
118 }
119
120 accept(p, "CONFIRM_DECISION");
121 return true;
122
123 }
124 return false;
125 }
126
127 @Override
128 public void accept(Player player, String component) {
130 switch (component) {
131 case "OFFER_ITEMS":
132 if (!lastOfferModification.elapsed(1_000)) {
133 player.send(new SendString("@red@Trade has been modified!", 33030));
134 return;
135 }
136 if (!player.inventory.hasCapacityFor(item_containers.get(other).toArray())) {
137 player.send(new SendMessage("You don't have enough free slots for this many items.", MessageColor.RED));
138 break;
139 }
140
141 if (!other.inventory.hasCapacityFor(item_containers.get(player).toArray())) {
142 String username = other.getName();
143 player.send(new SendMessage(username + " doesn't have enough free slots for this many items", MessageColor.RED));
144 break;
145 }
146 if (hasAttachment() && getAttachment() != player) {
147 this.setAttachment(null);
148 updateMainComponents("SECOND_SCREEN");
149 return;
150 }
151 setAttachment(player);
152 player.send(new SendString("Waiting for other player...", 33029));
153 other.send(new SendString("Other player has accepted", 33029));
154 break;
155 case "CONFIRM_DECISION":
156 if (hasAttachment() && getAttachment() != player) {
157 this.setAttachment(null);
158 accept(player, "FINALIZE");
159 return;
160 }
162 other.send(new SendString("Other player has accepted.", 33202));
163 player.send(new SendString("Waiting for other player...", 33202));
164 break;
165
166 case "FINALIZE":
167 if (other.isRegistered() && player.isRegistered()) {
168
169 final Item[] playerItems = this.item_containers.get(player).toArray();
170 final Item[] otherItems = this.item_containers.get(other).toArray();
171
172 player.inventory.addAll(otherItems);
173 other.inventory.addAll(playerItems);
174
175 World.getDataBus().publish(new TradeLogEvent(player, playerItems, other, otherItems));
176
177 forEach(p -> p.send(new SendMessage("Trade successfully completed with " + this.getOther(p).getName(), MessageColor.RED)));
179 }
180 break;
181
182 }
183 }
184
185 @Override
186 public void updateMainComponents(String component) {
187 switch (component) {
188 case "FIRST_SCREEN":
190 break;
191 case "SECOND_SCREEN":
192 forEach(p -> {
193 Player recipient = p.getName().equals(player.getName()) ? this.other : this.player;
194
195 p.send(new SendString("<col=65535>Are you sure you want to make this trade?", 33202));
196 p.send(new SendItemOnInterface(InterfaceConstants.INVENTORY_INTERFACE, p.inventory.toArray()));
197
198 p.send(new SendString(getItemNames(p, this.item_containers.get(p).toArray()), 33221));
199 p.send(new SendString(getItemNames(recipient, this.item_containers.get(recipient).toArray()), 33251));
200 p.send(new SendString("<col=65535>Trading With:", 33207));
201 p.send(new SendString(String.format("%s <col=65535>%s", PlayerRight.getCrown(recipient), Utility.formatName(recipient.getName())), 33208));
202 p.interfaceManager.openInventory(InterfaceConstants.SECOND_TRADE_SCREEN, 3213);
203 });
204 break;
205 }
206 }
207
208 @Override
209 public void updateOfferComponents() {
210 this.lastOfferModification.reset();
211 this.setAttachment(null);
212 forEach(p -> {
213 Player recipient = p.getName().equals(player.getName()) ? this.other : this.player;
214 int remaining = recipient.inventory.remaining();
215
217 this.item_containers.get(p).refresh(recipient, InterfaceConstants.OTHER_TRADE_CONTAINER);
218
219 p.send(new SendItemOnInterface(3322, p.inventory.toArray()));
220 p.send(new SendString(String.format("Trading with: %s %s", PlayerRight.getCrown(recipient), Utility.formatName(recipient.getName())), 33002));
221 p.send(new SendString(Utility.formatName(recipient.getName()), 33003));
222 p.send(new SendString("has " + remaining + " free", 33004));
223 p.send(new SendString("inventory spaces", 33005));
224
225 // p = current player being looped
226 // recipient = the other player (not the player being looped)
227 // don't use player and other object because those are the cached values.
228// long difference = this.item_containers.get(p).containerValue(PriceType.VALUE) - this.item_containers.get(recipient).containerValue(PriceType.VALUE);
229// System.out.println("difference = " + difference);FIXME
230// p.send(new SendString(difference == 0 ? "<col=ffffff> Absolutely nothing!" : "<col=ffffff> " + difference, 33018));
231
232 p.send(new SendString(this.item_containers.get(p).containerValue(PriceType.VALUE) == 0 ? "Nothing." : Utility.formatDigits(this.item_containers.get(p).containerValue(PriceType.VALUE)) + " gp", 33019));
233 p.send(new SendString(this.item_containers.get(recipient).containerValue(PriceType.VALUE) == 0 ? "Nothing." : Utility.formatDigits(this.item_containers.get(recipient).containerValue(PriceType.VALUE)) + " gp", 33020));
234
235 p.send(new SendString("", 33029));
236 p.send(new SendString("", 33030));
237
238 p.interfaceManager.openInventory(InterfaceConstants.FIRST_TRADE_SCREEN, 3321);
239 });
240 }
241
242 @Override
243 public void onReset() {
244 forEach(p -> {
245 p.attributes.set("TRADE_KEY", false);
246 p.interfaceManager.close();
247 p.resetFace();
249 });
250 }
251
252 /**
253 * Determines and returns the text for {@code items} that will be displayed
254 * on the confirm trade screen.
255 */
256 private String getItemNames(Player player, Item[] items) {
257 String tradeItems = "Absolutely nothing!";
258 String tradeAmount;
259 int count = 0;
260 for (Item item : items) {
261 if (item == null || tradeItems.contains(item.getName())) {
262 continue;
263 }
264 int amount = this.item_containers.get(player).computeAmountForId(item.getId());
265 tradeAmount = item.isStackable() ? amount >= 1000 && amount < 1000000 ? "@cya@" + (amount / 1000) + "K @whi@" + "(" + amount + ")" : amount >= 1000000 ? "@gre@" + (amount / 1000000) + " " + "million @whi@(" + amount + ")" : "" + amount : "(x" + amount + ")";
266 tradeItems = count == 0 ? item.getName() : tradeItems + "\\n" + item.getName();
267 tradeItems = tradeItems + (item.isStackable() ? " x " : " ") + tradeAmount;
268 count++;
269 }
270 return tradeItems;
271 }
272}
void publish(Event event)
Sends an Event to all subscribed listeners.
Definition DataBus.java:92
The class that contains helpful information on interfaces.
static final int PLAYER_TRADE_CONTAINER
The container itemcontainer for the player starting the trade.
static final int FIRST_TRADE_SCREEN
The main trade itemcontainer.
static final int OTHER_TRADE_CONTAINER
The container itemcontainer for the other player in the trade.
static final int SECOND_TRADE_SCREEN
The second trade screen itemcontainer.
Represents the game world.
Definition World.java:46
static DataBus getDataBus()
Definition World.java:568
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 ExchangeSessionManager exchangeSession
Definition Player.java:318
boolean hasAttachment()
Determines if the trade stage has an attachment.
static final Set< ExchangeSession > SESSIONS
The collection of sessions.
Object getAttachment()
Retrieves the attachment object to this class.
void withdrawAll(Player player)
Withdraws all items from the exchange session.
final Map< Player, ItemContainer > item_containers
The items which are in this exchange session.
ExchangeSession(Player player, Player other, ExchangeSessionType type)
Constructs a new ExchangeSession.
void setAttachment(Object attachment)
Assigns an attachment to this stage object.
void finalize(ExchangeCompletionType type)
Finalizes the exchange session procedure for the specified player in a session.
void forEach(Consumer< Player > action)
Executes the specified action for every player in this session.
void depositeAll(Player player)
Deposites all items to the exchange session.
Player getOther(Player p)
Gets the other player in the exchange session.
void reset(ExchangeSessionType type)
Resets all the session for the player dependant on the type.
TradeSession(Player player, Player other)
Constructs a new ExchangeSession.
void accept(Player player, String component)
The method invoked when a PLAYER accepts a certain exchange component.
String getItemNames(Player player, Item[] items)
Determines and returns the text for items that will be displayed on the confirm trade screen.
void onReset()
Any functionality that should be handled when the itemcontainer closes.
boolean canRemoveItem(Player player, Item item, int slot)
Checks if the item can be removed from the container.
boolean onButtonClick(Player p, int button)
The method invoked when a button is clicked.
boolean canAddItem(Player player, Item item, int slot)
Checks if the item can be added to the container.
void updateMainComponents(String component)
Updates the main components of the itemcontainer.
void updateOfferComponents()
Updates the itemcontainer when an item is offered or removed.
final Stopwatch lastOfferModification
The stopwatch which blocks the player from further continueing the session if a second hasn't passed ...
boolean onRequest()
The method invoked when a player requests the other player.
The container class that represents an item that can be interacted with.
Definition Item.java:21
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.
static Stopwatch start()
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 getCrown(Player player)
Gets the crown display.
UNCLICKABLE
The state where the map is visible, but clicking is disabled.
NORMAL
The default state where the map is visible and clicking is enabled.
Holds an enum of colors for ease.