• 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!

Lua Function [TFS 1.3] Item abilities via Lua

If i try to sell items with abilities to Npcs, how put to ignored this new items?
 
If I were to ever work on this again, it'd be a complete rewrite to revscripts utilizing CustomAttributes to avoid writing direct serialization and open up infinite possibilities for abilities to be added instead of being limited to 64 bit flags.
You're welcome to share your improvements to the rest of the people here, I'm sure they'd be glad to have them.
What is the possibility to what you said in this message happens? Missing the coding streams... 😅
 
I think I found the fix for wrong saving in house.
In iomapserialize.cpp:
C++:
void IOMapSerialize::saveItem(PropWriteStream& stream, PropWriteStream& abilStream, const Item* item)
{
    const Container* container = item->getContainer();

    // Write ID & props
    stream.write<uint16_t>(item->getID());
    item->serializeAttr(stream);
    item->serializeAbility(abilStream);

    if (container) {
        // Hack our way into the attributes
        stream.write<uint8_t>(ATTR_CONTAINER_ITEMS);
        stream.write<uint32_t>(container->size());
        for (auto it = container->getReversedItems(), end = container->getReversedEnd(); it != end; ++it) {
            saveItem(stream, abilStream, *it);
        }
    }

    stream.write<uint8_t>(0x00); // attr end
    //abilStream.write<uint8_t>(0x00); // abil end
}

Under
C++:
item->serializeAbility(abilStream);
Put
C++:
abilStream.write<uint8_t>(0x00);

When it was unserializing the tiles there was nothing to make it stop and go for next item so it unserialized all in one item.
 
Engine: OTX 3.8 protocol 8.6

@Infernum Hi! I did everything, also added this
And this fixes (i had missing items.cpp lines same as that thread)
Also the two commits mentioned for 1.2
To OTX 3.8 (guess it is based on TFS 1.2), but having this errors on compile

First attempt
errores.png
Second attempt
2ndtry.png

Code:
1>..\src\items.cpp(640): error C2039: 'forceSerialize': is not a member of 'ItemType'
1>  d:\users\usuario\desktop\greed380\src\items.h(211): note: see declaration of 'ItemType'

Code:
1>..\src\game.cpp(3711): error C2660: 'Game::combatChangeMana': function does not take 3 arguments
1>..\src\game.cpp(3717): error C2065: 'CONST_ME_CRITICAL_DAMAGE': undeclared identifier

If I missed something, please help! :)
 
Last edited:
Engine: OTX 3.8 protocol 8.6

@Infernum Hi! I did everything, also added this
And this fixes (i had missing items.cpp lines same as that thread)
Also the two commits mentioned for 1.2
To OTX 3.8 (guess it is based on TFS 1.2), but having this errors on compile

First attempt
View attachment 57134
Second attempt
View attachment 57135

Code:
1>..\src\items.cpp(640): error C2039: 'forceSerialize': is not a member of 'ItemType'
1>  d:\users\usuario\desktop\greed380\src\items.h(211): note: see declaration of 'ItemType'

Code:
1>..\src\game.cpp(3711): error C2660: 'Game::combatChangeMana': function does not take 3 arguments
1>..\src\game.cpp(3717): error C2065: 'CONST_ME_CRITICAL_DAMAGE': undeclared identifier

If I missed something, please help! :)
this thread is old
 
this thread is old
A last question, i'm very noob at this.
If I don't have revscript system, for example, for files like this one
Code:
data/scripts/ItemAbilities/3_tempconditions.lua
I can add them on libs or other folders?

Otherwise, there's no chance to fix this reply, when I passed the code it looks so good I really was expecting it to work.
Was really intrested on

Infernum said:
For now, this only works with TFS 1.3. If you use 1.2 and still want to use this code you can apply this commit to your sources for critical and leech skills, this commit as well since it was pushed later
 
Don't have the time to completely finish this, but here's a skeleton on how you could do this (read every comment as well):
C++:
// Abilities reference here, this is what you need to access inside of getAbilityInt

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;
};

// items.h underneath public:
int getAbilityInt(itemAbilityTypes ability);

// items.cpp above Items::Items()
int getAbilityInt(itemAbilityTypes ability)
{
    Abilities& abilities = getAbilities();
    switch (ability) {
        case ITEM_ABILITY_NONE:
            return 0;

        case ITEM_ABILITY_ABSORBENERGY:
            return abilities.absorbPercent[COMBAT_ENERGYDAMAGE];

        // add the rest of the abliities here

        default:
            return 0;

    }
    return 0;
}

// luascript.h
static int luaItemTypeGetAbility(lua_State* L); // place underneath another itemType forward declaration

// luascript.cpp

registerMethod("ItemType", "getAbility", LuaScriptInterface::luaItemTypeGetAbility); // place where the rest of the itemType registerMethods are

int LuaScriptInterface::luaItemTypeGetAbility(lua_State* L) // place underneath any other itemType function definition
{
    // itemType:getAbility(ability)
    const ItemType* itemType = getUserdata<const ItemType>(L, 1);
    itemAbilityTypes ability;
    if (isNumber(L, 2)) {
        ability = getNumber<itemAbilityTypes>(L, 2);
    } else {
        ability = ITEM_ABILITY_NONE;
    }

    if (itemType) {
        lua_pushnumber(L, itemType->getAbilityInt(ability));
    } else {
        lua_pushnil(L);
    }

    return 1;
}
This would implement a function for the itemType class where you can use itemType:getAbility(ability enum) to return the default value loaded from items.xml. All you should need to do is add a case for every single enum available and access the Abilities struct (the struct i provided for reference at the top of the code).
I provided an example on how to get absorbPercent for energy damage inside. Follow that example for every other enum and there will be no problem.
If you don't want to bother I'll do this eventually since I forgot it, but if you do add all the cases I can review it and merge it so others could use it as well.
I followed everything, and I keep getting the following error when compiling:
Bash:
/home/jroma/forgottenserver-otclientv8/src/items.cpp: In function ‘int getAbilityInt(itemAbilityTypes)’:
/home/jroma/forgottenserver-otclientv8/src/items.cpp:1383:28: error: ‘getAbilities’ was not declared in this scope; did you mean ‘ItemAbilities’?
 1383 |     Abilities& abilities = getAbilities();
          |                                     ^~~~~~~~~~~~
          |                                     ItemAbilities

I pasted:
C++:
// items.h underneath public:
int getAbilityInt(itemAbilityTypes ability);

underneath 'public' of the class ItemType, is this ok? I did not understand which 'public' class ItemType or Items (I tried both, one at a time but same output). And by 'underneath' you mean just like this?
C++:
    public:
        int getAbilityInt(itemAbilityTypes ability);

I know that the error means 'getAbilities' is not declared, however it is defined in items.h (in the public ItemType class), please don't reply with it's not defined.
Anyways, I hope anyone can help me with this. Thanks in advance.

EDIT: Before appliyng these last changes cited here, I was able to compile everything without any error.
 
Last edited:
Back
Top