From 40acbedfacda8aca7ebec19799abcd9398e16146 Mon Sep 17 00:00:00 2001 From: ElimarCosta Date: Tue, 24 Jan 2023 20:27:56 -0300 Subject: [PATCH] fix --- data/items/items.xml | 10 +-- src/creatures/players/player.cpp | 59 ++++++++++++++++- src/creatures/players/player.h | 18 +++-- src/server/network/protocol/protocolgame.cpp | 70 ++++---------------- 4 files changed, 89 insertions(+), 68 deletions(-) diff --git a/data/items/items.xml b/data/items/items.xml index d8e56eee6a7..4cefc7c0b07 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -2,7 +2,7 @@ - + @@ -20752,7 +20752,7 @@ - + @@ -35287,7 +35287,7 @@ - + @@ -52606,7 +52606,7 @@ - + @@ -52664,7 +52664,7 @@ - + diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index cb9fd7c8c11..562edd41aa3 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -474,6 +474,7 @@ void Player::updateInventoryImbuement() for (auto item : getAllInventoryItems()) { // Iterate through all imbuement slots on the item + for (uint8_t slotid = 0; slotid < item->getImbuementSlot(); slotid++) { ImbuementInfo imbuementInfo; @@ -1363,7 +1364,7 @@ void Player::sendMarketEnter(uint32_t depotId) if (!client || this->getLastDepotId() == -1 || !depotId) { return; } - + client->sendMarketEnter(depotId); } @@ -3719,6 +3720,60 @@ std::vector Player::getInventoryItemsFromId(uint16_t itemId, bool ignore return itemVector; } +std::array Player::getFinalDamageReduction() const { + std::array combatReductionArray; + combatReductionArray.fill(0); + calculateDamageReductionFromEquipedItems(combatReductionArray); + for (int combatTypeIndex = 0; combatTypeIndex < COMBAT_COUNT; combatTypeIndex++) { + combatReductionArray[combatTypeIndex] = std::clamp(std::floor(combatReductionArray[combatTypeIndex]), -100, 100); + } + return combatReductionArray; +} + + +void Player::calculateDamageReductionFromEquipedItems(std::array &combatReductionArray) const { + for (uint8_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) { + Item *item = inventory[slot]; + if (item) { + calculateDamageReductionFromItem(combatReductionArray, item); + } + } +} + +void Player::calculateDamageReductionFromItem(std::array &combatReductionArray, Item *item) const { + for (uint16_t combatTypeIndex = 0; combatTypeIndex < COMBAT_COUNT; combatTypeIndex++) { + updateDamageReductionFromItemImbuement(combatReductionArray, item, combatTypeIndex); + updateDamageReductionFromItemAbility(combatReductionArray, item, combatTypeIndex); + } +} + +void Player::updateDamageReductionFromItemImbuement(std::array &combatReductionArray, Item *item, uint16_t combatTypeIndex) const { + for (uint8_t imbueSlotId = 0; imbueSlotId < item->getImbuementSlot(); imbueSlotId++) { + ImbuementInfo imbuementInfo; + if (item->getImbuementInfo(imbueSlotId, &imbuementInfo) && imbuementInfo.imbuement) { + int16_t imbuementAbsorption = imbuementInfo.imbuement->absorbPercent[combatTypeIndex]; + if(imbuementAbsorption != 0) { + combatReductionArray[combatTypeIndex] = calculateDamageReduction(combatReductionArray[combatTypeIndex], imbuementAbsorption); + } + } + } +} + +void Player::updateDamageReductionFromItemAbility(std::array &combatReductionArray, const Item *item, uint16_t combatTypeIndex) const { + if(!item) return; + const ItemType &itemType = Item::items[item->getID()]; + if (itemType.abilities) { + int16_t elementReduction = itemType.abilities->absorbPercent[combatTypeIndex]; + if (elementReduction != 0) { + combatReductionArray[combatTypeIndex] = calculateDamageReduction(combatReductionArray[combatTypeIndex], elementReduction); + } + } +} + +double_t Player::calculateDamageReduction(double_t currentTotal, int16_t resistance) const { + return (100 - currentTotal) / 100.0 * resistance + currentTotal; +} + std::vector Player::getAllInventoryItems(bool ignoreEquiped /*= false*/) const { std::vector itemVector; @@ -5973,7 +6028,7 @@ std::string Player::getBlessingsName() const std::ostringstream os; for (uint8_t i = 1; i <= 8; i++) { if (hasBlessing(i)) { - if (auto blessName = BlessingNames.find(static_cast(i)); + if (auto blessName = BlessingNames.find(static_cast(i)); blessName != BlessingNames.end()) { os << (*blessName).second; } else { diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index b1417e9f64b..57dd6664379 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -71,7 +71,7 @@ struct ForgeHistory { bool tierLoss = false; bool successCore = false; bool tierCore = false; - + std::string description; std::string firstItemName; std::string secondItemName; @@ -382,7 +382,7 @@ class Player final : public Creature, public Cylinder uint8_t getBlessingCount(uint8_t index) const { return blessings[index - 1]; } - std::string getBlessingsName() const; + std::string getBlessingsName() const; bool isOffline() const { return (getID() == 0); @@ -2085,7 +2085,7 @@ class Player final : public Creature, public Cylinder void forgeTransferItemTier(uint16_t donorItemId, uint8_t tier, uint16_t receiveItemId); void forgeResourceConversion(uint8_t action); void forgeHistory(uint8_t page) const; - + void sendOpenForge() const { if (client) @@ -2181,6 +2181,8 @@ class Player final : public Creature, public Cylinder void registerForgeHistoryDescription(ForgeHistory history); + std::map getEquippedItemsWithEnabledAbilitiesBySlot() const; + private: std::forward_list getMuteConditions() const; @@ -2521,7 +2523,15 @@ class Player final : public Creature, public Cylinder friend class MoveEvent; friend class BedItem; - account::Account *account_; + account::Account *account_; + + std::array getFinalDamageReduction() const; + void calculateDamageReductionFromEquipedItems(std::array &combatReductionMap) const; + void calculateDamageReductionFromItem(std::array &combatReductionMap, Item *item) const; + void updateDamageReductionFromItemImbuement(std::array &combatReductionMap, Item *item, uint16_t combatTypeIndex) const; + void updateDamageReductionFromItemAbility(std::array &combatReductionMap, const Item *item, uint16_t combatTypeIndex) const; + double_t calculateDamageReduction(double_t currentTotal, int16_t resistance) const; }; + #endif // SRC_CREATURES_PLAYERS_PLAYER_H_ diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 51336edbd32..9205e56032c 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -158,7 +158,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, const Item *item) } else if (it.isSplash() || it.isFluidContainer()) { - msg.addByte(static_cast(item->getFluidType())); + msg.addByte(static_cast(item->getFluidType())); } else if (it.isContainer()) { @@ -493,7 +493,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) } else { setChecksumMethod(CHECKSUM_METHOD_ADLER32); } - + version = msg.get(); // Protocol version @@ -3189,58 +3189,14 @@ void ProtocolGame::sendCyclopediaCharacterCombatStats() auto startCombats = msg.getBufferPosition(); msg.skipBytes(1); - alignas(16) int16_t absorbs[COMBAT_COUNT] = {}; - for (int32_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) - { - if (!player->isItemAbilityEnabled(static_cast(slot))) - { - continue; - } - - Item *item = player->getInventoryItem(static_cast(slot)); - if (!item) - { - continue; - } - - const ItemType &it = Item::items[item->getID()]; - if (!it.abilities) - { - continue; - } - - if (COMBAT_COUNT == 12) - { - absorbs[0] += it.abilities->absorbPercent[0]; - absorbs[1] += it.abilities->absorbPercent[1]; - absorbs[2] += it.abilities->absorbPercent[2]; - absorbs[3] += it.abilities->absorbPercent[3]; - absorbs[4] += it.abilities->absorbPercent[4]; - absorbs[5] += it.abilities->absorbPercent[5]; - absorbs[6] += it.abilities->absorbPercent[6]; - absorbs[7] += it.abilities->absorbPercent[7]; - absorbs[8] += it.abilities->absorbPercent[8]; - absorbs[9] += it.abilities->absorbPercent[9]; - absorbs[10] += it.abilities->absorbPercent[10]; - absorbs[11] += it.abilities->absorbPercent[11]; - } - else - { - for (size_t i = 0; i < COMBAT_COUNT; ++i) - { - absorbs[i] += it.abilities->absorbPercent[i]; - } - } - } - + const std::array &damageReduction = player->getFinalDamageReduction(); static const Cipbia_Elementals_t cipbiaCombats[] = {CIPBIA_ELEMENTAL_PHYSICAL, CIPBIA_ELEMENTAL_ENERGY, CIPBIA_ELEMENTAL_EARTH, CIPBIA_ELEMENTAL_FIRE, CIPBIA_ELEMENTAL_UNDEFINED, CIPBIA_ELEMENTAL_LIFEDRAIN, CIPBIA_ELEMENTAL_UNDEFINED, CIPBIA_ELEMENTAL_HEALING, CIPBIA_ELEMENTAL_DROWN, CIPBIA_ELEMENTAL_ICE, CIPBIA_ELEMENTAL_HOLY, CIPBIA_ELEMENTAL_DEATH}; - for (size_t i = 0; i < COMBAT_COUNT; ++i) - { - if (absorbs[i] != 0) - { + for (size_t i = 0; i < COMBAT_COUNT; ++i) { + int8_t finalDamage = damageReduction[i]; + if (finalDamage != 0) { msg.addByte(cipbiaCombats[i]); - msg.addByte(std::max(-100, std::min(100, absorbs[i]))); + msg.addByte(finalDamage); ++combats; } } @@ -4578,7 +4534,7 @@ void ProtocolGame::sendForgeHistory(uint8_t page) msg.addByte((history.bonus >= 1 && history.bonus < 8) ? 0x01 : 0x00); } } - + writeToOutputBuffer(msg); } @@ -6229,7 +6185,7 @@ void ProtocolGame::sendPreyData(const PreySlot* slot) msg.addByte(player->isPremium() ? 0x01 : 0x00); } else if (slot->state == PreyDataState_Inactive) { // Empty - } else if (slot->state == PreyDataState_Active) { + } else if (slot->state == PreyDataState_Active) { if (const MonsterType* mtype = g_monsters().getMonsterTypeByRaceId(slot->selectedRaceId)) { msg.addString(mtype->name); const Outfit_t outfit = mtype->info.outfit; @@ -7333,7 +7289,7 @@ void ProtocolGame::parseDepotSearchItemRequest(NetworkMessage &msg) if (Item::items[itemId].upgradeClassification > 0) { itemTier = msg.getByte(); } - + addGameTask(&Game::playerRequestDepotSearchItem, player->getID(), itemId, itemTier); } @@ -7345,7 +7301,7 @@ void ProtocolGame::parseRetrieveDepotSearch(NetworkMessage &msg) itemTier = msg.getByte(); } uint8_t type = msg.getByte(); - + addGameTask(&Game::playerRequestDepotSearchRetrieve, player->getID(), itemId, itemTier, type); } @@ -7359,7 +7315,7 @@ void ProtocolGame::parseOpenParentContainer(NetworkMessage &msg) void ProtocolGame::sendUpdateCreature(const Creature* creature) { if (!creature || !player) { - return; + return; } if (!canSee(creature)) @@ -7370,7 +7326,7 @@ void ProtocolGame::sendUpdateCreature(const Creature* creature) return; } - NetworkMessage msg; + NetworkMessage msg; msg.addByte(0x6B); msg.addPosition(creature->getPosition()); msg.addByte(static_cast(stackPos));