[Feature] Add Barter/Buyer Features (#4405)

* Add Barter/Buyer Features

Adds barter and buyer features, for ROF2 only at this time including item compensation

* Remove FKs from buyer tables

Remove FKs from buyer tables

* Bug fix for Find Buyer and mutli item selling

Update for quantity purchases not correctly providing multi items.
Update for Find Buyer functionality based on zone instancing.
Update buyer messaging
Update buyer LORE duplicate check

* Revert zone instance comment

* Revert zone_id packet size field

* Add zone instancing to barter/buyer

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Mitch Freeman
2024-07-30 17:23:37 -03:00
committed by GitHub
parent fc3c691588
commit e49ab924cc
40 changed files with 4715 additions and 946 deletions
+113 -9
View File
@@ -203,7 +203,6 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
port = ntohs(eqs->GetRemotePort());
client_state = CLIENT_CONNECTING;
SetTrader(false);
Buyer = false;
Haste = 0;
SetCustomerID(0);
SetTraderID(0);
@@ -386,6 +385,8 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
m_parcel_merchant_engaged = false;
m_parcels.clear();
m_buyer_id = 0;
SetBotPulling(false);
SetBotPrecombat(false);
@@ -429,8 +430,9 @@ Client::~Client() {
TraderEndTrader();
}
if(Buyer)
if(IsBuyer()) {
ToggleBuyerMode(false);
}
if(conn_state != ClientConnectFinished) {
LogDebug("Client [{}] was destroyed before reaching the connected state:", GetName());
@@ -2163,12 +2165,13 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
Mob::FillSpawnStruct(ns, ForWho);
// Populate client-specific spawn information
ns->spawn.afk = AFK;
ns->spawn.lfg = LFG; // afk and lfg are cleared on zoning on live
ns->spawn.anon = m_pp.anon;
ns->spawn.gm = GetGM() ? 1 : 0;
ns->spawn.guildID = GuildID();
ns->spawn.trader = IsTrader();
ns->spawn.afk = AFK;
ns->spawn.lfg = LFG; // afk and lfg are cleared on zoning on live
ns->spawn.anon = m_pp.anon;
ns->spawn.gm = GetGM() ? 1 : 0;
ns->spawn.guildID = GuildID();
ns->spawn.trader = IsTrader();
ns->spawn.buyer = IsBuyer();
// ns->spawn.linkdead = IsLD() ? 1 : 0;
// ns->spawn.pvp = GetPVP(false) ? 1 : 0;
ns->spawn.show_name = true;
@@ -11993,7 +11996,7 @@ void Client::SendPath(Mob* target)
target->IsClient() &&
(
target->CastToClient()->IsTrader() ||
target->CastToClient()->Buyer
target->CastToClient()->IsBuyer()
)
) {
Message(
@@ -12597,3 +12600,104 @@ void Client::RemoveItemBySerialNumber(uint32 serial_number, uint32 quantity)
}
}
}
void Client::AddMoneyToPPWithOverflow(uint64 copper, bool update_client)
{
//I noticed in the ROF2 client that the client auto updates the currency values using overflow
//Therefore, I created this method to ensure that the db matches and clients don't see 10 pp 5 gp
//becoming 9pp 15 gold with the current AddMoneyToPP method.
auto add_pp = copper / 1000;
auto add_gp = (copper - add_pp * 1000) / 100;
auto add_sp = (copper - add_pp * 1000 - add_gp * 100) / 10;
auto add_cp = copper - add_pp * 1000 - add_gp * 100 - add_sp * 10;
m_pp.copper += add_cp;
if (m_pp.copper >= 10) {
m_pp.silver += m_pp.copper / 10;
m_pp.copper = m_pp.copper % 10;
}
m_pp.silver += add_sp;
if (m_pp.silver >= 10) {
m_pp.gold += m_pp.silver / 10;
m_pp.silver = m_pp.silver % 10;
}
m_pp.gold += add_gp;
if (m_pp.gold >= 10) {
m_pp.platinum += m_pp.gold / 10;
m_pp.gold = m_pp.gold % 10;
}
m_pp.platinum += add_pp;
if (update_client) {
SendMoneyUpdate();
}
RecalcWeight();
SaveCurrency();
LogDebug("Client::AddMoneyToPPWithOverflow() [{}] should have: plat:[{}] gold:[{}] silver:[{}] copper:[{}]",
GetName(),
m_pp.platinum,
m_pp.gold,
m_pp.silver,
m_pp.copper
);
}
bool Client::TakeMoneyFromPPWithOverFlow(uint64 copper, bool update_client)
{
int32 remove_pp = copper / 1000;
int32 remove_gp = (copper - remove_pp * 1000) / 100;
int32 remove_sp = (copper - remove_pp * 1000 - remove_gp * 100) / 10;
int32 remove_cp = copper - remove_pp * 1000 - remove_gp * 100 - remove_sp * 10;
uint64 current_money = GetCarriedMoney();
if (copper > current_money) {
return false; //client does not have enough money on them
}
m_pp.copper -= remove_cp;
if (m_pp.copper < 0) {
m_pp.silver -= 1;
m_pp.copper = m_pp.copper + 10;
if (m_pp.copper >= 10) {
m_pp.silver += m_pp.copper / 10;
m_pp.copper = m_pp.copper % 10;
}
}
m_pp.silver -= remove_sp;
if (m_pp.silver < 0) {
m_pp.gold -= 1;
m_pp.silver = m_pp.silver + 10;
if (m_pp.silver >= 10) {
m_pp.gold += m_pp.silver / 10;
m_pp.silver = m_pp.silver % 10;
}
}
m_pp.gold -= remove_gp;
if (m_pp.gold < 0) {
m_pp.platinum -= 1;
m_pp.gold = m_pp.gold + 10;
if (m_pp.gold >= 10) {
m_pp.platinum += m_pp.gold / 10;
m_pp.gold = m_pp.gold % 10;
}
}
m_pp.platinum -= remove_pp;
if (update_client) {
SendMoneyUpdate();
}
SaveCurrency();
RecalcWeight();
return true;
}