• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Bronze Amulet

Dries390

Well-Known Member
Joined
Sep 8, 2007
Messages
91
Solutions
4
Reaction score
70
Hello everyone. I seem to be having issues with the attribute which protects against mana drain. The stat seems to have vanished and turned into holy resist! I have tried testing it with a non-GM character fighting a priestess and the amulet neither loses charges nor protects against mana burn. I have also tried creating an amulet with +death resistance, thinking that mana drain had perhaps become a death ability.

XML:
<item id="2172" article="a" name="bronze amulet">
        <attribute key="weight" value="500" />
        <attribute key="slotType" value="necklace" />
        <attribute key="charges" value="200" />
        <attribute key="showcharges" value="1" />
        <attribute key="absorbPercentManaDrain" value="20" />
        <attribute key="showattributes" value="1" />
    </item>
I am using Nekiro's TFS 1.3 downport for 8.60 with Delusion's abilities.

Here is more information on the sources I'm using.


This has got me stumped, could anyone possible point me in the correct direction (src) to try and see where the problem is?

Edit: absorbPercentLifeDrain converts to + ice protection, absorbPercentManaDrain converts to +holy protection. Holy, ice and death protection do not show up on items.
Edit2: absorbPercentAll correctly protects against all elements, absorbPercentElements does not protect against ice, nor does absorbPercentMagic.
 

Attachments

Last edited:
Solution
I was able to fix manadrain, lifedrain, undefined damage and healing by editing the following sources (add the code between the dashes):

