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

C++ DeEquip and Stackable items

Addams

OTMadness.com OTSes Services
Staff member
Board Moderator
Joined
Sep 29, 2009
Messages
2,920
Solutions
342
Reaction score
1,688
Location
Egypt
Is this how DeEquip is supposed to work with stackable items on TFS 1.4.2?
Shouldn't it only remove attributes when the whole stack is unEquipped?
Example: Using a normal spear for testing.
This is how it's added to items.xml:
XML:
<item id="2389" article="a" name="spear">
        <attribute key="weight" value="2000" />
        <attribute key="attack" value="25" />
        <attribute key="weaponType" value="distance" />
        <attribute key="shootType" value="spear" />
        <attribute key="maxhitpoints" value="500" />
        <attribute key="maxmanapoints" value="500" />
        <attribute key="maxHitChance" value="76" />
        <attribute key="range" value="3" />
        <attribute key="showattributes" value="1" />
</item>
This is how it's added to movements.xml:
XML:
<movevent event="Equip" itemid="2389" slot="hand" function="onEquipItem" />
<movevent event="DeEquip" itemid="2389" slot="hand" function="onDeEquipItem" />
Stackable and attributes.gif
I've tried to add some checks on Lua on a DeEquip script but nothing worked.
How can I make it to only remove attributes when the whole item stack is unEquipped?
 
Last edited:
You can do this through Globalevents:
Lua:
local config = {
    gainedHealth = 500,
    gainedMana = 500,
    itemId = 2389,
    slot = CONST_SLOT_LEFT,
}

local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, config.gainedHealth)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANA, config.gainedMana)

function onThink(interval)
    for _, cid in ipairs(getPlayersOnline()) do
        local item = getPlayerSlotItem(cid, config.slot)
        if item and item.itemid == config.itemId then
            doAddCondition(cid, condition)
        else
            doRemoveCondition(cid, condition)
        end
    end
    return true
end

Also you can do this through Login:
Lua:
local config = {
    gainedHealth = 500,
    gainedMana = 500,
    itemId = 2389,
    slot = CONST_SLOT_LEFT,
}

local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, config.gainedHealth)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANA, config.gainedMana)

function checkSpear(cid)
    if isPlayer(cid) then
        local item = getPlayerSlotItem(cid, config.slot)
        if item and item.itemid == config.itemId then
            doAddCondition(cid, condition)
        else
            doRemoveCondition(cid, condition)
        end
        addEvent(checkSpear, 250, cid)
    end
end

function onLogin(cid)
    checkSpear(cid)
end
 
You can do this through Globalevents:
Lua:
local config = {
    gainedHealth = 500,
    gainedMana = 500,
    itemId = 2389,
    slot = CONST_SLOT_LEFT,
}

local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, config.gainedHealth)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANA, config.gainedMana)

function onThink(interval)
    for _, cid in ipairs(getPlayersOnline()) do
        local item = getPlayerSlotItem(cid, config.slot)
        if item and item.itemid == config.itemId then
            doAddCondition(cid, condition)
        else
            doRemoveCondition(cid, condition)
        end
    end
    return true
end
Thank you. But, I did a quick/slight edit to this one and then tried it, It has its own issues.
It will keep adding MAXHITPOINTS and MAXMANAPOINTS to the player, and it won't remove the conditions.
I am sure there'll be more issues so I prefer a fix for the normal DeEquip one, Not a workaround.
and also using conditions is so limited on attributes, Health and mana were just for testing sakes and I may need to add different/custom attributes.
Healing myself and then it keeps re-adding the MAXHITPOINTS.
TestThink.gif
That's the script after my edit.
Lua:
local testSpears = GlobalEvent("testSpears")
local config = {
    gainedHealth = 500,
    gainedMana = 500,
    itemId = 2389,
    slot = CONST_SLOT_LEFT
}

local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, -1)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, config.gainedHealth)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANAPOINTS, config.gainedMana)

function testSpears.onThink(interval)
    for _, player in pairs(Game.getPlayers()) do
        local item = player:getSlotItem(config.slot)
        if item and item.itemid == config.itemId then
            if not player:getCondition(condition) then
                player:addCondition(condition)
            end
        elseif player:getCondition(condition) then
            player:removeCondition(condition)
        end
    end
    return true
end

testSpears:interval(1000)
testSpears:register()
Also you can do this through Login:
Lua:
local config = {
    gainedHealth = 500,
    gainedMana = 500,
    itemId = 2389,
    slot = CONST_SLOT_LEFT,
}

local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTS, config.gainedHealth)
condition:setParameter(CONDITION_PARAM_STAT_MAXMANA, config.gainedMana)

function checkSpear(cid)
    if isPlayer(cid) then
        local item = getPlayerSlotItem(cid, config.slot)
        if item and item.itemid == config.itemId then
            doAddCondition(cid, condition)
        else
            doRemoveCondition(cid, condition)
        end
        addEvent(checkSpear, 250, cid)
    end
end

function onLogin(cid)
    checkSpear(cid)
end
Here it's worse, It will only check once onLogin and will never remove the condition unless player logged out/died.
So I didn't bother testing in-game.
 
Last edited:
Replace those

C++:
const ItemType& it = Item::items[item->getID()];
if (it.stackable && player->getInventoryItem(slot)) {
    return RETURNVALUE_NOERROR;
}

player->setItemAbility(slot, false);
 
Solution
Last edited:
Replace those

C++:
const ItemType& it = Item::items[item->getID()];
if (it.stackable && player->getInventoryItem(slot)) {
    return RETURNVALUE_NOERROR;
}

player->setItemAbility(slot, false);
Thank you. As always works perfectly!
Was the mark as solution option removed? I cannot find it anymore.
Only the upvote and downvote are there.
Solutionremove.PNG
 
Back
Top