Files
ThordekkCore/src/server/game/PerkProgram/PerkProgramMgr.cpp
T
2026-03-15 19:40:29 -03:00

431 lines
12 KiB
C++

/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "Common.h"
#include "CollectionMgr.h"
#include "ObjectMgr.h"
#include "PerkProgramMgr.h"
#include "WorldSession.h"
#include "Guild.h"
#include "GuildMgr.h"
#include "Player.h"
#include "Creature.h"
#include "PerkProgramData.h"
#include "DatabaseEnv.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
#include <sstream>
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "Language.h"
#include "SpellPackets.h"
#include "Chat.h"
#include "DB2Stores.h"
#include "Pet.h"
#include "Item.h"
#include "MiscPackets.h"
#include "Unit.h"
#include "GameTime.h"
#include "PerksProgramPackets.h"
using namespace PerkPrograms;
PerkProgramManager::PerkProgramManager(WorldSession* session)
{
_session = session;
if (session->GetPlayer())
m_player = session->GetPlayer();
m_currencyAmount = 0;
}
PerkProgramManager::~PerkProgramManager()
{
};
void PerkProgramManager::SendVendorItems(Creature* vendor, std::vector<uint32> purchasedItems)
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_AVAILABLE_ITEMS;
uint32 cameraId = 0;
switch (vendor->GetEntry())
{
case PerkPrograms::VENDOR_HORDE:
cameraId = PerkPrograms::CAMERA_HORDE;
break;
case PerkPrograms::VENDOR_ALLIANCE:
cameraId = PerkPrograms::CAMERA_ALLIANCE;
break;
default:
cameraId = 0;
break;
}
perks.Params.VendorItem.VendorGuid = vendor->GetGUID();
if (cameraId != 0)
{
std::list<Creature*> list;
_session->GetPlayer()->GetCreatureListWithEntryInGrid(list, cameraId, 100);
for (auto cr1 : list)
{
perks.Params.VendorItem.ModelSceneCameraGuid = cr1->GetGUID();
break;
}
}
for (auto items : sPerkProgramDataStore->GetVendorItems())
{
WorldPackets::PerksProgram::PerksVendorItem vendorItem;
vendorItem.VendorItemID = items.second.Id;
vendorItem.MountID = items.second.MountSpellID;
vendorItem.BattlePetSpeciesID = items.second.PetSpellID;
vendorItem.ItemModifiedAppearanceID = items.second.ItemModifiedAppearanceID;
vendorItem.ToyID = items.second.ToyItem;
vendorItem.TransmogSetID = items.second.TransmogSet;
vendorItem.Price = items.second.Cost;
vendorItem.OriginalPrice = items.second.CategoryId;
vendorItem.Disabled = false;
vendorItem.AvailableUntil = items.second.AvailableUntil;
perks.Params.VendorItem.FrozenPerksVendorItems.emplace_back(vendorItem);
}
_session->SendPacket(perks.Write());
}
bool PerkProgramManager::IsAccountWideItem(uint32 item)
{
bool level = false;
if (auto i = sPerkProgramDataStore->GetVendorItem(item))
{
switch (i->CategoryId)
{
case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
level = true;
break;
default:
break;
}
}
return level;
}
bool PerkProgramManager::IsItemAlreadyOwned(PerkProgramData::PerkVendorItem const* vendorItem)
{
if (!vendorItem)
return true;
switch (vendorItem->CategoryId)
{
case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
return m_player->GetSession()->GetCollectionMgr()->HasToy(vendorItem->ToyItem);
// case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
// return m_player->GetMountCollection()->Has(vendorItem->MountSpellID);
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
// return m_player->GetSession()->GetCollectionMgr()->HasTransmogSet(vendorItem->TransmogSet);
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
// return m_player->GetSession()->GetCollectionMgr()->HasItemAppearance(vendorItem->ItemModifiedAppearanceID);
// case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
// return m_player->GetBattlePetCollection()->HasPet(vendorItem->PetSpellID);
default:
break;
}
return false;
}
void PerkProgramManager::GrantItem(PerkProgramData::PerkVendorItem const* vendorItem)
{
if (!vendorItem)
return;
switch (vendorItem->CategoryId)
{
case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
{
m_player->GetSession()->GetCollectionMgr()->AddToy(vendorItem->ToyItem, false, false);
break;
}
case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
{
m_player->LearnSpell(vendorItem->MountSpellID, false);
break;
}
case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
{
m_player->GetSession()->GetCollectionMgr()->AddTransmogSet(vendorItem->TransmogSet);
break;
}
case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
{
m_player->GetSession()->GetCollectionMgr()->AddItemAppearance(vendorItem->ItemModifiedAppearanceID);
break;
}
case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
{
// m_player->AddBattlePet(vendorItem->PetSpellID);
break;
}
case PerkPrograms::PERKS_VENDOR_CATEGORY_CONSUMABLES:
{
m_player->AddItem(vendorItem->ItemID, 1);
break;
}
default:
break;
}
}
void PerkProgramManager::RemoveGrantedItem(PerkProgramData::PerkVendorItem const* vendorItem)
{
if (!vendorItem)
return;
switch (vendorItem->CategoryId)
{
case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
break;
case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
m_player->RemoveSpell(vendorItem->MountSpellID, false, true);
break;
case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
break;
case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
break;
case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
break;
case PerkPrograms::PERKS_VENDOR_CATEGORY_CONSUMABLES:
m_player->DestroyItemCount(vendorItem->ItemID, 1, true);
break;
default:
break;
}
}
void PerkProgramManager::BuyItem(uint32 itemId, ObjectGuid /*vendor*/)
{
auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
if (!vendorItem)
{
SendPerksProgramError(1);
return;
}
if (m_currencyAmount < vendorItem->Cost)
{
SendPerksProgramError(2);
return;
}
if (IsItemAlreadyOwned(vendorItem))
{
SendPerksProgramError(3);
return;
}
m_currencyAmount -= vendorItem->Cost;
m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, -static_cast<int32>(vendorItem->Cost));
GrantItem(vendorItem);
RecordPurchase(itemId, GameTime::GetGameTime());
SendBuyItemResult(itemId);
SendCurrencyRefresh();
}
void PerkProgramManager::SendBuyItemResult(int32 itemId)
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_BUY_ITEM;
perks.Params.BuyItem.VendorItemID = itemId;
WorldPackets::PerksProgram::JamTimePair time;
time.BuyTime = GameTime::GetGameTime();
time.VendorItemID = itemId;
perks.Params.BuyItem.TimePair.emplace_back(time);
_session->SendPacket(perks.Write());
}
void PerkProgramManager::SendCurrencyRefresh()
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::SendPerksProgramError(uint32 errorCode)
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_ERROR;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::RecordPurchase(uint32 itemId, time_t purchaseTime)
{
m_recentPurchases.push_back(std::make_pair(itemId, purchaseTime));
}
void PerkProgramManager::RefundItem(int32 itemId)
{
auto it = std::find_if(m_recentPurchases.begin(), m_recentPurchases.end(),
[itemId](std::pair<uint32, time_t> const& p) { return p.first == static_cast<uint32>(itemId); });
if (it == m_recentPurchases.end())
{
SendPerksProgramError(4);
return;
}
if (GameTime::GetGameTime() - it->second > REFUND_WINDOW_SECONDS)
{
SendPerksProgramError(5);
return;
}
auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
if (!vendorItem)
return;
RemoveGrantedItem(vendorItem);
m_currencyAmount += vendorItem->Cost;
m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, static_cast<int32>(vendorItem->Cost));
m_recentPurchases.erase(it);
SendRefundSuccess(itemId);
SendCurrencyRefresh();
}
void PerkProgramManager::SendRefundSuccess(int32 itemId)
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_REFUND_SUCCESS;
perks.Params.BuyItem.VendorItemID = itemId;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::CartCheckout(std::vector<uint32> const& vendorItemIDs)
{
uint32 totalCost = 0;
for (uint32 itemId : vendorItemIDs)
{
auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
if (!item)
{
SendPerksProgramError(1);
return;
}
totalCost += item->Cost;
}
if (m_currencyAmount < totalCost)
{
SendPerksProgramError(2);
return;
}
for (uint32 itemId : vendorItemIDs)
{
auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
if (!item)
continue;
if (IsItemAlreadyOwned(item))
continue;
m_currencyAmount -= item->Cost;
m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, -static_cast<int32>(item->Cost));
GrantItem(item);
RecordPurchase(itemId, GameTime::GetGameTime());
}
SendCartCheckoutSuccess();
SendCurrencyRefresh();
}
void PerkProgramManager::SendCartCheckoutSuccess()
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_PURCHASE_CART;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::SendPerksProgramStatus()
{
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::SendPendingRewards()
{
}
void PerkProgramManager::SetFrozenItem(int32 itemId, bool clear)
{
if (clear)
{
m_frozenItems.clear();
}
else
{
auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
if (item)
{
m_frozenItems.clear();
m_frozenItems.push_back(*item);
}
}
WorldPackets::PerksProgram::PerksProgramResult perks;
perks.Type = PerkPrograms::RESULT_FROZEN_ITEM;
_session->SendPacket(perks.Write());
}
void PerkProgramManager::AddTrackedActivity(uint32 activityId)
{
if (std::find(m_trackedActivities.begin(), m_trackedActivities.end(), activityId) == m_trackedActivities.end())
{
m_trackedActivities.push_back(activityId);
}
}
void PerkProgramManager::RemoveTrackedActivity(uint32 activityId)
{
auto it = std::find(m_trackedActivities.begin(), m_trackedActivities.end(), activityId);
if (it != m_trackedActivities.end())
{
m_trackedActivities.erase(it);
}
}
void PerkProgramManager::SendPerksProgramActivities()
{
WorldPackets::PerksProgram::PerksProgramActivityUpdate activity;
activity.TimeUntilStart = GameTime::GetGameTime();
// activity.TimeUntilEnd = sWorld->GetNextPerksProgramReset();
for (auto ac : sPerkProgramDataStore->GetActivities())
{
activity.ActivityIDs.push_back(ac.ActivityID);
}
_session->SendPacket(activity.Write());
}