Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
elsongabriel committed May 22, 2024
1 parent 659c659 commit 7d0e73e
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 102 deletions.
28 changes: 12 additions & 16 deletions data/modules/scripts/gamestore/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -400,13 +400,13 @@ end

-- Used on cyclopedia store summary
local function insertPlayerTransactionSummary(player, offer)
local offerId = offer.id
if offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL then
offerId = offerId - HIRELING_STORAGE.SKILL
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT then
offerId = offerId - HIRELING_STORAGE.OUTFIT
local id = offer.id
if offer.type == GameStore.OfferTypes.OFFER_TYPE_HOUSE then
id = offer.itemtype
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_BLESSINGS then
id = offer.blessid
end
player:createTransactionSummary(offer.type, math.max(1, offer.count), offer.itemtype or 0, offerId, offer.blessid or 0)
player:createTransactionSummary(offer.type, math.max(1, offer.count or 1), id)
end

function parseBuyStoreOffer(playerId, msg)
Expand Down Expand Up @@ -460,9 +460,7 @@ function parseBuyStoreOffer(playerId, msg)
-- Handled errors are thrown to indicate that the purchase has failed;
-- Handled errors have a code index and unhandled errors do not
local pcallOk, pcallError = pcall(function()
if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM then
GameStore.processItemPurchase(player, offer.itemtype, offer.count or 1, offer.movable, offer.setOwner)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM_UNIQUE then
if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM or offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM_UNIQUE then
GameStore.processItemPurchase(player, offer.itemtype, offer.count or 1, offer.movable, offer.setOwner)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS then
GameStore.processInstantRewardAccess(player, offer.count)
Expand All @@ -476,11 +474,9 @@ function parseBuyStoreOffer(playerId, msg)
GameStore.processPremiumPurchase(player, offer.id)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE then
GameStore.processStackablePurchase(player, offer.itemtype, offer.count, offer.name, offer.movable, offer.setOwner)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HOUSE then
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HOUSE or offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM_BED then
GameStore.processHouseRelatedPurchase(player, offer)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT then
GameStore.processOutfitPurchase(player, offer.sexId, offer.addon)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
GameStore.processOutfitPurchase(player, offer.sexId, offer.addon)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then
GameStore.processMountPurchase(player, offer.id)
Expand Down Expand Up @@ -514,8 +510,6 @@ function parseBuyStoreOffer(playerId, msg)
GameStore.processHirelingSkillPurchase(player, offer)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT then
GameStore.processHirelingOutfitPurchase(player, offer)
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM_BED then
GameStore.processHouseRelatedPurchase(player, offer)
else
-- This should never happen by our convention, but just in case the guarding condition is messed up...
error({ code = 0, message = "This offer is unavailable [2]" })
Expand All @@ -533,7 +527,9 @@ function parseBuyStoreOffer(playerId, msg)
return queueSendStoreAlertToUser(alertMessage, 500, playerId)
end

insertPlayerTransactionSummary(player, offer)
if table.contains({ GameStore.OfferTypes.OFFER_TYPE_HOUSE, GameStore.OfferTypes.OFFER_TYPE_EXPBOOST, GameStore.OfferTypes.OFFER_TYPE_PREYBONUS, GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, GameStore.OfferTypes.OFFER_TYPE_ALLBLESSINGS, GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS }, offer.type) then
insertPlayerTransactionSummary(player, offer)
end
local configure = useOfferConfigure(offer.type)
if configure ~= GameStore.ConfigureOffers.SHOW_CONFIGURE then
if not player:makeCoinTransaction(offer) then
Expand Down
64 changes: 34 additions & 30 deletions src/creatures/players/cyclopedia/player_cyclopedia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,21 @@ void PlayerCyclopedia::loadDeathHistory() {
g_logger().debug("Checking and updating death history of player {} took {} milliseconds.", m_player.getName(), bm_check.duration());
}

void PlayerCyclopedia::updateStoreSummary(uint8_t type, uint16_t count, uint8_t itemType, uint8_t offerId, uint8_t blessId) {
updateAmount(type, count);
void PlayerCyclopedia::updateStoreSummary(uint8_t type, uint16_t amount, uint16_t id) {
switch (type) {
case Summary_t::HOUSE_ITEMS:
case Summary_t::BLESSINGS:
insertValue(type, amount, id);
break;
case Summary_t::ALL_BLESSINGS:
for (int i = 1; i < 8; ++i) {
insertValue(static_cast<uint8_t>(Summary_t::BLESSINGS), amount, i);
}
break;
default:
updateAmount(type, amount);
break;
}
}

uint16_t PlayerCyclopedia::getAmount(uint8_t type) {
Expand Down Expand Up @@ -116,37 +129,28 @@ void PlayerCyclopedia::insertPvpKillOnHistory(std::string cause, uint32_t timest
m_pvpKillsHistory.emplace_back(std::move(cause), timestamp, status);
}

std::map<Blessings_t, uint16_t> PlayerCyclopedia::getBlessings() const {
}
void insertBlessings(uint8_t bless, uint32_t timestamp) {
}

std::vector<uint8_t> PlayerCyclopedia::getHirelingJobs() const {
}
void insertHirelingJobs(uint8_t job, uint32_t timestamp) {
}

std::vector<uint16_t> PlayerCyclopedia::getHirelingOutfits() const {
}
void insertHirelingOutfits(uint8_t outfit, uint32_t timestamp) {
Summary PlayerCyclopedia::getSummary() {
return { getAmount(Summary_t::BOOSTS), getAmount(Summary_t::PREY_CARDS), getAmount(Summary_t::INSTANT_REWARDS), getAmount(Summary_t::HIRELINGS) };
}

std::map<uint32_t, uint16_t> PlayerCyclopedia::getHouseItems() const {
auto type = static_cast<uint8_t>(Summary_t::HOUSE_ITEMS);
auto kvItem = m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type));

std::map<uint32_t, uint16_t> items = {};
for (const auto &itemId : kvItem->keys()) {
auto kv = kvItem->scoped(itemId)->get("amount");
auto amount = static_cast<uint16_t>(kv ? kv->getNumber() : 0);
items[std::stoull(itemId)] += amount;
std::map<uint16_t, uint16_t> PlayerCyclopedia::getResult(uint8_t type) const {
auto kvScope = m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type));
std::map<uint16_t, uint16_t> result = {};
for (const auto &id : kvScope->keys()) {
auto kv = kvScope->scoped(id)->get("amount");
result[std::stoull(id)] = static_cast<uint16_t>(kv ? kv->getNumber() : 0);
}

return items;
return result;
}

void PlayerCyclopedia::insertHouseItems(uint32_t itemId, uint16_t amount) {
auto type = static_cast<uint8_t>(Summary_t::HOUSE_ITEMS);
auto oldAmount = static_cast<uint16_t>(m_houseItems[itemId]);
m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type))->scoped(fmt::format("{}", itemId))->set("amount", oldAmount + amount);
void PlayerCyclopedia::insertValue(uint8_t type, uint16_t amount, uint16_t id) {
auto kv = m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type));
auto oldAmount = 0;
auto result = getResult(type);
auto it = result.find(id);
if (it != result.end()) {
oldAmount = it->second;
}
kv->scoped(fmt::format("{}", id))->set("amount", oldAmount + amount);
g_logger().info("type: {}, old: {}, amount: {}, newamount: {}, id: {}", type, oldAmount, amount, oldAmount + amount, id);
}
27 changes: 6 additions & 21 deletions src/creatures/players/cyclopedia/player_cyclopedia.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ struct Summary {
uint16_t m_xpBoosts = 0;
uint16_t m_preyWildcards = 0;
uint16_t m_instantRewards = 0;
uint16_t m_charmsExpansions = 0;
uint16_t m_hirelings = 0;

Summary(uint16_t mXpBoosts, uint16_t mPreyWildcards, uint16_t mInstantRewards, uint16_t mCharmsExpansions, uint16_t mHirelings) :
m_xpBoosts(mXpBoosts), m_preyWildcards(mPreyWildcards), m_instantRewards(mInstantRewards), m_charmsExpansions(mCharmsExpansions), m_hirelings(mHirelings) { }
Summary(uint16_t mXpBoosts, uint16_t mPreyWildcards, uint16_t mInstantRewards, uint16_t mHirelings) :
m_xpBoosts(mXpBoosts), m_preyWildcards(mPreyWildcards), m_instantRewards(mInstantRewards), m_hirelings(mHirelings) { }
};

