• 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.2] Enchant decay

Caduceus

Unknown Member
Joined
May 10, 2010
Messages
321
Solutions
2
Reaction score
24
I am having issues with my enchanting system. Specifically the rainbow shield. The gem enchants the item giving it a 20 min. duration. However, the time does not count down, unless you log out & back in. The item is registered in movements, before it is recommended. Is this a source issue or is there maybe something in lua that can resolve this?

items.xml
Code:
<item id="8906" article="a" name="fiery rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with fire magic and boosts your shielding skill." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="skillShield" value="2" />
        <attribute key="absorbPercentFire" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8907" article="an" name="icy rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with ice magic and has a greatly increased shielding value." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="skillShield" value="5" />
        <attribute key="absorbPercentIce" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8908" article="a" name="sparking rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with energy magic and increases your speed." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="speed" value="20" />
        <attribute key="absorbPercentEnergy" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8909" article="a" name="terran rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with earth magic and boosts your regeneration." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="37" />
        <attribute key="weaponType" value="shield" />
        <attribute key="healthGain" value="1" />
        <attribute key="healthTicks" value="3000" />
        <attribute key="manaGain" value="4" />
        <attribute key="manaTicks" value="3000" />
        <attribute key="absorbPercentEarth" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
 
Last edited:
I am having issues with my enchanting system. Specifically the rainbow shield. The gem enchants the item giving it a 20 min. duration. However, the time does not count down, unless you log out & back in. The item is registered in movements, before it is recommended. Is this a source issue or is there maybe something in lua that can resolve this?

items.xml
Code:
<item id="8906" article="a" name="fiery rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with fire magic and boosts your shielding skill." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="skillShield" value="2" />
        <attribute key="absorbPercentFire" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8907" article="an" name="icy rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with ice magic and has a greatly increased shielding value." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="skillShield" value="5" />
        <attribute key="absorbPercentIce" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8908" article="a" name="sparking rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with energy magic and increases your speed." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="40" />
        <attribute key="weaponType" value="shield" />
        <attribute key="speed" value="20" />
        <attribute key="absorbPercentEnergy" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
    <item id="8909" article="a" name="terran rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with earth magic and boosts your regeneration." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="37" />
        <attribute key="weaponType" value="shield" />
        <attribute key="healthGain" value="1" />
        <attribute key="healthTicks" value="3000" />
        <attribute key="manaGain" value="4" />
        <attribute key="manaTicks" value="3000" />
        <attribute key="absorbPercentEarth" value="20"/>
        <attribute key="showattributes" value="1" />
        <attribute key="duration" value="1200" />
        <attribute key="showduration" value="1" />
        <attribute key="decayTo" value="8905" />
    </item>
this is because when you transform an item, the game doesn't register you as equipping it.
so logging in/putting it back on will execute the onEquip and make it start counting down
as for solving this i don't know really if this is the best way to do it, but you can check if the player has it in the shield in their inventory, and you can tell them to take it off and return false, that way they are forced to have it off when they transform and have to equip it :)
 
equipping the item does not start decay. I have tried enchanting on ground, in inventory, & on player.. none of the above start decay, until player logs out & back in. Else enchant is infinite, until logout..
 
equiping the item does not start decay.
https://vvvulcan.s-ul.eu/rKa82Dd4
works completely fine for me o-o
it even decays if i dont equip it

items
Code:
    <item id="8906" article="a" name="fiery rainbow shield">
        <attribute key="description" value="It has been temporarily imbued with fire magic and boosts your shielding skill." />
        <attribute key="weight" value="6900" />
        <attribute key="defense" value="36" />
        <attribute key="weaponType" value="shield" />
        <attribute key="duration" value="3" />
        <attribute key="showattributes" value="1" />
        <attribute key="decayTo" value="8905" />
        <attribute key="skillShield" value="3" />
        <attribute key="stopduration" value="1" />
        <attribute key="showduration" value="1" />
    </item>
