From eea48441a225e71d49ca35481e75b05d22f27b49 Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Fri, 12 Apr 2024 11:28:45 -0300 Subject: [PATCH] badge & title system: fixes. --- data/scripts/lib/register_titles.lua | 22 ++++++++-------- .../players/cyclopedia/player_title.cpp | 4 +-- .../players/cyclopedia/player_title.hpp | 9 +++---- src/creatures/players/player.cpp | 14 +++++----- src/creatures/players/player.hpp | 4 +-- src/game/game.cpp | 4 +-- src/game/game.hpp | 26 +++++++++---------- src/game/game_definitions.hpp | 3 ++- src/server/network/protocol/protocolgame.cpp | 24 +++++++++-------- src/server/network/protocol/protocolgame.hpp | 2 +- 10 files changed, 56 insertions(+), 56 deletions(-) diff --git a/data/scripts/lib/register_titles.lua b/data/scripts/lib/register_titles.lua index 7aa54d55bbf..53e3efd5e60 100644 --- a/data/scripts/lib/register_titles.lua +++ b/data/scripts/lib/register_titles.lua @@ -167,17 +167,17 @@ Functions: TitleSystem:questFunction(player, storage, isKv) ]] -for _, titleTable in pairs(TITLES) do - if type(titleTable) == "table" and #titleTable > 0 then - for __, item in pairs(titleTable) do - if item.id then - local title = not item.names and { male = item.name, female = item.name } or { male = item.names.male, female = item.names.female } - logger.trace("[Title System registration] - Registering title '{}' with id '{}'", title.male, title.id) - Game.registerTitle(item.id, title.male, title.female, item.description, item.permanent) - end - end - end -end +--for _, titleTable in pairs(TITLES) do +-- if type(titleTable) == "table" and #titleTable > 0 then +-- for __, item in pairs(titleTable) do +-- if item.id then +-- local title = not item.names and { male = item.name, female = item.name } or { male = item.names.male, female = item.names.female } +-- logger.trace("[Title System registration] - Registering title '{}' with id '{}'", title.male, title.id) +-- Game.registerTitle(item.id, title.male, title.female, item.description, item.permanent) +-- end +-- end +-- end +--end ---- Gold section --TitleSystem.goldFunction = function(player, amount) diff --git a/src/creatures/players/cyclopedia/player_title.cpp b/src/creatures/players/cyclopedia/player_title.cpp index 77e5ce6c032..04ec4420d7a 100644 --- a/src/creatures/players/cyclopedia/player_title.cpp +++ b/src/creatures/players/cyclopedia/player_title.cpp @@ -24,7 +24,7 @@ bool PlayerTitle::isTitleUnlocked(uint8_t id) const { } if (auto it = std::find_if(m_titlesUnlocked.begin(), m_titlesUnlocked.end(), [id](auto title_it) { - return title_it == id; + return title_it.first == id; }); it != m_titlesUnlocked.end()) { return true; @@ -81,7 +81,7 @@ void PlayerTitle::loadUnlockedTitles() { g_logger().debug("[{}] - Loading unlocked titles: {}", __FUNCTION__, unlockedTitles.size()); for (const auto &uTitle : unlockedTitles) { auto id = static_cast(std::stoul(uTitle)); - const Title &title = g_game().getTitleById(static_cast(id)); + const Title &title = g_game().getTitleById(id); if (title.m_id == 0) { g_logger().error("[{}] - Title {} not found.", __FUNCTION__, uTitle); continue; diff --git a/src/creatures/players/cyclopedia/player_title.hpp b/src/creatures/players/cyclopedia/player_title.hpp index 4fe3f494575..17a6af6f9c0 100644 --- a/src/creatures/players/cyclopedia/player_title.hpp +++ b/src/creatures/players/cyclopedia/player_title.hpp @@ -24,10 +24,10 @@ struct TitleStorage { }; struct Title { - uint8_t m_id; - CyclopediaTitleType_t m_type; + uint8_t m_id = 0; + CyclopediaTitleType_t m_type = CyclopediaTitleType_t::NOTHING; std::string m_maleName; - std::string m_femaleName = ""; + std::string m_femaleName; std::string m_description; uint32_t m_amount = 0; bool m_permanent = false; @@ -37,9 +37,6 @@ struct Title { Title() = default; - Title(uint8_t id, CyclopediaTitleType_t type, const std::string &maleName, const std::string &description, uint32_t amount) : - m_id(id), m_type(type), m_maleName(maleName), m_description(description), m_amount(amount) { } - Title(uint8_t id, CyclopediaTitleType_t type, const std::string &maleName, const std::string &description, uint32_t amount, bool permanent) : m_id(id), m_type(type), m_maleName(maleName), m_description(description), m_amount(amount), m_permanent(permanent) { } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index ceacf55531e..6d52841dc1e 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -139,8 +139,8 @@ std::string Player::getDescription(int32_t lookDistance) { s << " You are a " << loyaltyTitle << "."; } - if (summary()->getCurrentTitle() != 0) { - s << " You are a " << summary()->getCurrentTitleName() << "."; + if (title()->getCurrentTitle() != 0) { + s << " You are a " << title()->getCurrentTitleName() << "."; } if (isVip()) { @@ -171,8 +171,8 @@ std::string Player::getDescription(int32_t lookDistance) { s << " " << subjectPronoun << " " << getSubjectVerb() << " " << article << " " << loyaltyTitle << "."; } - if (summary()->getCurrentTitle() != 0) { - s << " " << subjectPronoun << " " << getSubjectVerb() << " a " << summary()->getCurrentTitleName() << "."; + if (title()->getCurrentTitle() != 0) { + s << " " << subjectPronoun << " " << getSubjectVerb() << " a " << title()->getCurrentTitleName() << "."; } if (isVip()) { @@ -2864,9 +2864,9 @@ void Player::death(std::shared_ptr lastHitCreature) { description << "Killed " << getName() << '.'; CyclopediaCharacterInfo_RecentKillStatus_t status = unfairFightReduction != 100 ? CYCLOPEDIA_CHARACTERINFO_RECENTKILLSTATUS_UNJUSTIFIED : CYCLOPEDIA_CHARACTERINFO_RECENTKILLSTATUS_JUSTIFIED; if (lastHitCreature && lastHitCreature->getPlayer()) { - lastHitCreature->getPlayer()->summary()->insertPvpKillOnHistory(std::move(description.str()), OTSYS_TIME() / 1000, status); + lastHitCreature->getPlayer()->cyclopedia()->insertPvpKillOnHistory(std::move(description.str()), OTSYS_TIME() / 1000, status); } else if (lastHitCreature && lastHitCreature->getMaster() && lastHitCreature->getMaster()->getPlayer()) { - lastHitCreature->getMaster()->getPlayer()->summary()->insertPvpKillOnHistory(std::move(description.str()), OTSYS_TIME() / 1000, status); + lastHitCreature->getMaster()->getPlayer()->cyclopedia()->insertPvpKillOnHistory(std::move(description.str()), OTSYS_TIME() / 1000, status); } } else { description << "Died at Level " << getLevel() << " by"; @@ -2883,7 +2883,7 @@ void Player::death(std::shared_ptr lastHitCreature) { } description << '.'; - getPlayer()->summary()->insertDeathOnHistory(std::move(description.str()), OTSYS_TIME() / 1000); + getPlayer()->cyclopedia()->insertDeathOnHistory(std::move(description.str()), OTSYS_TIME() / 1000); } sendStats(); diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 27301ead0b6..81ae6c84c67 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -1666,9 +1666,9 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendCyclopediaCharacterBadges(); } } - void sendCyclopediaCharacterTitles(std::map titles) { + void sendCyclopediaCharacterTitles() { if (client) { - client->sendCyclopediaCharacterTitles(titles); + client->sendCyclopediaCharacterTitles(); } } void sendHighscoresNoData() { diff --git a/src/game/game.cpp b/src/game/game.cpp index bea4bf3a433..bfc8f9cd4f9 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -10503,7 +10503,7 @@ std::map Game::getAchievements() { // // } -const Badge Game::getBadgeById(uint8_t id) { +Badge Game::getBadgeById(uint8_t id) { auto it = std::find_if(m_badges.begin(), m_badges.end(), [id](const Badge &b) { return b.m_id == id; }); @@ -10517,7 +10517,7 @@ std::unordered_set Game::getBadges() { return m_badges; } -const Title Game::getTitleById(uint8_t id) { +Title Game::getTitleById(uint8_t id) { auto it = std::find_if(m_titles.begin(), m_titles.end(), [id](const Title &t) { return t.m_id == id; }); diff --git a/src/game/game.hpp b/src/game/game.hpp index 23e9b41311a..8da122fae78 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -722,7 +722,7 @@ class Game { std::map getAchievements(); // void registerBadge(uint8_t id, std::string name, uint16_t amount); - const Badge getBadgeById(uint8_t id); + Badge getBadgeById(uint8_t id); std::unordered_set getBadges(); // void registerTitle(uint8_t id, std::string maleName, std::string femaleName, std::string type, std::string description, bool permanent); @@ -764,9 +764,9 @@ class Game { std::map m_badgesNames; std::unordered_set m_titles = { - Title(1, CyclopediaTitleType_t::GOLD, "Gold Hoarder", "Earned at least 1,000,000 gold.", 1000000), - Title(2, CyclopediaTitleType_t::GOLD, "Platinum Hoarder", "Earned at least 10,000,000 gold.", 10000000), - Title(3, CyclopediaTitleType_t::GOLD, "Crystal Hoarder", "Earned at least 100,000,000 gold.", 100000000), + Title(1, CyclopediaTitleType_t::GOLD, "Gold Hoarder", "Earned at least 1,000,000 gold.", 1000000, false), + Title(2, CyclopediaTitleType_t::GOLD, "Platinum Hoarder", "Earned at least 10,000,000 gold.", 10000000, false), + Title(3, CyclopediaTitleType_t::GOLD, "Crystal Hoarder", "Earned at least 100,000,000 gold.", 100000000, false), Title(4, CyclopediaTitleType_t::MOUNTS, "Beaststrider (Grade 1)", "Unlocked 10 or more Mounts.", 10, true), Title(5, CyclopediaTitleType_t::MOUNTS, "Beaststrider (Grade 2)", "Unlocked 20 or more Mounts.", 20, true), @@ -780,13 +780,13 @@ class Game { Title(12, CyclopediaTitleType_t::OUTFITS, "Tibia's Topmodel (Grade 4)", "Unlocked 40 or more Outfits.", 40, true), Title(13, CyclopediaTitleType_t::OUTFITS, "Tibia's Topmodel (Grade 5)", "Unlocked 50 or more Outfits.", 50, true), - Title(14, CyclopediaTitleType_t::LEVEL, "Trolltrasher", "Reached level 50.", 50), - Title(15, CyclopediaTitleType_t::LEVEL, "Cyclopscamper", "Reached level 100.", 100), - Title(16, CyclopediaTitleType_t::LEVEL, "Dragondouser", "Reached level 200.", 200), - Title(17, CyclopediaTitleType_t::LEVEL, "Demondoom", "Reached level 300.", 300), - Title(18, CyclopediaTitleType_t::LEVEL, "Drakenbane", "Reached level 400.", 400), - Title(19, CyclopediaTitleType_t::LEVEL, "Silencer", "Reached level 500.", 500), - Title(20, CyclopediaTitleType_t::LEVEL, "Exalted", "Reached level 1000.", 1000), + Title(14, CyclopediaTitleType_t::LEVEL, "Trolltrasher", "Reached level 50.", 50, false), + Title(15, CyclopediaTitleType_t::LEVEL, "Cyclopscamper", "Reached level 100.", 100, false), + Title(16, CyclopediaTitleType_t::LEVEL, "Dragondouser", "Reached level 200.", 200, false), + Title(17, CyclopediaTitleType_t::LEVEL, "Demondoom", "Reached level 300.", 300, false), + Title(18, CyclopediaTitleType_t::LEVEL, "Drakenbane", "Reached level 400.", 400, false), + Title(19, CyclopediaTitleType_t::LEVEL, "Silencer", "Reached level 500.", 500, false), + Title(20, CyclopediaTitleType_t::LEVEL, "Exalted", "Reached level 1000.", 1000, false), Title(21, CyclopediaTitleType_t::HIGHSCORES, "Legend of Fishing", "", "Highest fishing level on character's world.", static_cast<uint8_t>(HighscoreCategories_t::FISHING)), Title(22, CyclopediaTitleType_t::HIGHSCORES, "Legend of Magic", "", "Highest magic level on character's world.", static_cast<uint8_t>(HighscoreCategories_t::MAGIC_LEVEL)), @@ -831,8 +831,8 @@ class Game { Title(58, CyclopediaTitleType_t::TASK, "Competent Beastslayer", "Invested 320,000 tasks points.", 320000, true), Title(59, CyclopediaTitleType_t::TASK, "Feared Bountyhunter", "Invested 430,000 tasks points.", 430000, true), - Title(60, CyclopediaTitleType_t::MAP, "Dedicated Entrepreneur", "Explored 50% of all the map areas.", 50), - Title(61, CyclopediaTitleType_t::MAP, "Globetrotter", "Explored all map areas.", 100), + Title(60, CyclopediaTitleType_t::MAP, "Dedicated Entrepreneur", "Explored 50% of all the map areas.", 50, false), + Title(61, CyclopediaTitleType_t::MAP, "Globetrotter", "Explored all map areas.", 100, false), Title(62, CyclopediaTitleType_t::QUEST, "Planegazer", "Followed the trail of the Planestrider to the end.", TitleStorage(1000, 1, false), true), Title(63, CyclopediaTitleType_t::QUEST, "Hero of Bounac", "You prevailed during the battle of Bounac and broke the siege that held Bounac's people in its firm grasp.", TitleStorage(1000, 1, false), true), diff --git a/src/game/game_definitions.hpp b/src/game/game_definitions.hpp index b6228f7bbde..cc9e07fbf2c 100644 --- a/src/game/game_definitions.hpp +++ b/src/game/game_definitions.hpp @@ -71,7 +71,8 @@ enum class CyclopediaBadgeType_t : uint8_t { }; enum class CyclopediaTitleType_t : uint8_t { - GOLD = 1, + NOTHING = 0, + GOLD, MOUNTS, OUTFITS, LEVEL, diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 7884f392166..09537adb47b 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -3900,10 +3900,10 @@ void ProtocolGame::sendCyclopediaCharacterInspection() { msg.addString(player->getVocation()->getVocName(), "ProtocolGame::sendCyclopediaCharacterInspection - player->getVocation()->getVocName()"); // Player title - if (player->summary()->getCurrentTitle() != 0) { + if (player->title()->getCurrentTitle() != 0) { playerDescriptionSize++; msg.addString("Title", "ProtocolGame::sendCyclopediaCharacterInspection - Title"); - msg.addString(player->summary()->getCurrentTitleName(), "ProtocolGame::sendCyclopediaCharacterInspection - player->summary()->getCurrentTitleName()"); + msg.addString(player->title()->getCurrentTitleName(), "ProtocolGame::sendCyclopediaCharacterInspection - player->title()->getCurrentTitleName()"); } // Loyalty title @@ -3989,7 +3989,7 @@ void ProtocolGame::sendCyclopediaCharacterBadges() { auto badgesSizePosition = msg.getBufferPosition(); msg.skipBytes(1); for (const auto &badge : g_game().getBadges()) { - if (player->summary()->hasBadge(badge.m_id)) { + if (player->badge()->hasBadge(badge.m_id)) { msg.add<uint32_t>(badge.m_id); msg.addString(badge.m_name, "ProtocolGame::sendCyclopediaCharacterBadges - name"); badgesSize++; @@ -4001,25 +4001,27 @@ void ProtocolGame::sendCyclopediaCharacterBadges() { writeToOutputBuffer(msg); } -void ProtocolGame::sendCyclopediaCharacterTitles(std::map<uint8_t, Title> titles) { +void ProtocolGame::sendCyclopediaCharacterTitles() { if (!player || oldProtocol) { return; } + auto titles = g_game().getTitles(); + NetworkMessage msg; msg.addByte(0xDA); msg.addByte(CYCLOPEDIA_CHARACTERINFO_TITLES); msg.addByte(0x00); // 0x00 Here means 'no error' - msg.addByte(player->summary()->getCurrentTitle()); + msg.addByte(player->title()->getCurrentTitle()); msg.addByte(static_cast<uint8_t>(titles.size())); std::string messageTitleName = "ProtocolGame::sendCyclopediaCharacterTitles - title.name"; std::string messageTitleDesc = "ProtocolGame::sendCyclopediaCharacterTitles - title.description"; - for (const auto title : titles) { - msg.addByte(title.first); - msg.addString(player->getSex() == PLAYERSEX_MALE ? title.second.maleName : title.second.femaleName, messageTitleName); - msg.addString(title.second.description, messageTitleDesc); - msg.addByte(title.second.permanent ? 0x01 : 0x00); - msg.addByte(player->achiev()->isUnlocked(title.first) ? 0x01 : 0x00); + for (const auto &title : titles) { + msg.addByte(title.m_id); + msg.addString(player->getSex() == PLAYERSEX_MALE ? title.m_maleName : title.m_femaleName, messageTitleName); + msg.addString(title.m_description, messageTitleDesc); + msg.addByte(title.m_permanent ? 0x01 : 0x00); + msg.addByte(player->title()->isTitleUnlocked(title.m_id) ? 0x01 : 0x00); } writeToOutputBuffer(msg); diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp index 593e30696b8..889bfaab595 100644 --- a/src/server/network/protocol/protocolgame.hpp +++ b/src/server/network/protocol/protocolgame.hpp @@ -323,7 +323,7 @@ class ProtocolGame final : public Protocol { void sendCyclopediaCharacterStoreSummary(); void sendCyclopediaCharacterInspection(); void sendCyclopediaCharacterBadges(); - void sendCyclopediaCharacterTitles(std::map<uint8_t, Title> titles); + void sendCyclopediaCharacterTitles(); void sendCreatureWalkthrough(std::shared_ptr<Creature> creature, bool walkthrough); void sendCreatureShield(std::shared_ptr<Creature> creature);