class PlayerCyclopedia {
Expand All @@ -36,7 +35,7 @@ class PlayerCyclopedia {
void loadRecentKills();
void loadDeathHistory();

void updateStoreSummary(uint8_t type, uint16_t count = 1, uint8_t itemType = 0, uint8_t offerId = 0, uint8_t blessId = 0);
void updateStoreSummary(uint8_t type, uint16_t amount = 1, uint16_t id = 0);
uint16_t getAmount(uint8_t type);
void updateAmount(uint8_t type, uint16_t toAddPoints);

Expand All @@ -46,27 +45,13 @@ class PlayerCyclopedia {
[[nodiscard]] std::vector<RecentPvPKillEntry> getPvpKillsHistory() const;
void insertPvpKillOnHistory(std::string cause, uint32_t timestamp, uint8_t status);

const Summary &getSummary() {
return Summary(getAmount(Summary_t::BOOSTS), getAmount(Summary_t::PREY_WILDCARDS), getAmount(Summary_t::INSTANT_REWARDS), getAmount(Summary_t::CHARM_EXPANSIONS), getAmount(Summary_t::HIRELINGS));
}
[[nodiscard]] std::map<Blessings_t, uint16_t> getBlessings() const;
void insertBlessings(uint8_t bless, uint32_t timestamp);
Summary getSummary();

[[nodiscard]] std::vector<uint8_t> getHirelingJobs() const;
void insertHirelingJobs(uint8_t job, uint32_t timestamp);

[[nodiscard]] std::vector<uint16_t> getHirelingOutfits() const;
void insertHirelingOutfits(uint8_t outfit, uint32_t timestamp);

[[nodiscard]] std::map<uint32_t, uint16_t> getHouseItems() const;
void insertHouseItems(uint32_t itemId, uint16_t amount);
[[nodiscard]] std::map<uint16_t, uint16_t> getResult(uint8_t type) const;
void insertValue(uint8_t type, uint16_t amount = 1, uint16_t id = 0);

private:
std::vector<RecentDeathEntry> m_deathHistory;
std::vector<RecentPvPKillEntry> m_pvpKillsHistory;
std::map<Blessings_t, uint16_t> m_blessings;
std::vector<uint8_t> m_hirelingJobs;
std::vector<uint16_t> m_hirelingOutfits;
std::map<uint32_t, uint16_t> m_houseItems;
Player &m_player;
};
18 changes: 9 additions & 9 deletions src/enums/player_cyclopedia.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ enum CyclopediaTitle_t : uint8_t {
};

enum Summary_t : uint8_t {
BOOSTS = 1,
PREY_SLOTS,
PREY_WILDCARDS,
INSTANT_REWARDS,
CHARM_EXPANSIONS,
HIRELINGS,
HIRELING_JOBS,
HIRELING_OUTFITS,
HOUSE_ITEMS,
HOUSE_ITEMS = 9,
BOOSTS = 10,
PREY_CARDS = 12,
BLESSINGS = 14,
ALL_BLESSINGS = 17,
INSTANT_REWARDS = 18,
HIRELINGS = 20,
HIRELING_JOBS = 23,
HIRELING_OUTFITS = 24,
};
34 changes: 30 additions & 4 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,33 @@ Game::Game() {
};

m_summaryCategories = {
{ static_cast<uint8_t>(Summary_t::HOUSE_ITEMS), "house-items" },
{ static_cast<uint8_t>(Summary_t::BOOSTS), "xp-boosts" },
{ static_cast<uint8_t>(Summary_t::PREY_SLOTS), "prey-slots" },
{ static_cast<uint8_t>(Summary_t::PREY_WILDCARDS), "prey-wildcards" },
{ static_cast<uint8_t>(Summary_t::PREY_CARDS), "prey-cards" },
{ static_cast<uint8_t>(Summary_t::BLESSINGS), "blessings" },
{ static_cast<uint8_t>(Summary_t::INSTANT_REWARDS), "instant-rewards" },
{ static_cast<uint8_t>(Summary_t::CHARM_EXPANSIONS), "charm-expansions" },
{ static_cast<uint8_t>(Summary_t::HIRELINGS), "hirelings" },
{ static_cast<uint8_t>(Summary_t::HIRELING_JOBS), "hirelings-jobs" },
{ static_cast<uint8_t>(Summary_t::HIRELING_OUTFITS), "hireling-outfits" },
{ static_cast<uint8_t>(Summary_t::HOUSE_ITEMS), "house-items" },
};

m_hirelingSkills = {
{ 1001, "banker" },
{ 1002, "cooker" },
{ 1003, "steward" },
{ 1004, "trader" }
};

m_hirelingOutfits = {
{ 2001, "banker" },
{ 2002, "cooker" },
{ 2003, "steward" },
{ 2004, "trader" },
{ 2005, "servant" },
{ 2006, "hydra" },
{ 2007, "ferumbras" },
{ 2008, "bonelord" },
{ 2009, "dragon" },
};
}

Expand Down Expand Up @@ -10632,3 +10650,11 @@ Title Game::getTitleByName(const std::string &name) {
}
return {};
}