movements
Code:
<movevent event="Equip" itemid="8906" slot="shield" level="100" function="onEquipItem">
        <vocation name="Knight" />
        <vocation name="Elite Knight" showInDescription="0" />
    </movevent>
    <movevent event="DeEquip" itemid="8906" slot="shield" function="onDeEquipItem" />
 
ok, I added "target:decay()" when the target is transformed. so that fixed my shield decay issues. I also have an issue with the enchanted arrows. I am trying to add a duration to a single arrow, since I have them infinite. When the target is transformed, it decays fine. However when a player onDeEquip item, decay stops, until player logs out & back in. How can I make the decay rate never stop on that item as well? The item is recognized by the server as being deEquip/onEquip.



Code:
<movevent event="Equip" itemid="7838" slot="ammo" level="100" script="EquipItem.lua"/>
        <vocation name="Paladin"/>
        <vocation name="Royal Paladin" showInDescription="0"/>
    </movevent>
    <movevent event="DeEquipItem" itemid="7838" slot="ammo" script="DeEquip.lua"/>

script per each
Code:
function onEquip(player, item, slot)
    item:decay()
return true
end
 
function onDeEquip(player, item, slot)
    item:decay()
return true
end
 
Last edited:
show me your enchanting lua file
im sleepy but if I dont post it now I will forget it
you got 2 solutions
lua and c++
in lua you need to edit the part when you transform the item
example: https://github.com/orts/server/blob/master/data/actions/scripts/other/enchanting.lua#L129-L131
just edit the last part like this

Code:
target:transform(enchantedItems[target.itemid][targetId], subtype)
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        if target:hasAttribute(ITEM_ATTRIBUTE_DECAYSTATE) then
            target:decay()
        end
        item:remove(1)
or the better one version
search for
Code:
int LuaScriptInterface::luaItemTransform(lua_State* L)
and before the end of the function after
Code:
item = newItem;
add
Code:
    if (item && item->hasAttribute(ITEM_ATTRIBUTE_DECAYSTATE)) {
        g_game.startDecay(item);
    }

done, I guess (im learning c++, started a few days ago)
 
Last edited:
show me your enchanting lua file
original. I will have to try both methods, I suppose. Thank you.
Code:
local config = {
    manaCost = 300,
    soulCost = 10,
}

local spheres = {
    [7759] = {3, 7},
    [7760] = {1, 5},
    [7761] = {2, 6},
    [7762] = {4, 8}
}

local enchantableGems = {2147, 2146, 2149, 2150}
local enchantableItems = {2383, 7383, 7384, 7406, 7402, 2429, 2430, 7389, 7380, 2454, 2423, 2445, 7415, 7392, 2391, 7364, 8905}

local enchantingAltars = {
    {7504, 7505, 7506, 7507},
    {7508, 7509, 7510, 7511},
    {7516, 7517, 7518, 7519},
    {7512, 7513, 7514, 7515}
}

