Files
2006Scape/2006Scape Server/src/main/java/com/rs2/game/players/Trading.java
T
ipkpjersi cad090d8fe Various fixes and improvements (#640)
* Added more client settings for winter and hide roofs

* Removed unnecessary local var and added Javadoc comment

* Fixed dark wizards casting magic in melee range

* Added AttackType enum

* Removed extra asterisk

* Removed attackType magic numbers

* Enabled snow toggles by default

* Combined snow month into one variable

* Added option for fixes without custom settings

Added option for fixes (and QoL tab) without overriding specific features.

* Added more main args

* Fixed typo

* Added player sound saving

We have it for music, so why not for sounds too?

* Fixed typos

* Added closed client exception to ignores

* Fixed NPC definitions not loading

* Replaced NPC definitions XML with JSON

* Replaced NPCDefinition Array with HashMap

* Use err for early exit output

* Fixed KQ death causing client crash

It had the wrong anims.

* Added zoom level to debug info

* Added zoom level messages option

* Added fire breath attack type enum

* Replaced remaining fire breath attack types

* Fixed client lag

This should technically not be necessary, but it's more of a workaround due to server inefficiencies (if you kill a bunch of cows, your client will start to lag and you will even stack hits, I suspect it's due to the ground items) until we fix the server inefficiencies. There's not really any downsides in changing this from 5 to 100, so it's a good change for now.

* Make definitions private

* Fixed dark wizards not attacking back

* Improved comments

* Removed extra giant mole spawns

* Added mole lair rope action

* Only send yes chat head when talking to NPC

* Fixed removing item does not reset autocast

* Fixed picking up stackable items with full inv

* Fixed lvl 7 dark wizard anims

* Added confirm param to xprate command and fixed players command

* Removed usages of Misc.println

This hides which file the println is actually called from, so it's actually better to remove this helper.

* Don't move player when clicking on barrows check

This is both unauthentic and unnecessary.

* Removed unnecessary commented out code

We don't even need it commented out tbh.

* Fixed incorrect barrows NPC attack anims

* Improved slayer points message

* Fixed slayer task message cut off

* Might as well make this naming consistent

* Fixed typo

* Fixed stronghold slayer dungeon getting stuck in wall

* Require control key for zooming

It's too easy to accidentally zoom in/out with the scroll wheel, so let's make it so you need the control key held to scroll wheel zoom in/out.

* Added option for control key zooming

This way, it's off by default so it works the way it always did by default.

* Added alias for control key zoom

* Fixed quest interface not emptying out completely

* Updated slayer point dialogue to be more accurate

* Fixed compile error

* Fixed formatting

* More formatting fixes

* Added 5th click object handling (fixes pick-lock crash)

* Fixed lower level NPCs always hitting 0

* Fixed NPCs having incorrect max hit

Chickens were hitting 3's, ouch...

* Fixed NPCs still hitting 0s

This is much better now. Combat feels good.

* Fixed boss max hits

* Fixed al-kharid gate talking option

* Copied over max hits from spawns.json to npcDefinitions.json

This fixes a lot of NPCs. Many NPCs already seem to be correct.

* Added workaround preventing players stuck in level 28 wildy

* Changed comment to TODO

* Added control key zoom toggle

* Extracted config option to ClientSettings

* added message for control key zooming
2024-09-21 01:30:57 +01:00

553 lines
17 KiB
Java