std::unordered_map<uint16_t, std::string> Game::getHirelingSkills() {
return m_hirelingSkills;
}

std::unordered_map<uint16_t, std::string> Game::getHirelingOutfits() {
return m_hirelingOutfits;
}
5 changes: 5 additions & 0 deletions src/game/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,9 @@ class Game {
return m_summaryCategories[type];
}

std::unordered_map<uint16_t, std::string> getHirelingSkills();
std::unordered_map<uint16_t, std::string> getHirelingOutfits();

private:
std::map<uint16_t, Achievement> m_achievements;
std::map<std::string, uint16_t> m_achievementsNameToId;
Expand All @@ -747,6 +750,8 @@ class Game {
std::unordered_map<uint8_t, std::string> m_highscoreCategoriesNames;

std::unordered_map<uint8_t, std::string> m_summaryCategories;
std::unordered_map<uint16_t, std::string> m_hirelingSkills;
std::unordered_map<uint16_t, std::string> m_hirelingOutfits;

std::map<uint32_t, int32_t> forgeMonsterEventIds;
std::unordered_set<uint32_t> fiendishMonsters;
Expand Down
11 changes: 5 additions & 6 deletions src/lua/functions/creatures/player/player_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4356,7 +4356,7 @@ int PlayerFunctions::luaPlayerSetCurrentTitle(lua_State* L) {
}

int PlayerFunctions::luaPlayerCreateTransactionSummary(lua_State* L) {
// player:createTransactionSummary(type, count[, itemType = 0[, offerId = 0[, blessId = 0]]])
// player:createTransactionSummary(type, amount[, id = 0])
const auto &player = getUserdataShared<Player>(L, 1);
if (!player) {
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
Expand All @@ -4369,12 +4369,11 @@ int PlayerFunctions::luaPlayerCreateTransactionSummary(lua_State* L) {
return 1;
}

auto count = getNumber<uint8_t>(L, 3, 1);
auto itemType = getNumber<uint8_t>(L, 4, 0);
auto offerId = getNumber<uint8_t>(L, 5, 0);
auto blessId = getNumber<uint8_t>(L, 6, 0);
auto amount = getNumber<uint16_t>(L, 3, 1);
auto id = getNumber<uint16_t>(L, 4, 0);

player->cyclopedia()->updateStoreSummary(type, count, itemType, offerId, blessId);
g_logger().info("type: {}, amount: {}, id: {}", type, amount, id);
player->cyclopedia()->updateStoreSummary(type, amount, id);
pushBoolean(L, true);
return 1;
}
48 changes: 32 additions & 16 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3942,9 +3942,11 @@ void ProtocolGame::sendCyclopediaCharacterStoreSummary() {
// getBlessingsObtained
auto blessings = player->getBlessingNames();
msg.addByte(static_cast<uint8_t>(blessings.size()));
for (const auto &it : blessings) {
msg.addString(it.second, "ProtocolGame::sendCyclopediaCharacterStoreSummary - blessing.name");
msg.addByte(static_cast<uint8_t>((player->cyclopedia()->getBlessings())[it.first]));
auto amountsByBlessing = player->cyclopedia()->getResult(static_cast<uint8_t>(Summary_t::BLESSINGS));
for (const auto &bless_it : blessings) {
msg.addString(bless_it.second, "ProtocolGame::sendCyclopediaCharacterStoreSummary - blessing.name");
msg.addByte(static_cast<uint8_t>(amountsByBlessing[bless_it.first]));
g_logger().info("bless id: {}, name: {}, found(count): {}", bless_it.first, bless_it.second, amountsByBlessing[bless_it.first]);
}

uint8_t preySlotsUnlocked = 0;
Expand All @@ -3959,25 +3961,39 @@ void ProtocolGame::sendCyclopediaCharacterStoreSummary() {
preySlotsUnlocked++;
}
msg.addByte(preySlotsUnlocked); // getPreySlotById + getTaskHuntingSlotById

msg.addByte(cyclopediaSummary.m_preyWildcards); // getPreyCardsObtained
msg.addByte(cyclopediaSummary.m_instantRewards); // getRewardCollectionObtained
msg.addByte(player->hasCharmExpansion() ? 0x01 : 0x00);
msg.addByte(cyclopediaSummary.m_hirelings); // getHirelingsObtained

auto jobs = player->cyclopedia()->getHirelingJobs();
msg.addByte(jobs.size());
for (const auto job_it : jobs) {
msg.addByte(job_it);
}

auto outfits = player->cyclopedia()->getHirelingOutfits();
msg.addByte(outfits.size());
for (const auto outfit_it : outfits) {
msg.addByte(outfit_it);
}
std::vector<uint16_t> m_hSkills;
for (const auto &it : g_game().getHirelingSkills()) {
if (player->kv()->scoped("hireling-skills")->get(it.second)) {
m_hSkills.emplace_back(it.first);
g_logger().info("skill id: {}, name: {}", it.first, it.second);
}
}
msg.addByte(m_hSkills.size());
for (const auto &id : m_hSkills) {
msg.addByte(id);
}

// std::vector<uint16_t> m_hOutfits;
// for (const auto &it : g_game().getHirelingOutfits()) {
// if (player->kv()->scoped("hireling-outfits")->get(it.second)) {
// m_hOutfits.emplace_back(it.first);
// g_logger().info("outfit id: {}, name: {}", it.first, it.second);
// }
// }
// msg.addByte(m_hOutfits.size());
// for (const auto &id : m_hOutfits) {
// msg.add<uint16_t>(id);
// // msg.addByte(id);
// }
msg.addByte(0x00);

auto houseItems = player->cyclopedia()->getHouseItems();
auto houseItems = player->cyclopedia()->getResult(static_cast<uint8_t>(Summary_t::HOUSE_ITEMS));
msg.add<uint16_t>(houseItems.size());
for (const auto &hItem_it : houseItems) {
const ItemType &it = Item::items[hItem_it.first];
Expand Down

0 comments on commit 7d0e73e

Please sign in to comment.