mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-22 13:33:35 +00:00
feat: achievement vendor and vendor feedback (#1461)
* Groundwork * movie buying logic out of gm handler make transaction result more useful * Full implementation Cleanup and fix some calls in gamemessages * Load the component in the entity Patch Auth * new line at eof * cache lookups * remove sort * fix includes
This commit is contained in:
parent
1328850a8d
commit
e729c7f846
@ -106,7 +106,7 @@ enum class eReplicaComponentType : uint32_t {
|
||||
INTERACTION_MANAGER,
|
||||
DONATION_VENDOR,
|
||||
COMBAT_MEDIATOR,
|
||||
COMMENDATION_VENDOR,
|
||||
ACHIEVEMENT_VENDOR,
|
||||
GATE_RUSH_CONTROL,
|
||||
RAIL_ACTIVATOR,
|
||||
ROLLER,
|
||||
|
15
dCommon/dEnums/eVendorTransactionResult.h
Normal file
15
dCommon/dEnums/eVendorTransactionResult.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __EVENDORTRANSACTIONRESULT__
|
||||
#define __EVENDORTRANSACTIONRESULT__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eVendorTransactionResult : uint32_t {
|
||||
SELL_SUCCESS = 0,
|
||||
SELL_FAIL,
|
||||
PURCHASE_SUCCESS,
|
||||
PURCHASE_FAIL,
|
||||
DONATION_FAIL,
|
||||
DONATION_FULL
|
||||
};
|
||||
|
||||
#endif // !__EVENDORTRANSACTIONRESULT__
|
@ -79,7 +79,6 @@ void CDMissionsTable::LoadValuesFromDatabase() {
|
||||
entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
|
||||
Default.id = -1;
|
||||
@ -118,3 +117,12 @@ const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& foun
|
||||
return Default;
|
||||
}
|
||||
|
||||
const std::set<int32_t> CDMissionsTable::GetMissionsForReward(LOT lot) {
|
||||
std::set<int32_t> toReturn {};
|
||||
for (const auto& entry : GetEntries()) {
|
||||
if (lot == entry.reward_item1 || lot == entry.reward_item2 || lot == entry.reward_item3 || lot == entry.reward_item4) {
|
||||
toReturn.insert(entry.id);
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ public:
|
||||
|
||||
const CDMissions& GetByMissionID(uint32_t missionID, bool& found) const;
|
||||
|
||||
const std::set<int32_t> GetMissionsForReward(LOT lot);
|
||||
|
||||
|
||||
static CDMissions Default;
|
||||
};
|
||||
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "CollectibleComponent.h"
|
||||
#include "ItemComponent.h"
|
||||
#include "GhostComponent.h"
|
||||
#include "AchievementVendorComponent.h"
|
||||
|
||||
// Table includes
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
@ -615,6 +616,8 @@ void Entity::Initialize() {
|
||||
AddComponent<VendorComponent>();
|
||||
} else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) {
|
||||
AddComponent<DonationVendorComponent>();
|
||||
} else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ACHIEVEMENT_VENDOR, -1) != -1)) {
|
||||
AddComponent<AchievementVendorComponent>();
|
||||
}
|
||||
|
||||
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) {
|
||||
@ -1191,6 +1194,11 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
|
||||
donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
AchievementVendorComponent* achievementVendorComponent;
|
||||
if (TryGetComponent(eReplicaComponentType::ACHIEVEMENT_VENDOR, achievementVendorComponent)) {
|
||||
achievementVendorComponent->Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
BouncerComponent* bouncerComponent;
|
||||
if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) {
|
||||
bouncerComponent->Serialize(outBitStream, bIsInitialUpdate);
|
||||
|
72
dGame/dComponents/AchievementVendorComponent.cpp
Normal file
72
dGame/dComponents/AchievementVendorComponent.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "AchievementVendorComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "eMissionState.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDItemComponentTable.h"
|
||||
#include "eVendorTransactionResult.h"
|
||||
#include "CheatDetection.h"
|
||||
#include "UserManager.h"
|
||||
#include "CDMissionsTable.h"
|
||||
|
||||
bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) {
|
||||
auto* missionComponent = buyer->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return false;
|
||||
|
||||
if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)){
|
||||
return true;
|
||||
}
|
||||
|
||||
CDMissionsTable* missionsTable = CDClientManager::GetTable<CDMissionsTable>();
|
||||
const auto missions = missionsTable->GetMissionsForReward(lot);
|
||||
for (const auto mission : missions) {
|
||||
if (missionComponent->GetMissionState(mission) == eMissionState::COMPLETE) {
|
||||
m_PlayerPurchasableItems[buyer->GetObjectID()].insert(lot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
// get the item Comp from the item LOT
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM);
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
uint32_t costLOT = itemComp.commendationLOT;
|
||||
|
||||
if (costLOT == -1 || !SellsItem(buyer, lot)) {
|
||||
auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress());
|
||||
CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT());
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* inventoryComponent = buyer->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (costLOT == 13763) { // Faction Token Proxy
|
||||
auto* missionComponent = buyer->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
|
||||
if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) costLOT = 8318; // "Assembly Token"
|
||||
if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) costLOT = 8321; // "Venture League Token"
|
||||
if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) costLOT = 8319; // "Sentinels Token"
|
||||
if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) costLOT = 8320; // "Paradox Token"
|
||||
}
|
||||
|
||||
const uint32_t altCurrencyCost = itemComp.commendationCost * count;
|
||||
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
inventoryComponent->RemoveItem(costLOT, altCurrencyCost);
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
|
||||
}
|
23
dGame/dComponents/AchievementVendorComponent.h
Normal file
23
dGame/dComponents/AchievementVendorComponent.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef __ACHIEVEMENTVENDORCOMPONENT__H__
|
||||
#define __ACHIEVEMENTVENDORCOMPONENT__H__
|
||||
|
||||
#include "VendorComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
class Entity;
|
||||
|
||||
class AchievementVendorComponent final : public VendorComponent {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR;
|
||||
AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {};
|
||||
bool SellsItem(Entity* buyer, const LOT lot);
|
||||
void Buy(Entity* buyer, LOT lot, uint32_t count);
|
||||
|
||||
private:
|
||||
std::map<LWOOBJID,std::set<LOT>> m_PlayerPurchasableItems;
|
||||
};
|
||||
|
||||
|
||||
#endif //!__ACHIEVEMENTVENDORCOMPONENT__H__
|
@ -1,4 +1,5 @@
|
||||
set(DGAME_DCOMPONENTS_SOURCES
|
||||
"AchievementVendorComponent.cpp"
|
||||
"ActivityComponent.cpp"
|
||||
"BaseCombatAIComponent.cpp"
|
||||
"BouncerComponent.cpp"
|
||||
|
@ -8,6 +8,11 @@
|
||||
#include "CDLootMatrixTable.h"
|
||||
#include "CDLootTableTable.h"
|
||||
#include "CDItemComponentTable.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "Character.h"
|
||||
#include "eVendorTransactionResult.h"
|
||||
#include "UserManager.h"
|
||||
#include "CheatDetection.h"
|
||||
|
||||
VendorComponent::VendorComponent(Entity* parent) : Component(parent) {
|
||||
m_HasStandardCostItems = false;
|
||||
@ -151,3 +156,60 @@ void VendorComponent::HandleMrReeCameras(){
|
||||
m_Inventory.push_back(SoldItem(camera, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
|
||||
if (!SellsItem(lot)) {
|
||||
auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress());
|
||||
CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT());
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* inventoryComponent = buyer->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM);
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
|
||||
// Extra currency that needs to be deducted in case of crafting
|
||||
auto craftingCurrencies = CDItemComponentTable::ParseCraftingCurrencies(itemComp);
|
||||
for (const auto& [crafintCurrencyLOT, crafintCurrencyCount]: craftingCurrencies) {
|
||||
if (inventoryComponent->GetLotCount(crafintCurrencyLOT) < (crafintCurrencyCount * count)) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const auto& [crafintCurrencyLOT, crafintCurrencyCount]: craftingCurrencies) {
|
||||
inventoryComponent->RemoveItem(crafintCurrencyLOT, crafintCurrencyCount * count);
|
||||
}
|
||||
|
||||
|
||||
float buyScalar = GetBuyScalar();
|
||||
const auto coinCost = static_cast<uint32_t>(std::floor((itemComp.baseValue * buyScalar) * count));
|
||||
|
||||
Character* character = buyer->GetCharacter();
|
||||
if (!character || character->GetCoins() < coinCost) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Inventory::IsValidItem(itemComp.currencyLOT)) {
|
||||
const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * buyScalar) * count;
|
||||
if (inventoryComponent->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
inventoryComponent->RemoveItem(itemComp.currencyLOT, altCurrencyCost);
|
||||
}
|
||||
|
||||
character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR);
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
|
||||
}
|
@ -47,6 +47,7 @@ public:
|
||||
m_DirtyVendor = true;
|
||||
}
|
||||
|
||||
void Buy(Entity* buyer, LOT lot, uint32_t count);
|
||||
|
||||
private:
|
||||
void SetupMaxCustomVendor();
|
||||
|
@ -78,6 +78,7 @@
|
||||
#include "LevelProgressionComponent.h"
|
||||
#include "DonationVendorComponent.h"
|
||||
#include "GhostComponent.h"
|
||||
#include "AchievementVendorComponent.h"
|
||||
|
||||
// Message includes:
|
||||
#include "dZoneManager.h"
|
||||
@ -97,6 +98,7 @@
|
||||
#include "ePetAbilityType.h"
|
||||
#include "ActivityManager.h"
|
||||
#include "PlayerManager.h"
|
||||
#include "eVendorTransactionResult.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDObjectsTable.h"
|
||||
@ -1323,15 +1325,14 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr) {
|
||||
void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr, eVendorTransactionResult result) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
int iResult = 0x02; // success, seems to be the only relevant one
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write(eGameMessageType::VENDOR_TRANSACTION_RESULT);
|
||||
bitStream.Write(iResult);
|
||||
bitStream.Write(result);
|
||||
|
||||
SEND_PACKET;
|
||||
}
|
||||
@ -4664,94 +4665,27 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti
|
||||
if (!user) return;
|
||||
Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar());
|
||||
if (!player) return;
|
||||
|
||||
// handle buying normal items
|
||||
auto* vendorComponent = entity->GetComponent<VendorComponent>();
|
||||
if (vendorComponent) {
|
||||
vendorComponent->Buy(player, item, count);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* propertyVendorComponent = static_cast<PropertyVendorComponent*>(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR));
|
||||
// handle buying achievement items
|
||||
auto* achievementVendorComponent = entity->GetComponent<AchievementVendorComponent>();
|
||||
if (achievementVendorComponent) {
|
||||
achievementVendorComponent->Buy(player, item, count);
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyVendorComponent != nullptr) {
|
||||
// Handle buying properties
|
||||
auto* propertyVendorComponent = entity->GetComponent<PropertyVendorComponent>();
|
||||
if (propertyVendorComponent) {
|
||||
propertyVendorComponent->OnBuyFromVendor(player, bConfirmed, item, count);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto isCommendationVendor = entity->GetLOT() == 13806;
|
||||
|
||||
auto* vend = entity->GetComponent<VendorComponent>();
|
||||
if (!vend && !isCommendationVendor) return;
|
||||
|
||||
auto* inv = player->GetComponent<InventoryComponent>();
|
||||
if (!inv) return;
|
||||
|
||||
if (!isCommendationVendor && !vend->SellsItem(item)) {
|
||||
LOG("User %llu %s tried to buy an item %i from a vendor when they do not sell said item", player->GetObjectID(), user->GetUsername().c_str(), item);
|
||||
return;
|
||||
}
|
||||
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
|
||||
int itemCompID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM);
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
|
||||
Character* character = player->GetCharacter();
|
||||
if (!character) return;
|
||||
|
||||
// Extra currency that needs to be deducted in case of crafting
|
||||
auto craftingCurrencies = CDItemComponentTable::ParseCraftingCurrencies(itemComp);
|
||||
for (const auto& craftingCurrency : craftingCurrencies) {
|
||||
inv->RemoveItem(craftingCurrency.first, craftingCurrency.second * count);
|
||||
}
|
||||
|
||||
if (isCommendationVendor) {
|
||||
if (itemComp.commendationLOT != 13763) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* missionComponent = player->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOT tokenId = -1;
|
||||
|
||||
if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) tokenId = 8318; // "Assembly Token"
|
||||
if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) tokenId = 8321; // "Venture League Token"
|
||||
if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) tokenId = 8319; // "Sentinels Token"
|
||||
if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) tokenId = 8320; // "Paradox Token"
|
||||
|
||||
const uint32_t altCurrencyCost = itemComp.commendationCost * count;
|
||||
|
||||
if (inv->GetLotCount(tokenId) < altCurrencyCost) {
|
||||
return;
|
||||
}
|
||||
|
||||
inv->RemoveItem(tokenId, altCurrencyCost);
|
||||
|
||||
inv->AddItem(item, count, eLootSourceType::VENDOR);
|
||||
} else {
|
||||
float buyScalar = vend->GetBuyScalar();
|
||||
|
||||
const auto coinCost = static_cast<uint32_t>(std::floor((itemComp.baseValue * buyScalar) * count));
|
||||
|
||||
if (character->GetCoins() < coinCost) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Inventory::IsValidItem(itemComp.currencyLOT)) {
|
||||
const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * buyScalar) * count;
|
||||
|
||||
if (inv->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) {
|
||||
return;
|
||||
}
|
||||
|
||||
inv->RemoveItem(itemComp.currencyLOT, altCurrencyCost);
|
||||
}
|
||||
|
||||
character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR);
|
||||
inv->AddItem(item, count, eLootSourceType::VENDOR);
|
||||
}
|
||||
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr);
|
||||
}
|
||||
|
||||
void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
|
||||
@ -4785,7 +4719,10 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
|
||||
// Items with a base value of 0 or max int are special items that should not be sold if they're not sub items
|
||||
if (itemComp.baseValue == 0 || itemComp.baseValue == UINT_MAX) return;
|
||||
if (itemComp.baseValue == 0 || itemComp.baseValue == UINT_MAX) {
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::SELL_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
float sellScalar = vend->GetSellScalar();
|
||||
if (Inventory::IsValidItem(itemComp.currencyLOT)) {
|
||||
@ -4793,11 +4730,9 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit
|
||||
inv->AddItem(itemComp.currencyLOT, std::floor(altCurrency), eLootSourceType::VENDOR); // Return alt currencies like faction tokens.
|
||||
}
|
||||
|
||||
//inv->RemoveItem(count, -1, iObjID);
|
||||
inv->MoveItemToInventory(item, eInventoryType::VENDOR_BUYBACK, count, true, false, true);
|
||||
character->SetCoins(std::floor(character->GetCoins() + (static_cast<uint32_t>(itemComp.baseValue * sellScalar) * count)), eLootSourceType::VENDOR);
|
||||
//Game::entityManager->SerializeEntity(player); // so inventory updates
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr);
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::SELL_SUCCESS);
|
||||
}
|
||||
|
||||
void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
|
||||
@ -4839,16 +4774,16 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity*
|
||||
const auto cost = static_cast<uint32_t>(std::floor(((itemComp.baseValue * sellScalar) * count)));
|
||||
|
||||
if (character->GetCoins() < cost) {
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Inventory::IsValidItem(itemComp.currencyLOT)) {
|
||||
const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * sellScalar) * count;
|
||||
|
||||
if (inv->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) {
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
inv->RemoveItem(itemComp.currencyLOT, altCurrencyCost);
|
||||
}
|
||||
|
||||
@ -4856,7 +4791,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity*
|
||||
inv->MoveItemToInventory(item, Inventory::FindInventoryTypeForLot(item->GetLot()), count, true, false);
|
||||
character->SetCoins(character->GetCoins() - cost, eLootSourceType::VENDOR);
|
||||
//Game::entityManager->SerializeEntity(player); // so inventory updates
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr);
|
||||
GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
}
|
||||
|
||||
void GameMessages::HandleParseChatMessage(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
|
||||
|
@ -38,6 +38,7 @@ enum class eUseItemResponse : uint32_t;
|
||||
enum class eQuickBuildFailReason : uint32_t;
|
||||
enum class eQuickBuildState : uint32_t;
|
||||
enum class BehaviorSlot : int32_t;
|
||||
enum class eVendorTransactionResult : uint32_t;
|
||||
|
||||
namespace GameMessages {
|
||||
class PropertyDataMessage;
|
||||
@ -135,7 +136,7 @@ namespace GameMessages {
|
||||
|
||||
void SendVendorOpenWindow(Entity* entity, const SystemAddress& sysAddr);
|
||||
void SendVendorStatusUpdate(Entity* entity, const SystemAddress& sysAddr, bool bUpdateOnly = false);
|
||||
void SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr);
|
||||
void SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr, eVendorTransactionResult result);
|
||||
|
||||
void SendRemoveItemFromInventory(Entity* entity, const SystemAddress& sysAddr, LWOOBJID iObjID, LOT templateID, int inventoryType, uint32_t stackCount, uint32_t stackRemaining);
|
||||
void SendConsumeClientItem(Entity* entity, bool bSuccess, LWOOBJID item);
|
||||
|
@ -82,7 +82,7 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c
|
||||
if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth);
|
||||
else if (serverType == ServerType::World) bitStream.Write(ServiceId::World);
|
||||
else bitStream.Write(ServiceId::General);
|
||||
bitStream.Write<uint32_t>(774909490);
|
||||
bitStream.Write<uint64_t>(215523405360);
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user