package com.rs2.game.players;
import java.time.temporal.ValueRange;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apollo.cache.def.ItemDefinition;
import com.rs2.event.CycleEvent;
import com.rs2.event.CycleEventContainer;
import com.rs2.event.CycleEventHandler;
import com.rs2.game.content.minigames.castlewars.CastleWars;
import com.rs2.game.items.DeprecatedItems;
import com.rs2.game.items.GameItem;
import com.rs2.game.items.ItemData;
import com.rs2.game.items.ItemConstants;
import com.rs2.util.GameLogger;
import com.rs2.util.Misc;
public class Trading {
private final Player player;
public Trading(Player player2) {
player = player2;
}
/**
* Trading
**/
public CopyOnWriteArrayList<GameItem> offeredItems = new CopyOnWriteArrayList<GameItem>();
public void requestTrade(int id) {
try {
Client o = (Client) PlayerHandler.players[id];
if (id == player.playerId) {
return;
}
// player owned shop
if (o.isBot && o.shopId >= 0){
if (isCloseTo(o)) {
player.getShopAssistant().openShop(o.shopId);
} else {
player.getPacketSender().sendMessage("Player is not close enough. Retry when you are closer...");
}
return;
}
player.tradeWith = id;
if (!CastleWars.deleteCastleWarsItems(player, id)) {
return;
}
if (!player.inTrade && o.tradeRequested && o.tradeWith == player.playerId && !player.playerIsBusy() && !o.playerIsBusy() ) { //start trading process
if (!isCloseTo(o)) {
player.getPacketSender().sendMessage("Player is not close enough. Retry when you are closer...");
} else {
player.getTrading().openTrade();
o.getTrading().openTrade();
}
} else if (!player.inTrade && !player.playerIsBusy() && !o.playerIsBusy()) { //send trade request
//Problem = sends the request then walk to player. Solution= change processing order. Fix= Send message when trying to open the trade interface if the other player isn't closer than 3 tiles.
player.tradeRequested = true;
player.getPacketSender().sendMessage("Sending trade request...");
o.getPacketSender()
.sendMessage(player.playerName + ":tradereq:");
} else if (player.playerIsBusy()|| o.playerIsBusy()) {
player.getPacketSender().sendMessage("Other player is busy at the moment.");
}
} catch (Exception e) {
System.out.println("Error requesting trade.");
}
}
public boolean isCloseTo(Client tradedPlayer) {
ValueRange PlayerCoordRangeX = ValueRange.of(tradedPlayer.absX - 3, tradedPlayer.absX + 3);
ValueRange PlayerCoordRangeY = ValueRange.of(tradedPlayer.absY - 3, tradedPlayer.absY + 3);
if (PlayerCoordRangeX.isValidIntValue(player.absX) && PlayerCoordRangeY.isValidIntValue(player.absY)) {
return true;
} else {
return false;
}
}
public void openTrade() {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return;
}
player.inTrade = true;
player.tradeStatus = 1;
player.tradeRequested = false;
player.getItemAssistant().resetItems(3322);
resetTItems(3415);
resetOTItems(3416);
String out = o.playerName;
if (o.playerRights == 1) {
out = "@cr1@" + out;
} else if (o.playerRights == 2) {
out = "@cr2@" + out;
}
player.getPacketSender().sendString(
"Trading with: " + o.playerName + " who has @gre@"
+ o.getItemAssistant().freeSlots() + " free slots",
3417);
player.getPacketSender().sendString("", 3431);
player.getPacketSender().sendString(
"Are you sure you want to make this trade?", 3535);
player.getPacketSender().sendFrame248(3323, 3321);
}
public void resetTItems(int WriteFrame) {
synchronized (player) {
player.getOutStream().createFrameVarSizeWord(53);
player.getOutStream().writeWord(WriteFrame);
int len = offeredItems.toArray().length;
int current = 0;
player.getOutStream().writeWord(len);
for (GameItem item : offeredItems) {
if (item.amount > 254) {
player.getOutStream().writeByte(255);
player.getOutStream().writeDWord_v2(item.amount);
} else {
player.getOutStream().writeByte(item.amount);
}
player.getOutStream().writeWordBigEndianA(item.id + 1);
current++;
}
if (current < 27) {
for (int i = current; i < 28; i++) {
player.getOutStream().writeByte(1);
player.getOutStream().writeWordBigEndianA(-1);
}
}
player.getOutStream().endFrameVarSizeWord();
player.flushOutStream();
}
}
public boolean fromTrade(int itemID, int fromSlot, int amount) {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return false;
}
try {
if (!player.inTrade) {
declineTrade();
return false;
}
player.tradeConfirmed = false;
o.tradeConfirmed = false;
if (!ItemDefinition.lookup(itemID).isStackable()) {
for (int a = 0; a < amount; a++) {
for (GameItem item : offeredItems) {
if (item.id == itemID) {
if (!item.stackable) {
offeredItems.remove(item);
player.getItemAssistant().addItem(itemID, 1);
o.getPacketSender().sendString(
"Trading with: "
+ player.playerName
+ " who has @gre@"
+ player.getItemAssistant()
.freeSlots()
+ " free slots", 3417);
} else {
if (item.amount > amount) {
item.amount -= amount;
player.getItemAssistant()
.addItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: "
+ player.playerName
+ " who has @gre@"
+ player.getItemAssistant()
.freeSlots()
+ " free slots", 3417);
} else {
amount = item.amount;
offeredItems.remove(item);
player.getItemAssistant()
.addItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: "
+ player.playerName
+ " who has @gre@"
+ player.getItemAssistant()
.freeSlots()
+ " free slots", 3417);
}
}
break;
}
o.getPacketSender().sendString(
"Trading with: " + player.playerName
+ " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
player.tradeConfirmed = false;
o.tradeConfirmed = false;
player.getItemAssistant().resetItems(3322);
resetTItems(3415);
o.getTrading().resetOTItems(3416);
player.getPacketSender().sendString("", 3431);
o.getPacketSender().sendString("", 3431);
}
}
}
for (GameItem item : offeredItems) {
if (item.id == itemID) {
if (!item.stackable) {
} else {
if (item.amount > amount) {
item.amount -= amount;
player.getItemAssistant().addItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: " + player.playerName
+ " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
} else {
amount = item.amount;
offeredItems.remove(item);
player.getItemAssistant().addItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: " + player.playerName
+ " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
}
}
break;
}
}
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots() + " free slots",
3417);
player.tradeConfirmed = false;
o.tradeConfirmed = false;
player.getItemAssistant().resetItems(3322);
resetTItems(3415);
o.getTrading().resetOTItems(3416);
player.getPacketSender().sendString("", 3431);
o.getPacketSender().sendString("", 3431);
} catch (Exception e) {
}
return true;
}
public boolean tradeItem(int itemID, int fromSlot, int amount) {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return false;
}
if (!(player.playerItems[fromSlot] == itemID + 1 )){//&& player.playerItemsN[fromSlot] >= amount)) { I removed this check to permit trading max amount of item in inventory even when amount is higher than quantity in inventory.
player.getPacketSender().sendMessage("You don't have that amount!");
return false;
}
if (amount >= Integer.MAX_VALUE) {
player.getPacketSender().sendMessage("You can't possibly have that much of that item!");
player.getItemAssistant().deleteItem(itemID, fromSlot, amount);
return false;
}
for (int i : ItemConstants.ITEM_TRADEABLE) {
if (i == itemID && player.playerRights < 3) {
player.getPacketSender().sendMessage("You can't trade this item.");
return false;
}
}
player.tradeConfirmed = false;
o.tradeConfirmed = false;
if (!ItemDefinition.lookup(itemID).isStackable() && !ItemDefinition.lookup(itemID).isNote()) {
for (int a = 0; a < amount && a < 28; a++) {
if (player.getItemAssistant().playerHasItem(itemID, 1)) {
offeredItems.add(new GameItem(itemID, 1));
player.getItemAssistant().deleteItem(itemID,
player.getItemAssistant().getItemSlot(itemID), 1);
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
}
}
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots() + " free slots",
3417);
player.getItemAssistant().resetItems(3322);
resetTItems(3415);
o.getTrading().resetOTItems(3416);
player.getPacketSender().sendString("", 3431);
o.getPacketSender().sendString("", 3431);
}
if (player.getItemAssistant().getItemAmount(itemID) < amount) {
amount = player.getItemAssistant().getItemAmount(itemID);
if (amount == 0) {
return false;
}
}
if (!player.inTrade || !o.inTrade) {
declineTrade();
return false;
}
if (ItemDefinition.lookup(itemID).isStackable() || ItemDefinition.lookup(itemID).isNote()) {
boolean inTrade = false;
for (GameItem item : offeredItems) {
if (item.id == itemID) {
inTrade = true;
item.amount += amount;
player.getItemAssistant().deleteItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
break;
}
}
if (!inTrade) {
offeredItems.add(new GameItem(itemID, amount));
player.getItemAssistant().deleteItem(itemID, amount);
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots()
+ " free slots", 3417);
}
}
o.getPacketSender().sendString(
"Trading with: " + player.playerName + " who has @gre@"
+ player.getItemAssistant().freeSlots() + " free slots",
3417);
player.getItemAssistant().resetItems(3322);
resetTItems(3415);
o.getTrading().resetOTItems(3416);
player.getPacketSender().sendString("", 3431);
o.getPacketSender().sendString("", 3431);
return true;
}
public void resetTrade() {
offeredItems.clear();
player.inTrade = false;
player.tradeWith = 0;
player.tradeConfirmed = false;
player.tradeConfirmed2 = false;
player.acceptedTrade = false;
player.getPacketSender().closeAllWindows();
player.tradeResetNeeded = false;
player.getPacketSender().sendString("Are you sure you want to make this trade?", 3535);
}
public void declineTrade() {
player.tradeStatus = 0;
declineTrade(true);
}
public void declineTrade(boolean tellOther) {
player.getPacketSender().closeAllWindows();
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return;
}
if (tellOther) {
o.getTrading().declineTrade(false);
o.getTrading().player.getPacketSender().closeAllWindows();
}
for (GameItem item : offeredItems) {
if (item.amount < 1) {
continue;
}
if (item.stackable) {
player.getItemAssistant().addItem(item.id, item.amount);
} else {
for (int i = 0; i < item.amount; i++) {
player.getItemAssistant().addItem(item.id, 1);
}
}
}
player.tradeConfirmed = false;
player.tradeConfirmed2 = false;
offeredItems.clear();
player.inTrade = false;
player.tradeWith = 0;
}
public void resetOTItems(int WriteFrame) {
synchronized (player) {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return;
}
player.getOutStream().createFrameVarSizeWord(53);
player.getOutStream().writeWord(WriteFrame);
int len = o.getTrading().offeredItems.toArray().length;
int current = 0;
player.getOutStream().writeWord(len);
for (GameItem item : o.getTrading().offeredItems) {
if (item.amount > 254) {
player.getOutStream().writeByte(255); // item's stack count. if over 254, write byte 255
player.getOutStream().writeDWord_v2(item.amount);
} else {
player.getOutStream().writeByte(item.amount);
}
player.getOutStream().writeWordBigEndianA(item.id + 1); // item id
current++;
}
if (current < 27) {
for (int i = current; i < 28; i++) {
player.getOutStream().writeByte(1);
player.getOutStream().writeWordBigEndianA(-1);
}
}
player.getOutStream().endFrameVarSizeWord();
player.flushOutStream();
}
}
public void confirmScreen() {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return;
}
if(!player.inTrade) {
declineTrade();
return;
}
player.getItemAssistant().resetItems(3214);
String SendTrade = "Absolutely nothing!";
String SendAmount = "";
int Count = 0;
for (GameItem item : offeredItems) {
if (item.id > 0) {
if (item.amount >= 1000 && item.amount < 1000000) {
SendAmount = "@cya@" + item.amount / 1000 + "K @whi@("
+ Misc.format(item.amount) + ")";
} else if (item.amount >= 1000000) {
SendAmount = "@gre@" + item.amount / 1000000
+ " million @whi@(" + Misc.format(item.amount)
+ ")";
} else {
SendAmount = "" + Misc.format(item.amount);
}
if (Count == 0) {
SendTrade = DeprecatedItems.getItemName(item.id);
} else {
SendTrade = SendTrade + "\\n"
+ DeprecatedItems.getItemName(item.id);
}
if (item.stackable) {
SendTrade = SendTrade + " x " + SendAmount;
}
Count++;
}
}
player.getPacketSender().sendString(SendTrade, 3557);
SendTrade = "Absolutely nothing!";
SendAmount = "";
Count = 0;
for (GameItem item : o.getTrading().offeredItems) {
if (item.id > 0) {
if (item.amount >= 1000 && item.amount < 1000000) {
SendAmount = "@cya@" + item.amount / 1000 + "K @whi@("
+ Misc.format(item.amount) + ")";
} else if (item.amount >= 1000000) {
SendAmount = "@gre@" + item.amount / 1000000
+ " million @whi@(" + Misc.format(item.amount)
+ ")";
} else {
SendAmount = "" + Misc.format(item.amount);
}
if (Count == 0) {
SendTrade = DeprecatedItems.getItemName(item.id);
} else {
SendTrade = SendTrade + "\\n"
+ DeprecatedItems.getItemName(item.id);
}
if (item.stackable) {
SendTrade = SendTrade + " x " + SendAmount;
}
Count++;
}
}
player.getPacketSender().sendString(SendTrade, 3558);
// TODO: find out what 197 does eee 3213
player.getPacketSender().sendFrame248(3443, 197);
}
public void giveItems() {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o == null) {
return;
}
try {
for (GameItem item : o.getTrading().offeredItems) {
String itemName = DeprecatedItems.getItemName(item.id);
if (item.id > 0) {
player.getItemAssistant().addItem(item.id, item.amount);
if (player.getPlayerAssistant().isPlayer()) {
GameLogger.writeLog(o.playerName, "tradesgave", o.playerName + " traded " + player.playerName + " and gave " + item.amount + " " + itemName + "");
}
}
if (player.getPlayerAssistant().isPlayer()) {
GameLogger.writeLog(player.playerName, "tradesrecieved", player.playerName + " was traded by " + o.playerName + " and recieved " + item.amount + " " + itemName + "");
}
}
player.getPacketSender().closeAllWindows();
player.tradeResetNeeded = true;
CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
@Override
public void execute(CycleEventContainer container) {
if (player.inTrade && player.tradeResetNeeded) {
Client o = (Client) PlayerHandler.players[player.tradeWith];
if (o != null) {
if (o.tradeResetNeeded) {
player.getTrading().resetTrade();
o.getTrading().resetTrade();
container.stop();
} else {
container.stop();
}
} else {
container.stop();
}
} else {
container.stop();
}
}
@Override
public void stop() {
player.tradeResetNeeded = false;
}
}, 1);
} catch (Exception e) {
}
}
}