local enchantedGems = {7760, 7759, 7761, 7762}
local enchantedItems = {
    [2383] = {7744, 7763, 7854, 7869},
    [7383] = {7745, 7764, 7855, 7870},
    [7384] = {7746, 7765, 7856, 7871},
    [7406] = {7747, 7766, 7857, 7872},
    [7402] = {7748, 7767, 7858, 7873},
    [2429] = {7749, 7768, 7859, 7874},
    [2430] = {7750, 7769, 7860, 7875},
    [7389] = {7751, 7770, 7861, 7876},
    [7380] = {7752, 7771, 7862, 7877},
    [2454] = {7753, 7772, 7863, 7878},
    [2423] = {7754, 7773, 7864, 7879},
    [2445] = {7755, 7774, 7865, 7880},
    [7415] = {7756, 7775, 7866, 7881},
    [7392] = {7757, 7776, 7867, 7882},
    [2391] = {7758, 7777, 7868, 7883},
    [7364] = {7840, 7839, 7850, 7838},
    [8905] = {8906, 8907, 8909, 8908}
}
function table.find(tab, value)
    for i = 1, #tab do
        if tab[i] == value then
            return i
        end
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if isInArray({33268, 33269}, toPosition.x) and toPosition.y == 31830 and toPosition.z == 10 and player:getStorageValue(Storage.ElementalSphere.QuestLine) > 0 then
        if not isInArray(spheres[item.itemid], player:getVocation():getId()) then
            return true
        elseif isInArray({7915, 7916}, target.itemid) then
            player:say('Turn off the machine first.', TALKTYPE_MONSTER_SAY)
            return true
        else
            player:setStorageValue(Storage.ElementalSphere.MachineGemCount, math.max(1, player:getStorageValue(Storage.ElementalSphere.MachineGemCount) + 1))
            toPosition:sendMagicEffect(CONST_ME_PURPLEENERGY)
            item:transform(item.itemid, item.type - 1)
            return true
        end
    end

    if item.itemid == 7760 and target.itemid == 2342 then
        target:transform(2343)
        target:decay()
        item:remove(1)
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        return true
    end

    if item.itemid == 7760 and isInArray({9934, 10022}, target.itemid) then
        target:transform(9933)
        item:remove(1)
        toPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
        return true
    end

    if isInArray(enchantableGems, item.itemid) then
        local subtype = item.type
        if subtype == 0 then
            subtype = 1
        end

        local mana = config.manaCost * subtype
        if player:getMana() < mana then
            player:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA)
            return true
        end

        local soul = config.soulCost * subtype
        if player:getSoul() < soul then
            player:sendCancelMessage(RETURNVALUE_NOTENOUGHSOUL)
            return true
        end

        local targetId = table.find(enchantableGems, item.itemid)
        if not targetId or not isInArray(enchantingAltars[targetId], target.itemid) then
            return true
        end

        player:addMana(-mana)
        player:addSoul(-soul)
        item:transform(enchantedGems[targetId])
        player:addManaSpent(mana * configManager.getNumber(configKeys.RATE_MAGIC))
        player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE)
        return true
    end

    if item.itemid == 7761 and isInArray({9949, 9954}, target.itemid) then
        target:transform(target.itemid - 1)
        target:decay()
        item:remove(1)
        toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN)
        return true
    end

    if isInArray(enchantedGems, item.itemid) then
        if not isInArray(enchantableItems, target.itemid) then
            fromPosition:sendMagicEffect(CONST_ME_POFF)
            return true
        end

        local targetId = table.find(enchantedGems, item.itemid)
        if not targetId then
            return true
        end

        local subtype = target.type
        if not isInArray({7364, 8905}, target.itemid) then
            subtype = 1000
        end

        target:transform(enchantedItems[target.itemid][targetId], subtype)
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        target:decay()
        item:remove(1)
        return true
    end
    return true
end
 
original. I will have to try both methods, I suppose. Thank you.
Code:
local config = {
    manaCost = 300,
    soulCost = 10,
}

local spheres = {
    [7759] = {3, 7},
    [7760] = {1, 5},
    [7761] = {2, 6},
    [7762] = {4, 8}
}

local enchantableGems = {2147, 2146, 2149, 2150}
local enchantableItems = {2383, 7383, 7384, 7406, 7402, 2429, 2430, 7389, 7380, 2454, 2423, 2445, 7415, 7392, 2391, 7364, 8905}

local enchantingAltars = {
    {7504, 7505, 7506, 7507},
    {7508, 7509, 7510, 7511},
    {7516, 7517, 7518, 7519},
    {7512, 7513, 7514, 7515}
}

