From 0e94f62a5e2701ce359bb032a80ed72598c69372 Mon Sep 17 00:00:00 2001 From: murilo09 <78226931+murilo09@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:11:48 -0300 Subject: [PATCH] refactor: exp loss logic --- src/creatures/players/player.cpp | 46 ++++++++++++-------- src/server/network/protocol/protocolgame.cpp | 13 +++--- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index dfdf467aa97..0be4990ff74 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -3480,7 +3480,7 @@ void Player::death(const std::shared_ptr &lastHitCreature) { uint64_t sumMana = 0; uint64_t lostMana = 0; - // sum up all the mana + // Sum up all the mana for (uint32_t i = 1; i <= magLevel; ++i) { sumMana += vocation->getReqMana(i); } @@ -3490,12 +3490,10 @@ void Player::death(const std::shared_ptr &lastHitCreature) { double deathLossPercent = getLostPercent() * (unfairFightReduction / 100.); // Charm bless bestiary - if (lastHitCreature && lastHitCreature->getMonster()) { - if (charmRuneBless != 0) { - const auto mType = g_monsters().getMonsterType(lastHitCreature->getName()); - if (mType && mType->info.raceid == charmRuneBless) { - deathLossPercent = (deathLossPercent * 90) / 100; - } + if (lastHitCreature && lastHitCreature->getMonster() && charmRuneBless != 0) { + const auto mType = g_monsters().getMonsterType(lastHitCreature->getName()); + if (mType && mType->info.raceid == charmRuneBless) { + deathLossPercent = (deathLossPercent * 90) / 100; } } @@ -3517,7 +3515,9 @@ void Player::death(const std::shared_ptr &lastHitCreature) { } // Level loss - auto expLoss = static_cast(experience * deathLossPercent); + auto expLoss = static_cast(std::ceil((experience * deathLossPercent) / 100.)); + g_logger().debug("[{}] - experience lost {}", __FUNCTION__, expLoss); + g_events().eventPlayerOnLoseExperience(static_self_cast(), expLoss); g_callbacks().executeCallback(EventCallback_t::playerOnLoseExperience, &EventCallback::playerOnLoseExperience, getPlayer(), expLoss); @@ -3526,9 +3526,9 @@ void Player::death(const std::shared_ptr &lastHitCreature) { lostExp << "You lost " << expLoss << " experience."; // Skill loss - for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { // for each skill + for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { // For each skill uint64_t sumSkillTries = 0; - for (uint16_t c = 11; c <= skills[i].level; ++c) { // sum up all required tries for all skill levels + for (uint16_t c = 11; c <= skills[i].level; ++c) { // Sum up all required tries for all skill levels sumSkillTries += vocation->getReqSkillTries(i, c); } @@ -3604,9 +3604,12 @@ void Player::death(const std::shared_ptr &lastHitCreature) { bless.empty() ? blessOutput << "You weren't protected with any blessings." : blessOutput << "You were blessed with " << bless; - // Make player lose bless + + const auto playerSkull = getSkull(); + bool hasSkull = (playerSkull == Skulls_t::SKULL_RED || playerSkull == Skulls_t::SKULL_BLACK); + // Remove player blessing uint8_t maxBlessing = 8; - if (pvpDeath && hasBlessing(1)) { + if (!hasSkull && pvpDeath && hasBlessing(1)) { removeBlessing(1, 1); // Remove TOF only } else { for (int i = 2; i <= maxBlessing; i++) { @@ -6298,21 +6301,30 @@ double Player::getLostPercent() const { return std::max(0, deathLosePercent) / 100.; } + bool isRetro = g_configManager().getBoolean(TOGGLE_SERVER_IS_RETRO); + const auto factor = (isRetro ? 6.31 : 8); + double percentReduction = (blessingCount * factor) / 100.; + double lossPercent; if (level >= 24) { const double tmpLevel = level + (levelPercent / 100.); lossPercent = ((tmpLevel + 50) * 50 * ((tmpLevel * tmpLevel) - (5 * tmpLevel) + 8)) / experience; } else { - lossPercent = 5; + percentReduction = (percentReduction >= 0.40 ? 0.50 : percentReduction); + lossPercent = 10; } - double percentReduction = 0; + g_logger().debug("[{}] - lossPercent {}", __FUNCTION__, lossPercent); + g_logger().debug("[{}] - before promotion {}", __FUNCTION__, percentReduction); + if (isPromoted()) { - percentReduction += 30; + percentReduction += 30 / 100.; + g_logger().debug("[{}] - after promotion {}", __FUNCTION__, percentReduction); } - percentReduction += blessingCount * 8; - return lossPercent * (1 - (percentReduction / 100.)) / 100.; + g_logger().debug("[{}] - total lost percent {}", __FUNCTION__, lossPercent - (lossPercent * percentReduction)); + + return lossPercent - (lossPercent * percentReduction); } [[nodiscard]] const std::string &Player::getGuildNick() const { diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 9c20db01cc4..0015b5e8a0f 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -4369,12 +4369,11 @@ void ProtocolGame::sendBlessingWindow() { msg.addByte(player->getBlessingCount(blessingValue, true)); } + // Start at "The Wisdom Of Solitude" uint8_t blessCount = 0; - for (int i = 1; i <= 8; i++) { + for (int i = 2; i <= 8; i++) { if (player->hasBlessing(i)) { - if (i > 1) { - blessCount++; - } + blessCount++; } } @@ -4421,11 +4420,9 @@ void ProtocolGame::sendBlessStatus() { // Ignore Twist of Fate (Id 1) uint8_t blessCount = 0; - for (int i = 1; i <= 8; i++) { + for (int i = 2; i <= 8; i++) { if (player->hasBlessing(i)) { - if (i > 1) { - blessCount++; - } + blessCount++; } }