item.cpp
C++:
int64_t Item::getAbilityValue(itemAbilityTypes type) const
{
    const ItemType& it = Item::items[id];
    if ((!it.abilities && abilities) || (abilities && hasAbility(type))) {
        return getAbilityInt(type);
    }
    if (!it.abilities) {
        return 0;
    }
    switch (type) {
        case ITEM_ABILITY_HEALTHGAIN:
            return it.abilities->healthGain;
        case ITEM_ABILITY_HEALTHTICKS:
            return it.abilities->healthTicks;
        case ITEM_ABILITY_MANAGAIN:
            return it.abilities->manaGain;
        case ITEM_ABILITY_CONDITIONSUPPRESSIONS...
I've added some snippets of the source code but understanding all C++ is a bit above my paygrade. The code seems identical for all elements.

items.h
C++:
/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2018  Mark Samman <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef FS_ITEMS_H_4E2221634ABA45FE85BA50F710669B3C
#define FS_ITEMS_H_4E2221634ABA45FE85BA50F710669B3C

#include "const.h"
#include "enums.h"
#include "itemloader.h"
#include "position.h"

enum SlotPositionBits : uint32_t {
    SLOTP_WHEREEVER = 0xFFFFFFFF,
    SLOTP_HEAD = 1 << 0,
    SLOTP_NECKLACE = 1 << 1,
    SLOTP_BACKPACK = 1 << 2,
    SLOTP_ARMOR = 1 << 3,
    SLOTP_RIGHT = 1 << 4,
    SLOTP_LEFT = 1 << 5,
    SLOTP_LEGS = 1 << 6,
    SLOTP_FEET = 1 << 7,
    SLOTP_RING = 1 << 8,
    SLOTP_AMMO = 1 << 9,
    SLOTP_DEPOT = 1 << 10,
    SLOTP_TWO_HAND = 1 << 11,
    SLOTP_HAND = (SLOTP_LEFT | SLOTP_RIGHT)
};

enum ItemTypes_t {
    ITEM_TYPE_NONE,
    ITEM_TYPE_DEPOT,
    ITEM_TYPE_MAILBOX,
    ITEM_TYPE_TRASHHOLDER,
    ITEM_TYPE_CONTAINER,
    ITEM_TYPE_DOOR,
    ITEM_TYPE_MAGICFIELD,
    ITEM_TYPE_TELEPORT,
    ITEM_TYPE_BED,
    ITEM_TYPE_KEY,
    ITEM_TYPE_RUNE,
    ITEM_TYPE_LAST
};

enum ItemParseAttributes_t {
    ITEM_PARSE_TYPE,
    ITEM_PARSE_DESCRIPTION,
    ITEM_PARSE_RUNESPELLNAME,
    ITEM_PARSE_WEIGHT,
    ITEM_PARSE_SHOWCOUNT,
    ITEM_PARSE_ARMOR,
    ITEM_PARSE_DEFENSE,
    ITEM_PARSE_EXTRADEF,
    ITEM_PARSE_ATTACK,
    ITEM_PARSE_ROTATETO,
    ITEM_PARSE_MOVEABLE,
    ITEM_PARSE_BLOCKPROJECTILE,
    ITEM_PARSE_PICKUPABLE,
    ITEM_PARSE_FORCESERIALIZE,
    ITEM_PARSE_FLOORCHANGE,
    ITEM_PARSE_CORPSETYPE,
    ITEM_PARSE_CONTAINERSIZE,
    ITEM_PARSE_FLUIDSOURCE,
    ITEM_PARSE_READABLE,
    ITEM_PARSE_WRITEABLE,
    ITEM_PARSE_MAXTEXTLEN,
    ITEM_PARSE_WRITEONCEITEMID,
    ITEM_PARSE_WEAPONTYPE,
    ITEM_PARSE_SLOTTYPE,
    ITEM_PARSE_AMMOTYPE,
    ITEM_PARSE_SHOOTTYPE,
    ITEM_PARSE_EFFECT,
    ITEM_PARSE_RANGE,
    ITEM_PARSE_STOPDURATION,
    ITEM_PARSE_DECAYTO,
    ITEM_PARSE_TRANSFORMEQUIPTO,
    ITEM_PARSE_TRANSFORMDEEQUIPTO,
    ITEM_PARSE_DURATION,
    ITEM_PARSE_SHOWDURATION,
    ITEM_PARSE_CHARGES,
    ITEM_PARSE_SHOWCHARGES,
    ITEM_PARSE_SHOWATTRIBUTES,
    ITEM_PARSE_HITCHANCE,
    ITEM_PARSE_MAXHITCHANCE,
    ITEM_PARSE_INVISIBLE,
    ITEM_PARSE_SPEED,
    ITEM_PARSE_HEALTHGAIN,
    ITEM_PARSE_HEALTHTICKS,
    ITEM_PARSE_MANAGAIN,
    ITEM_PARSE_MANATICKS,
    ITEM_PARSE_MANASHIELD,
    ITEM_PARSE_SKILLSWORD,
    ITEM_PARSE_SKILLAXE,
    ITEM_PARSE_SKILLCLUB,
    ITEM_PARSE_SKILLDIST,
    ITEM_PARSE_SKILLFISH,
    ITEM_PARSE_SKILLSHIELD,
    ITEM_PARSE_SKILLFIST,
    ITEM_PARSE_MAXHITPOINTS,
    ITEM_PARSE_MAXHITPOINTSPERCENT,
    ITEM_PARSE_MAXMANAPOINTS,
    ITEM_PARSE_MAXMANAPOINTSPERCENT,
    ITEM_PARSE_MAGICPOINTS,
    ITEM_PARSE_MAGICPOINTSPERCENT,
    ITEM_PARSE_CRITICALHITCHANCE,
    ITEM_PARSE_CRITICALHITAMOUNT,
    ITEM_PARSE_HITPOINTSLEECHCHANCE,
    ITEM_PARSE_HITPOINTSLEECHAMOUNT,
    ITEM_PARSE_MANAPOINTSLEECHCHANCE,
    ITEM_PARSE_MANAPOINTSLEECHAMOUNT,
    ITEM_PARSE_FIELDABSORBPERCENTENERGY,
    ITEM_PARSE_FIELDABSORBPERCENTFIRE,
    ITEM_PARSE_FIELDABSORBPERCENTPOISON,
    ITEM_PARSE_ABSORBPERCENTALL,
    ITEM_PARSE_ABSORBPERCENTELEMENTS,
    ITEM_PARSE_ABSORBPERCENTMAGIC,
    ITEM_PARSE_ABSORBPERCENTENERGY,
    ITEM_PARSE_ABSORBPERCENTFIRE,
    ITEM_PARSE_ABSORBPERCENTPOISON,
    ITEM_PARSE_ABSORBPERCENTICE,
    ITEM_PARSE_ABSORBPERCENTHOLY,
    ITEM_PARSE_ABSORBPERCENTDEATH,
    ITEM_PARSE_ABSORBPERCENTLIFEDRAIN,
    ITEM_PARSE_ABSORBPERCENTMANADRAIN,
    ITEM_PARSE_ABSORBPERCENTDROWN,
    ITEM_PARSE_ABSORBPERCENTPHYSICAL,
    ITEM_PARSE_ABSORBPERCENTHEALING,
    ITEM_PARSE_ABSORBPERCENTUNDEFINED,
    ITEM_PARSE_SUPPRESSDRUNK,
    ITEM_PARSE_SUPPRESSENERGY,
    ITEM_PARSE_SUPPRESSFIRE,
    ITEM_PARSE_SUPPRESSPOISON,
    ITEM_PARSE_SUPPRESSDROWN,
    ITEM_PARSE_SUPPRESSPHYSICAL,
    ITEM_PARSE_SUPPRESSFREEZE,
    ITEM_PARSE_SUPPRESSDAZZLE,
    ITEM_PARSE_SUPPRESSCURSE,
    ITEM_PARSE_FIELD,
    ITEM_PARSE_REPLACEABLE,
    ITEM_PARSE_PARTNERDIRECTION,
    ITEM_PARSE_LEVELDOOR,
    ITEM_PARSE_MALETRANSFORMTO,
    ITEM_PARSE_FEMALETRANSFORMTO,
    ITEM_PARSE_TRANSFORMTO,
    ITEM_PARSE_DESTROYTO,
    ITEM_PARSE_ELEMENTICE,
    ITEM_PARSE_ELEMENTEARTH,
    ITEM_PARSE_ELEMENTFIRE,
    ITEM_PARSE_ELEMENTENERGY,
    ITEM_PARSE_WALKSTACK,
    ITEM_PARSE_BLOCKING,
    ITEM_PARSE_ALLOWDISTREAD,
};

struct Abilities {
    uint32_t healthGain = 0;
    uint32_t healthTicks = 0;
    uint32_t manaGain = 0;
    uint32_t manaTicks = 0;

    uint32_t conditionImmunities = 0;
    uint32_t conditionSuppressions = 0;

    //stats modifiers
    int32_t stats[STAT_LAST + 1] = { 0 };
    int32_t statsPercent[STAT_LAST + 1] = { 0 };

    //extra skill modifiers
    int32_t skills[SKILL_LAST + 1] = { 0 };
    int32_t specialSkills[SPECIALSKILL_LAST + 1] = { 0 };

    int32_t speed = 0;

    // field damage abilities modifiers
    int16_t fieldAbsorbPercent[COMBAT_COUNT] = { 0 };

    //damage abilities modifiers
    int16_t absorbPercent[COMBAT_COUNT] = { 0 };

    //elemental damage
    uint16_t elementDamage = 0;
    CombatType_t elementType = COMBAT_NONE;

    bool manaShield = false;
    bool invisible = false;
    bool regeneration = false;
};

class ConditionDamage;

class ItemType
{
    public:
        ItemType() = default;

        //non-copyable
        ItemType(const ItemType& other) = delete;
        ItemType& operator=(const ItemType& other) = delete;

        ItemType(ItemType&& other) = default;
        ItemType& operator=(ItemType&& other) = default;

        bool isGroundTile() const {
            return group == ITEM_GROUP_GROUND;
        }
        bool isContainer() const {
            return group == ITEM_GROUP_CONTAINER;
        }
        bool isSplash() const {
            return group == ITEM_GROUP_SPLASH;
        }
        bool isFluidContainer() const {
            return group == ITEM_GROUP_FLUID;
        }

        bool isDoor() const {
            return (type == ITEM_TYPE_DOOR);
        }
        bool isMagicField() const {
            return (type == ITEM_TYPE_MAGICFIELD);
        }
        bool isTeleport() const {
            return (type == ITEM_TYPE_TELEPORT);
        }
        bool isKey() const {
            return (type == ITEM_TYPE_KEY);
        }
        bool isDepot() const {
            return (type == ITEM_TYPE_DEPOT);
        }
        bool isMailbox() const {
            return (type == ITEM_TYPE_MAILBOX);
        }
        bool isTrashHolder() const {
            return (type == ITEM_TYPE_TRASHHOLDER);
        }
        bool isBed() const {
            return (type == ITEM_TYPE_BED);
        }
        bool isRune() const {
            return (type == ITEM_TYPE_RUNE);
        }
        bool isPickupable() const {
            return (allowPickupable || pickupable);
        }
        bool isUseable() const {
            return (useable);
        }
        bool hasSubType() const {
            return (isFluidContainer() || isSplash() || stackable || charges != 0);
        }

        Abilities& getAbilities() {
            if (!abilities) {
                abilities.reset(new Abilities());
            }
            return *abilities;
        }

        std::string getPluralName() const {
            if (!pluralName.empty()) {
                return pluralName;
            }

            if (showCount == 0) {
                return name;
            }

            std::string str;
            str.reserve(name.length() + 1);
            str.assign(name);
            str += 's';
            return str;
        }

        itemgroup_t group = ITEM_GROUP_NONE;
        ItemTypes_t type = ITEM_TYPE_NONE;
        uint16_t id = 0;
        uint16_t clientId = 0;
        bool stackable = false;

        std::string name;
        std::string article;
        std::string pluralName;
        std::string description;
        std::string runeSpellName;
        std::string vocationString;

        std::unique_ptr<Abilities> abilities;
        std::unique_ptr<ConditionDamage> conditionDamage;

        uint32_t weight = 0;
        uint32_t levelDoor = 0;
        uint32_t decayTime = 0;
        uint32_t wieldInfo = 0;
        uint32_t minReqLevel = 0;
        uint32_t minReqMagicLevel = 0;
        uint32_t charges = 0;
        int32_t maxHitChance = -1;
        int32_t decayTo = -1;
        int32_t attack = 0;
        int32_t defense = 0;
        int32_t extraDefense = 0;
        int32_t armor = 0;
        uint16_t rotateTo = 0;
        int32_t runeMagLevel = 0;
        int32_t runeLevel = 0;

        CombatType_t combatType = COMBAT_NONE;

        uint16_t transformToOnUse[2] = {0, 0};
        uint16_t transformToFree = 0;
        uint16_t destroyTo = 0;
        uint16_t maxTextLen = 0;
        uint16_t writeOnceItemId = 0;
        uint16_t transformEquipTo = 0;
        uint16_t transformDeEquipTo = 0;
        uint16_t maxItems = 8;
        uint16_t slotPosition = SLOTP_HAND;
        uint16_t speed = 0;
        uint16_t wareId = 0;

        MagicEffectClasses magicEffect = CONST_ME_NONE;
        Direction bedPartnerDir = DIRECTION_NONE;
        WeaponType_t weaponType = WEAPON_NONE;
        Ammo_t ammoType = AMMO_NONE;
        ShootType_t shootType = CONST_ANI_NONE;
        RaceType_t corpseType = RACE_NONE;
        FluidTypes_t fluidSource = FLUID_NONE;

        uint8_t floorChange = 0;
        uint8_t alwaysOnTopOrder = 0;
        uint8_t lightLevel = 0;
        uint8_t lightColor = 0;
        uint8_t shootRange = 1;
        int8_t hitChance = 0;

        bool forceUse = false;
        bool forceSerialize = false;
        bool hasHeight = false;
        bool walkStack = true;
        bool blockSolid = false;
        bool blockPickupable = false;
        bool blockProjectile = false;
        bool blockPathFind = false;
        bool allowPickupable = false;
        bool showDuration = false;
        bool showCharges = false;
        bool showAttributes = false;
        bool replaceable = true;
        bool pickupable = false;
        bool rotatable = false;
        bool useable = false;
        bool moveable = false;
        bool alwaysOnTop = false;
        bool canReadText = false;
        bool canWriteText = false;
        bool isVertical = false;
        bool isHorizontal = false;
        bool isHangable = false;
        bool allowDistRead = false;
        bool lookThrough = false;
        bool stopTime = false;
        bool showCount = true;
};

class Items
{
    public:
        using NameMap = std::unordered_multimap<std::string, uint16_t>;
        using InventoryVector = std::vector<uint16_t>;

        Items();

        // non-copyable
        Items(const Items&) = delete;
        Items& operator=(const Items&) = delete;

        bool reload();
        void clear();

        bool loadFromOtb(const std::string& file);

        const ItemType& operator[](size_t id) const {
            return getItemType(id);
        }
        const ItemType& getItemType(size_t id) const;
        ItemType& getItemType(size_t id);
        const ItemType& getItemIdByClientId(uint16_t spriteId) const;

        uint16_t getItemIdByName(const std::string& name);

        uint32_t majorVersion = 0;
        uint32_t minorVersion = 0;
        uint32_t buildNumber = 0;

        bool loadFromXml();
        void parseItemNode(const pugi::xml_node& itemNode, uint16_t id);

        void buildInventoryList();
        const InventoryVector& getInventory() const {
            return inventory;
        }

        size_t size() const {
            return items.size();
        }

        NameMap nameToItems;

    private:
        std::map<uint16_t, uint16_t> reverseItemMap;
        std::vector<ItemType> items;
        InventoryVector inventory;
};
#endif
items.cpp
C++:
case ITEM_PARSE_ABSORBPERCENTALL: {
                    int16_t value = pugi::cast<int16_t>(valueAttribute.value());
                    for (auto& i : abilities.absorbPercent) {
                        i += value;
                    }
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTELEMENTS: {
                    int16_t value = pugi::cast<int16_t>(valueAttribute.value());
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTMAGIC: {
                    int16_t value = pugi::cast<int16_t>(valueAttribute.value());
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTENERGY: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTFIRE: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTPOISON: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTICE: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTHOLY: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTDEATH: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTLIFEDRAIN: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTMANADRAIN: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTDROWN: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTPHYSICAL: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTHEALING: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }

                case ITEM_PARSE_ABSORBPERCENTUNDEFINED: {
                    abilities.absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
                    break;
                }
 
I was able to fix manadrain, lifedrain, undefined damage and healing by editing the following sources (add the code between the dashes):

item.cpp
C++:
int64_t Item::getAbilityValue(itemAbilityTypes type) const
{
    const ItemType& it = Item::items[id];
    if ((!it.abilities && abilities) || (abilities && hasAbility(type))) {
        return getAbilityInt(type);
    }
    if (!it.abilities) {
        return 0;
    }
    switch (type) {
        case ITEM_ABILITY_HEALTHGAIN:
            return it.abilities->healthGain;
        case ITEM_ABILITY_HEALTHTICKS:
            return it.abilities->healthTicks;
        case ITEM_ABILITY_MANAGAIN:
            return it.abilities->manaGain;
        case ITEM_ABILITY_CONDITIONSUPPRESSIONS:
            return it.abilities->conditionSuppressions;
        case ITEM_ABILITY_MAXHITPOINTS:
            return it.abilities->stats[STAT_MAXHITPOINTS];
        case ITEM_ABILITY_MAXMANAPOINTS:
            return it.abilities->stats[STAT_MAXMANAPOINTS];
        case ITEM_ABILITY_MAGICPOINTS:
            return it.abilities->stats[STAT_MAGICPOINTS];
        case ITEM_ABILITY_MAXHITPOINTSPERCENT:
            return it.abilities->statsPercent[STAT_MAXHITPOINTS];
        case ITEM_ABILITY_MAXMANAPOINTSPERCENT:
            return it.abilities->statsPercent[STAT_MAXMANAPOINTS];
        case ITEM_ABILITY_MAGICPOINTSPERCENT:
            return it.abilities->statsPercent[STAT_MAGICPOINTS];
        case ITEM_ABILITY_SKILLFIST:
            return it.abilities->skills[SKILL_FIST];
        case ITEM_ABILITY_SKILLCLUB:
            return it.abilities->skills[SKILL_CLUB];
        case ITEM_ABILITY_SKILLSWORD:
            return it.abilities->skills[SKILL_SWORD];
        case ITEM_ABILITY_SKILLAXE:
            return it.abilities->skills[SKILL_AXE];
        case ITEM_ABILITY_SKILLDISTANCE:
            return it.abilities->skills[SKILL_DISTANCE];
        case ITEM_ABILITY_SKILLSHIELD:
            return it.abilities->skills[SKILL_SHIELD];
        case ITEM_ABILITY_SKILLFISHING:
            return it.abilities->skills[SKILL_FISHING];
        case ITEM_ABILITY_CRITICALHITCHANCE:
            return it.abilities->specialSkills[SPECIALSKILL_CRITICALHITCHANCE];
        case ITEM_ABILITY_CRITICALHITAMOUNT:
            return it.abilities->specialSkills[SPECIALSKILL_CRITICALHITAMOUNT];
        case ITEM_ABILITY_LIFELEECHCHANCE:
            return it.abilities->specialSkills[SPECIALSKILL_HITPOINTSLEECHCHANCE];
        case ITEM_ABILITY_LIFELEECHAMOUNT:
            return it.abilities->specialSkills[SPECIALSKILL_HITPOINTSLEECHAMOUNT];
        case ITEM_ABILITY_MANALEECHCHANCE:
            return it.abilities->specialSkills[SPECIALSKILL_MANAPOINTSLEECHCHANCE];
        case ITEM_ABILITY_MANALEECHAMOUNT:
            return it.abilities->specialSkills[SPECIALSKILL_MANAPOINTSLEECHAMOUNT];
        case ITEM_ABILITY_SPEED:
            return it.abilities->speed;
        case ITEM_ABILITY_ABSORBPHYSICAL:
            return it.abilities->absorbPercent[0];
        case ITEM_ABILITY_ABSORBENERGY:
            return it.abilities->absorbPercent[1];
        case ITEM_ABILITY_ABSORBEARTH:
            return it.abilities->absorbPercent[2];
        case ITEM_ABILITY_ABSORBFIRE:
            return it.abilities->absorbPercent[3];
        case ITEM_ABILITY_ABSORBWATER:
            return it.abilities->absorbPercent[4];
        case ITEM_ABILITY_ABSORBICE:
            return it.abilities->absorbPercent[5];
        case ITEM_ABILITY_ABSORBHOLY:
            return it.abilities->absorbPercent[6];
        case ITEM_ABILITY_ABSORBDEATH:
            return it.abilities->absorbPercent[7];
-----------------------------------------------------------------------------------------
        case ITEM_ABILITY_UNDEFINEDDAMAGE:
            return it.abilities->absorbPercent[8];
        case ITEM_ABILITY_LIFEDRAIN:
            return it.abilities->absorbPercent[9];
        case ITEM_ABILITY_MANADRAIN:
            return it.abilities->absorbPercent[10];
        case ITEM_ABILITY_HEALING:
            return it.abilities->absorbPercent[11];
-----------------------------------------------------------------------------------------
        case ITEM_ABILITY_FIELDABSORBPHYSICAL:
            return it.abilities->fieldAbsorbPercent[0];
        case ITEM_ABILITY_FIELDABSORBENERGY:
            return it.abilities->fieldAbsorbPercent[1];
        case ITEM_ABILITY_FIELDABSORBEARTH:
            return it.abilities->fieldAbsorbPercent[2];
        case ITEM_ABILITY_FIELDABSORBFIRE:
            return it.abilities->fieldAbsorbPercent[3];
        case ITEM_ABILITY_FIELDABSORBWATER:
            return it.abilities->fieldAbsorbPercent[4];
        case ITEM_ABILITY_FIELDABSORBICE:
            return it.abilities->fieldAbsorbPercent[5];
        case ITEM_ABILITY_FIELDABSORBHOLY:
            return it.abilities->fieldAbsorbPercent[6];
        case ITEM_ABILITY_FIELDABSORBDEATH:
            return it.abilities->fieldAbsorbPercent[7];
        case ITEM_ABILITY_ELEMENTTYPE:
            return it.abilities->elementType;
        case ITEM_ABILITY_ELEMENTDAMAGE:
            return it.abilities->elementDamage;
        case ITEM_ABILITY_MANASHIELD:
            return static_cast<int64_t>(it.abilities->manaShield);
        case ITEM_ABILITY_INVISIBLE:
            return static_cast<int64_t>(it.abilities->invisible);
        case ITEM_ABILITY_REGENERATION:
            return static_cast<int64_t>(it.abilities->regeneration);
        default:
            return 0;
    }
}
enums.h
C++:
enum itemAbilityTypes : uint64_t {
    ITEM_ABILITY_NONE,
    ITEM_ABILITY_HEALTHGAIN = 1 << 0,
    ITEM_ABILITY_HEALTHTICKS = 1 << 1,
    ITEM_ABILITY_MANAGAIN = 1 << 2,
    ITEM_ABILITY_MANATICKS = 1 << 3,
    ITEM_ABILITY_CONDITIONSUPPRESSIONS = 1 << 4,
    ITEM_ABILITY_MAXHITPOINTS = 1 << 5,
    ITEM_ABILITY_MAXMANAPOINTS = 1 << 6,
    ITEM_ABILITY_MAGICPOINTS = 1 << 7,
    ITEM_ABILITY_MAXHITPOINTSPERCENT = 1 << 8,
    ITEM_ABILITY_MAXMANAPOINTSPERCENT = 1 << 9,
    ITEM_ABILITY_MAGICPOINTSPERCENT = 1 << 10,
    ITEM_ABILITY_SKILLFIST = 1 << 11,
    ITEM_ABILITY_SKILLCLUB = 1 << 12,
    ITEM_ABILITY_SKILLSWORD = 1 << 13,
    ITEM_ABILITY_SKILLAXE = 1 << 14,
    ITEM_ABILITY_SKILLDISTANCE = 1 << 15,
    ITEM_ABILITY_SKILLSHIELD = 1 << 16,
    ITEM_ABILITY_SKILLFISHING = 1 << 17,
    ITEM_ABILITY_CRITICALHITCHANCE = 1 << 18,
    ITEM_ABILITY_CRITICALHITAMOUNT = 1 << 19,
    ITEM_ABILITY_LIFELEECHCHANCE = 1 << 20,
    ITEM_ABILITY_LIFELEECHAMOUNT = 1 << 21,
    ITEM_ABILITY_MANALEECHCHANCE = 1 << 22,
    ITEM_ABILITY_MANALEECHAMOUNT = 1 << 23,
    ITEM_ABILITY_SPEED = 1 << 24,
    ITEM_ABILITY_ABSORBPHYSICAL = 1 << 25,
    ITEM_ABILITY_ABSORBENERGY = 1 << 26,
    ITEM_ABILITY_ABSORBEARTH = 1 << 27,
    ITEM_ABILITY_ABSORBFIRE = 1 << 28,
    ITEM_ABILITY_ABSORBWATER = 1 << 29,
    ITEM_ABILITY_ABSORBICE = 1 << 30,
    ITEM_ABILITY_ABSORBHOLY = 1ULL << 31,
    ITEM_ABILITY_ABSORBDEATH = 1ULL << 32,
    ITEM_ABILITY_FIELDABSORBPHYSICAL = 1ULL << 33,
    ITEM_ABILITY_FIELDABSORBENERGY = 1ULL << 34,
    ITEM_ABILITY_FIELDABSORBEARTH = 1ULL << 35,
    ITEM_ABILITY_FIELDABSORBFIRE = 1ULL << 36,
    ITEM_ABILITY_FIELDABSORBWATER = 1ULL << 37,
    ITEM_ABILITY_FIELDABSORBICE = 1ULL << 38,
    ITEM_ABILITY_FIELDABSORBHOLY = 1ULL << 39,
    ITEM_ABILITY_FIELDABSORBDEATH = 1ULL << 40,
    ITEM_ABILITY_ELEMENTTYPE = 1ULL << 41,
    ITEM_ABILITY_ELEMENTDAMAGE = 1ULL << 42,
    ITEM_ABILITY_MANASHIELD = 1ULL << 43,
    ITEM_ABILITY_INVISIBLE = 1ULL << 44,
    ITEM_ABILITY_REGENERATION = 1ULL << 45,
-----------------------------------------------------------------------------------------
    ITEM_ABILITY_UNDEFINEDDAMAGE = 1ULL << 46,
    ITEM_ABILITY_LIFEDRAIN = 1ULL << 47,
    ITEM_ABILITY_MANADRAIN = 1ULL << 48,
    ITEM_ABILITY_HEALING = 1ULL << 49
-----------------------------------------------------------------------------------------
};

tools.cpp
C++:
itemAbilityTypes combatToAbsorb(CombatType_t combatType)
{
    switch (combatType) {
        case COMBAT_PHYSICALDAMAGE:
            return ITEM_ABILITY_ABSORBPHYSICAL;
        case COMBAT_ENERGYDAMAGE:
            return ITEM_ABILITY_ABSORBENERGY;
        case COMBAT_EARTHDAMAGE:
            return ITEM_ABILITY_ABSORBEARTH;
        case COMBAT_FIREDAMAGE:
            return ITEM_ABILITY_ABSORBFIRE;
        case COMBAT_DROWNDAMAGE:
            return ITEM_ABILITY_ABSORBWATER;
        case COMBAT_ICEDAMAGE:
            return ITEM_ABILITY_ABSORBICE;
        case COMBAT_HOLYDAMAGE:
            return ITEM_ABILITY_ABSORBHOLY;
        case COMBAT_DEATHDAMAGE:
            return ITEM_ABILITY_ABSORBDEATH;
-----------------------------------------------------------------------------------------
        case COMBAT_LIFEDRAIN:
            return ITEM_ABILITY_LIFEDRAIN;
        case COMBAT_MANADRAIN:
            return ITEM_ABILITY_MANADRAIN;
        case COMBAT_UNDEFINEDDAMAGE:
            return ITEM_ABILITY_UNDEFINEDDAMAGE;
        case COMBAT_HEALING:
            return ITEM_ABILITY_HEALING;
-----------------------------------------------------------------------------------------
        default:
            return ITEM_ABILITY_NONE;
    }
}
So I guess that's that. Don't think I can give myself best answer so this can be locked or whatever.
 
Solution
Back
Top