local enchantedGems = {7760, 7759, 7761, 7762}
local enchantedItems = {
    [2383] = {7744, 7763, 7854, 7869},
    [7383] = {7745, 7764, 7855, 7870},
    [7384] = {7746, 7765, 7856, 7871},
    [7406] = {7747, 7766, 7857, 7872},
    [7402] = {7748, 7767, 7858, 7873},
    [2429] = {7749, 7768, 7859, 7874},
    [2430] = {7750, 7769, 7860, 7875},
    [7389] = {7751, 7770, 7861, 7876},
    [7380] = {7752, 7771, 7862, 7877},
    [2454] = {7753, 7772, 7863, 7878},
    [2423] = {7754, 7773, 7864, 7879},
    [2445] = {7755, 7774, 7865, 7880},
    [7415] = {7756, 7775, 7866, 7881},
    [7392] = {7757, 7776, 7867, 7882},
    [2391] = {7758, 7777, 7868, 7883},
    [7364] = {7840, 7839, 7850, 7838},
    [8905] = {8906, 8907, 8909, 8908}
}
function table.find(tab, value)
    for i = 1, #tab do
        if tab[i] == value then
            return i
        end
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if isInArray({33268, 33269}, toPosition.x) and toPosition.y == 31830 and toPosition.z == 10 and player:getStorageValue(Storage.ElementalSphere.QuestLine) > 0 then
        if not isInArray(spheres[item.itemid], player:getVocation():getId()) then
            return true
        elseif isInArray({7915, 7916}, target.itemid) then
            player:say('Turn off the machine first.', TALKTYPE_MONSTER_SAY)
            return true
        else
            player:setStorageValue(Storage.ElementalSphere.MachineGemCount, math.max(1, player:getStorageValue(Storage.ElementalSphere.MachineGemCount) + 1))
            toPosition:sendMagicEffect(CONST_ME_PURPLEENERGY)
            item:transform(item.itemid, item.type - 1)
            return true
        end
    end

    if item.itemid == 7760 and target.itemid == 2342 then
        target:transform(2343)
        target:decay()
        item:remove(1)
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        return true
    end

    if item.itemid == 7760 and isInArray({9934, 10022}, target.itemid) then
        target:transform(9933)
        item:remove(1)
        toPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
        return true
    end

    if isInArray(enchantableGems, item.itemid) then
        local subtype = item.type
        if subtype == 0 then
            subtype = 1
        end

        local mana = config.manaCost * subtype
        if player:getMana() < mana then
            player:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA)
            return true
        end

        local soul = config.soulCost * subtype
        if player:getSoul() < soul then
            player:sendCancelMessage(RETURNVALUE_NOTENOUGHSOUL)
            return true
        end

        local targetId = table.find(enchantableGems, item.itemid)
        if not targetId or not isInArray(enchantingAltars[targetId], target.itemid) then
            return true
        end

        player:addMana(-mana)
        player:addSoul(-soul)
        item:transform(enchantedGems[targetId])
        player:addManaSpent(mana * configManager.getNumber(configKeys.RATE_MAGIC))
        player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE)
        return true
    end

    if item.itemid == 7761 and isInArray({9949, 9954}, target.itemid) then
        target:transform(target.itemid - 1)
        target:decay()
        item:remove(1)
        toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN)
        return true
    end

    if isInArray(enchantedGems, item.itemid) then
        if not isInArray(enchantableItems, target.itemid) then
            fromPosition:sendMagicEffect(CONST_ME_POFF)
            return true
        end

        local targetId = table.find(enchantedGems, item.itemid)
        if not targetId then
            return true
        end

        local subtype = target.type
        if not isInArray({7364, 8905}, target.itemid) then
            subtype = 1000
        end

        target:transform(enchantedItems[target.itemid][targetId], subtype)
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        target:decay()
        item:remove(1)
        return true
    end
    return true
end
i think its better
Code:
if target:hasAttribute(ITEM_ATTRIBUTE_DECAYSTATE) then
            target:decay()
        end
than just decay
 
Tried both methods. Still have same issue as before. Item stops decay the moment it is either equip or deEquip. Tried using default function="onEquipItem"|"onDeEquipItem" as movement as well.
 
Back
Top