• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFS 0.X [LUA/C++] Upgrade elemental damage on weapon

potinho

Advanced OT User
Joined
Oct 11, 2009
Messages
1,493
Solutions
17
Reaction score
187
Location
Brazil
Hello guys, i'm in correct way to create this upgrade system who add elemental damage on weapon? I'm using OTX2, it will necessary some C++ change? The script add description but weapon is not dealing elemental damage. Follow code:


LUA:
-- elementalupgrade.lua
-- Functional elemental enchantment for OTXServer 2

math.randomseed(os.time() % 0x7fffffff)

local elementalTypes = {
    [6402] = {name = "fire",   effect = CONST_ME_FIREAREA, combatType = COMBAT_FIREDAMAGE},
    [6398] = {name = "ice",    effect = CONST_ME_ICEATTACK, combatType = COMBAT_ICEDAMAGE},
    [6399] = {name = "earth",  effect = CONST_ME_SMALLPLANTS, combatType = COMBAT_EARTHDAMAGE},
    [6401] = {name = "death",  effect = CONST_ME_MORTAREA, combatType = COMBAT_DEATHDAMAGE},
    [6400] = {name = "energy", effect = CONST_ME_ENERGYHIT, combatType = COMBAT_ENERGYDAMAGE},
}

local successRates = {
    [1] = 100, [2] = 80, [3] = 60, [4] = 40, [5] = 20,
    [6] = 15, [7] = 10, [8] = 5, [9] = 3, [10] = 1
}

local MAX_LEVEL = 10

local function isWeapon(itemid)
    local info = getItemInfo(itemid)
    if not info then return false end
    if info.weaponType ~= nil then
        return info.weaponType ~= WEAPON_NONE
    end
    return (info.attack and info.attack > 0)
end

local function trim(s)
    return (s:gsub("^%s*(.-)%s*$", "%1"))
end

local function removeOldDesc(desc)
    return trim(desc:gsub("%(Atk:%s*%+%d+%s*%a+%)", ""))
end

-- Check if there's already an element of ANOTHER type
local function hasOtherElement(itemUid, currentGemName)
    for gemId, gemData in pairs(elementalTypes) do
        if gemData.name ~= currentGemName then
            local level = getItemAttribute(itemUid, gemData.name .. "_level")
            if level and tonumber(level) > 0 then
                return true
            end
        end
    end
    return false
end

-- Check if the weapon already has native element from XML
local function hasNativeElement(itemid)
    local info = getItemInfo(itemid)
    if not info then return false end
    
    -- Check if it already has some element defined in XML
    if info.elementType and info.elementType ~= COMBAT_PHYSICALDAMAGE then
        return true
    end
    
    return false
end

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local gem = elementalTypes[item.itemid]
    if not gem then return false end

    if not itemEx or itemEx.uid == 0 or not isWeapon(itemEx.itemid) then
        doPlayerSendCancel(cid, "You can only imbue weapons with gems.")
        return true
    end

    -- Check if the weapon already has native element in XML
    if hasNativeElement(itemEx.itemid) then
        doPlayerSendCancel(cid, "This weapon already has native elemental damage.")
        return true
    end

    -- Check if there's already an element of ANOTHER type
    if hasOtherElement(itemEx.uid, gem.name) then
        doPlayerSendCancel(cid, "This weapon already has another elemental damage.")
        return true
    end

    -- Level saved for THIS element
    local levelKey = gem.name .. "_level"
    local currentLevel = tonumber(getItemAttribute(itemEx.uid, levelKey)) or 0

    if currentLevel >= MAX_LEVEL then
        doPlayerSendCancel(cid, "This weapon already reached max "..gem.name.." level.")
        return true
    end

    local nextLevel = currentLevel + 1
    local chance = successRates[nextLevel] or 5

    if math.random(100) <= chance then
        -- Real bonus applied in combat
        local addDamage = math.random(3, 7)

        local currentDamage = tonumber(getItemAttribute(itemEx.uid, "elementDamage")) or 0
        local newDamage = currentDamage + addDamage

        -- Apply REAL engine attributes (according to weapons.cpp)
        doItemSetAttribute(itemEx.uid, "elementType", gem.combatType)  -- Combat type number
        doItemSetAttribute(itemEx.uid, "elementDamage", newDamage)     -- Damage amount

        -- Save custom level and current element type
        doItemSetAttribute(itemEx.uid, levelKey, nextLevel)
        doItemSetAttribute(itemEx.uid, "currentElement", gem.name)

        -- Description
        local oldDesc = getItemAttribute(itemEx.uid, "description") or ""
        oldDesc = removeOldDesc(oldDesc)
        if oldDesc ~= "" then oldDesc = oldDesc .. " " end
        doItemSetAttribute(itemEx.uid, "description",
            oldDesc .. "(Atk: +" .. newDamage .. " " .. gem.name .. ")")

        doSendMagicEffect(toPosition, gem.effect)

        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR,
            "Success! Level "..nextLevel.." +"..newDamage.." "..gem.name.." damage added.")
    else
        -- In case of failure, just inform - doesn't remove existing enchantments
        doSendMagicEffect(toPosition, CONST_ME_POFF)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR,
            "The gem failed to imbue your weapon at level "..nextLevel..".")
    end

    -- Remove the gem
    doRemoveItem(item.uid, 1)
    return true
end
 
Doing some research i've got the conclusion this only will work with some work on C++, if anyone can help me
 
Back
Top