• 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

Amazing! :).
I'm using your system in my server, and Im trying to implement other scripts using the same logic, look:

if I use 'player:getSpecialSkill(SPECIALSKILL_MANAPOINTSLEECHCHANCE)' returns an error: attempt to call method 'getSpecialSkill' (a nil value)
but in sources this method exists, right? For example in Game.cpp:
uint16_t chance = attackerPlayer->getSpecialSkill(SPECIALSKILL_HITPOINTSLEECHCHANCE);

Could you help me?
 
that's not a part of my system, getSpecialSkill has never been a luascript function
why do you need it?
 
Hello @Vulcan_
First of all, great job and thank you for releasing it.

I've been doing some testing:
When using hit points, description doesnt show up.
Critical chance visually works fine, but doesnt seem to change damage.
Critical dmg doesnt show on description nor seems to work. (it doesnt add anything to critical dmg on client)
Tested many different ways absorbs and absorbfield, and none of them seem to work. (No reduction at all)

And thats all for now! Thank you!
 
Cannot edit my post.

Critical chance and critical AMOUNT works. (Your example was just wrong)
Did some more testing with absorbs and they dont work.
mana, health, mana% and health% doesnt show up on item description.

Everything else seems to work fine! Thanks!
 
Nice, this should be a part of official TFS source code!

I am impressed.

I think that OT world need classic TFS and second TFS based on "classic TFS" with many additional things like: item attributes, monster levels, reflections functions etc.

OTLand community may start idea like this, because now we have all to do this.
I read a lot opinions that OT community must choose new road, independent from new Tibia updates, so maybe this may be best way?

Ideas for new "prefix" for this project? [name] Forgotten Server ;)
 
After some more testing. Absorbtion doesnt work after this code is implemented.
Tested the server after implementing the and all absorbtions works fine.
After implementing this code, absorbtions are not working at all, even if they are added directly on items.xml

Hope it helps to fix the issue.
 
i doubt i'm going to bother fixing anything for a while just cause it's a hassle to set up the code again and recompile every time i change something
dont know why it doesnt work for you but i remember testing it 2-3 times before releasing it and tested different element types to absorb and they worked just fine
 
After some more testing. Absorbtion doesnt work after this code is implemented.
Tested the server after implementing the and all absorbtions works fine.
After implementing this code, absorbtions are not working at all, even if they are added directly on items.xml

Hope it helps to fix the issue.
Update: Add HP/MP to description, fix broken HP/MP %
good news: i did find a bug with hp/mp % with this while testing and fixed it, should work properly now
bad news (for you): i tested absorption again, it works just fine. (both with and without using the system, tested an item from items.xml only and after tested with absorb ability)
are you sure you have the item registered in movements that you're testing?
cause now i've tested 4~ times for absorption and it works
 
Update: Add HP/MP to description, fix broken HP/MP %
good news: i did find a bug with hp/mp % with this while testing and fixed it, should work properly now
bad news (for you): i tested absorption again, it works just fine. (both with and without using the system, tested an item from items.xml only and after tested with absorb ability)
are you sure you have the item registered in movements that you're testing?
cause now i've tested 4~ times for absorption and it works

Hello! Thanks for checking and doing some fixing! After revising the code, it may have something to do with TFS 1.2. I've revised everything, and tested many times, but still is not working, so its probably my TFS 1.2.

Anyway, thank you for your time and dedication, really appreciate it.
 
Is there any possibility to get current (from xml file) attributes(absorb etc) values, I want to add a random value to it via setAbility(x,y)
example
Code:
<item id="7900" article="a" name="magma monocle">
    <attribute key="weight" value="1000" />
    <attribute key="armor" value="5" />
    <attribute key="absorbPercentFire" value="10" />
    <attribute key="absorbPercentIce" value="-7" />
    <attribute key="slotType" value="head" />
    </item>
i wanna get 5% and add another 5% by using item

getAbility (key) returns the value that was previously assigned by setAbility (key, value), does not return the original value (which is defined in the XML file)
 
Is there any possibility to get current (from xml file) attributes(absorb etc) values, I want to add a random value to it via setAbility(x,y)
example
Code:
<item id="7900" article="a" name="magma monocle">
    <attribute key="weight" value="1000" />
    <attribute key="armor" value="5" />
    <attribute key="absorbPercentFire" value="10" />
    <attribute key="absorbPercentIce" value="-7" />
    <attribute key="slotType" value="head" />
    </item>
i wanna get 5% and add another 5% by using item

getAbility (key) returns the value that was previously assigned by setAbility (key, value), does not return the original value (which is defined in the XML file)
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 get all values = 0
used on

23:32 You see a magic plate armor (Arm:17, protection physical +6%, energy +6%, earth +6%, fire +6%, drown +6%, ice +6%, holy +6%, death +6%).
It weighs 85.00 oz.
Item ID: 2472
Position: 1615, 930, 5
Code:
            std::cout  << "Test 2: " << abilities.absorbPercent[0] << abilities.absorbPercent[1] << abilities.absorbPercent[2] << abilities.absorbPercent[3] << abilities.absorbPercent[4] << std::endl;
this code return code "Test 2: 00000"
 
Last edited:
@BUMP
This code work 4you @Stigma?
I must remove "const " because the code don't compile
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
\/
ItemType* itemType = getUserdata<ItemType>(L, 1);
 
I get all values = 0
used on

23:32 You see a magic plate armor (Arm:17, protection physical +6%, energy +6%, earth +6%, fire +6%, drown +6%, ice +6%, holy +6%, death +6%).
It weighs 85.00 oz.
Item ID: 2472
Position: 1615, 930, 5
Code:
            std::cout  << "Test 2: " << abilities.absorbPercent[0] << abilities.absorbPercent[1] << abilities.absorbPercent[2] << abilities.absorbPercent[3] << abilities.absorbPercent[4] << std::endl;
this code return code "Test 2: 00000"
You're testing that completely wrong by the way, combat enums don't go 0 1 2 3, they are bitshifted left by n, 1 << n.
How are you trying to test it ingame? You should be using something along the lines of
Lua:
ItemType("magic plate armor"):getAbility(ITEM_ABILITY_ABSORBPHYSICAL)
 
Back
Top