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

Solved Multiple Conditions problem

Codinablack

Dreamer
Content Editor
Premium User
Joined
Dec 26, 2013
Messages
1,383
Solutions
7
Reaction score
508
Ok so I'm trying to make a customequipment system to release here on otland. While working on it, I did some testing, as some of the conditions worked, but I wanted to make sure all were... and man, I got a big problem. I have two examples in the .xml file it reads from, two swords, one applies the sword skill condition perfectly, the other doesn't, in fact, the one with the problem literally has four conditions, that all seem to have been applied (because I use a print counter to test), but only one gets applied, and that is the distance skill

zelda sword, applies haste, and sword skill condition without any problem,

blade of the ruined king only applies one of its four conditions from what the client shows, and that is the distance skill

what is most baffling, is that the sword skill tag in the .xml file is literally a copy and paste, I see zero reason it should not apply on the second sword.

XML:
<?xml version="1.0" encoding="UTF-8"?>
<CustomEquipment>
    <equipment baseItem="2400" article="a" name="zelda sword">
        <attribute key="description" value="a worthy blade." />
        <attribute key="defense" value="45" />
        <attribute key="attack" value="89" />
        <attribute key="extradef" value="10" />
        <condition key="speed" value="200" />
        <condition skill="sword" value="5" />
        <!-- requirements to wear the equipment must go on FIRST instances of items with same 'baseItem' -->
        <requirement key="vocation" name="knight"/>
        <requirement key="level" name="100"/>
        <requirement key="premmy" enabled="1"/> <!-- use integer as boolean value, 0 false, 1 true -->
    </equipment>

    <equipment baseItem="2400" article="a" name="blade of the ruined king">
        <attribute key="description" value="for adc's" />
        <attribute key="defense" value="48" />
        <attribute key="attack" value="99" />
        <attribute key="extradef" value="15" />
        <condition skill="sword" value="5" />
        <condition skill="distance" value="2" />
        <condition skill="criticalhit" chance="90" />
        <condition skill="criticalhit" amount="300" />
    </equipment>

    <equipment baseItem="2400" article="a" name="kahless thorn">
        <attribute key="description" value="only the most honorable warriors can wield this mighty weapon!" />
        <attribute key="defense" value="10" />
        <attribute key="attack" value="105" />
        <attribute key="extradef" value="10" />
        <condition key="meleeskill" value="12" />
        <condition key="soul" value="12" />
        <!-- penalties for wearing the equipment -->
        <penalty key="pzlock" enabled="1" /> <!-- use integer as boolean value, 0 false, 1 true -->
        <penalty key="bleed" damage="15"/>
    </equipment>

    <equipment baseItem="2472" article="a" name="Superior Armor">
        <attribute key="description" value="Upgraded Magic Plate Armor." />
        <attribute key="armor" value="22" />
        <condition key="healthgain" value="22" />
        <condition key="maxhitpoints" value="300" />
    </equipment>

    <equipment baseItem="2472" article="a" name="Supreme Kai Armor">
        <attribute key="description" value="scares even vegeta!" />
        <attribute key="armor" value="55" />
        <condition key="magicpoints" value="25" />
        <condition key="maxmanapoints" value="420" />
        <condition key="managain" value="39" />
        <condition key="manashield" value="true" />
    </equipment>

</CustomEquipment>

Lua:
local customEquipment = {}
local baseItemList = {}

local equipConditions = {       ---- ALL CONDITIONS ARE APPLIED TO WEARER OF EQUIPMENT, NOT THEIR TARGET!!!
    ["healthgain"] =                  {type = CONDITION_REGENERATION,          param = CONDITION_PARAM_HEALTHGAIN,},
    ["managain"] =                    {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_MANAGAIN,},
    ["maxhitpoints"] =                {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAXHITPOINTS,},
    ["maxmanapoints"] =               {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAXMANAPOINTS,},
    ["magicpoints"] =                 {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAGICPOINTS,},
    ["maxhitpointspercent"] =         {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT,},
    ["maxmanapointspercent"] =        {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT,},
    ["magicpointspercent"] =          {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_STAT_MAGICPOINTSPERCENT,},
    ["meleeskill"] =                  {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_MELEE,},
    ["fistskill"] =                   {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_FIST,},
    ["clubskill"] =                   {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_CLUB,},
    ["swordskill"] =                  {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_SWORD,},
    ["axeskill"] =                    {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_AXE,},
    ["distanceskill"] =               {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_DISTANCE,},
    ["shieldskill"] =                 {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_SHIELD,},
    ["fishingskill"] =                {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SKILL_FISHING,},
    ["criticalhitchance"] =           {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE,},
    ["criticalhitamount"] =           {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT,},
    -- ["lifeleechchance"] =             {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_LIFELEECHCHANCE,},
    -- ["lifeleechamount"] =             {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_LIFELEECHAMOUNT,},
    -- ["manaleechchance"] =             {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_MANALEECHCHANCE,},
    -- ["manaleechamount"] =             {type = CONDITION_ATTRIBUTES,            param = CONDITION_PARAM_SPECIALSKILL_MANALEECHAMOUNT,},
    ["speed"] =                       {type = CONDITION_HASTE,                 param = CONDITION_PARAM_SPEED,},
    ["soul"] =                        {type = CONDITION_SOUL,                  param = CONDITION_PARAM_SOULGAIN,},
    ["manashield"] =                  {type = CONDITION_MANASHIELD,            param = CONDITION_PARAM_BUFF_SPELL,},
    ["invis"] =                       {type = CONDITION_INVISIBLE,             param = CONDITION_PARAM_BUFF_SPELL,},

}

local equipmentFile = io.open("data/XML/custom_equipment.xml", "r")

for i in equipmentFile:read("*a"):gmatch("<equipment (.-)</equipment>") do
    local properties = {}
    properties.baseItem = tonumber(i:match('baseItem.-=.-"(.-)"'))
    properties.attributes = {
        ["aid"] = i:match('aid.-=.-"(.-)"'),
        ["article"] = i:match('article.-=.-"(.-)"'),
        ["name"] = i:match('name.-=.-"(.-)"'),
        ["description"] = i:match('key.-=.-"description".-value.-=.-"(.-)"'),
        ["defense"] = tonumber(i:match('key.-=.-"defense".-value.-=.-"(.-)"')),
        ["weight"] = tonumber(i:match('key.-=.-"weight".-value.-=.-"(.-)"')),
        ["attack"] = tonumber(i:match('key.-=.-"attack".-value.-=.-"(.-)"')),
        ["extradefense"] = tonumber(i:match('key.-=.-"extradef".-value.-=.-"(.-)"')),
        ["armor"] = tonumber(i:match('key.-=.-"armor".-value.-=.-"(.-)"')),
        ["hitchance"] = tonumber(i:match('key.-=.-"hitchance".-value.-=.-"(.-)"')),
        ["shootrange"] = tonumber(i:match('key.-=.-"shootrange".-value.-=.-"(.-)"')),
    }
    properties.conditions = {
        ["healthgain"] = tonumber(i:match('key.-=.-"healthgain".-value.-=.-"(.-)"')),
        ["managain"] = tonumber(i:match('key.-=.-"managain".-value.-=.-"(.-)"')),
        ["maxhitpoints"] = tonumber(i:match('key.-=.-"maxhitpoints".-value.-=.-"(.-)"')),
        ["maxmanapoints"] = tonumber(i:match('key.-=.-"maxmanapoints".-value.-=.-"(.-)"')),
        ["magicpoints"] = tonumber(i:match('key.-=.-"magicpoints".-value.-=.-"(.-)"')),
        ["maxhitpointspercent"] = tonumber(i:match('key.-=.-"maxhitpointspercent".-value.-=.-"(.-)"')),
        ["maxmanapointspercent"] = tonumber(i:match('key.-=.-"maxmanapointspercent".-value.-=.-"(.-)"')),
        ["magicpointspercent"] = tonumber(i:match('key.-=.-"magicpointspercent".-value.-=.-"(.-)"')),
        ["meleeskill"] = tonumber(i:match('skill.-=.-"melee".-value.-=.-"(.-)"')),
        ["fistskill"] = tonumber(i:match('skill.-=.-"fist".-value.-=.-"(.-)"')),
        ["clubskill"] = tonumber(i:match('skill.-=.-"club".-value.-=.-"(.-)"')),
        ["swordskill"] = tonumber(i:match('skill.-=.-"sword".-value.-=.-"(.-)"')),
        ["axeskill"] = tonumber(i:match('skill.-=.-"axe".-value.-=.-"(.-)"')),
        ["distanceskill"] = tonumber(i:match('skill.-=.-"distance".-value.-=.-"(.-)"')),
        ["shieldskill"] = tonumber(i:match('skill.-=.-"shield".-value.-=.-"(.-)"')),
        ["fishingskill"] = tonumber(i:match('skill.-=.-"fishing".-value.-=.-"(.-)"')),
        ["criticalhitchance"] = tonumber(i:match('skill.-=.-"criticalhit".-chance.-=.-"(.-)"')),
        ["criticalhitamount"] = tonumber(i:match('skill.-=.-"criticalhit".-amount.-=.-"(.-)"')),
        -- ["lifeleechchance"] = tonumber(i:match('skill.-=.-"lifeleech".-chance.-=.-"(.-)"')),
        -- ["lifeleechamount"] = tonumber(i:match('skill.-=.-"lifeleech".-amount.-=.-"(.-)"')),
        -- ["manaleechchance"] = tonumber(i:match('skill.-=.-"manaleech".-chance.-=.-"(.-)"')),
        -- ["manaleechamount"] = tonumber(i:match('skill.-=.-"manaleech".-amount.-=.-"(.-)"')),
        ["speed"] = tonumber(i:match('key.-=.-"speed".-value.-=.-"(.-)"')),
    }
    properties.penalties = {
        [CONDITION_INFIGHT] = tonumber(i:match('key.-=.-"pzlock".-enabled.-=.-"(.-)"')),
        [CONDITION_DRUNK] = tonumber(i:match('key.-=.-"drunk".-enabled.-=.-"(.-)"')),
        [CONDITION_PARALYZE] = tonumber(i:match('key.-=.-"poison".-enabled.-=.-"(.-)"')),
        [CONDITION_MUTED] = tonumber(i:match('key.-=.-"mute".-enabled.-=.-"(.-)"')),
        [CONDITION_PACIFIED] = tonumber(i:match('key.-=.-"pacify".-enabled.-=.-"(.-)"')),
        [CONDITION_EXHAUST_WEAPON] = tonumber(i:match('key.-=.-"disableweapon".-enabled.-=.-"(.-)"')),
        [CONDITION_EXHAUST_COMBAT] = tonumber(i:match('key.-=.-"disablecombat".-enabled.-=.-"(.-)"')),
        [CONDITION_EXHAUST_HEAL] = tonumber(i:match('key.-=.-"disableheal".-enabled.-=.-"(.-)"')),
        ---[CONDITION_SPELLGROUPCOOLDOWN] = tonumber(i:match('key.-=.-"disablespells".-group.-=.-"(.-)"')),
    }
    properties.dmgPenalties =
    {
        [CONDITION_POISON] = tonumber(i:match('key.-=.-"poison".-damage.-=.-"(.-)"')),
        [CONDITION_FIRE] = tonumber(i:match('key.-=.-"burn".-damage.-=.-"(.-)"')),
        [CONDITION_ENERGY] = tonumber(i:match('key.-=.-"shock".-damage.-=.-"(.-)"')),
        [CONDITION_BLEEDING] = tonumber(i:match('key.-=.-"poison".-damage.-=.-"(.-)"')),
        [CONDITION_CURSED] = tonumber(i:match('key.-=.-"curse".-damage.-=.-"(.-)"')),
        [CONDITION_DAZZLED] = tonumber(i:match('key.-=.-"dazzle".-damage.-=.-"(.-)"')),
        [CONDITION_DROWN] = tonumber(i:match('key.-=.-"drown".-damage.-=.-"(.-)"')),
        [CONDITION_FREEZING] = tonumber(i:match('key.-=.-"freeze".-damage.-=.-"(.-)"')),
    }
    properties.absorbs = {
        [COMBAT_PHYSICALDAMAGE] = tonumber(i:match('absorb.-=.-"physical".-percent.-=.-"(.-)"')),
        [COMBAT_ENERGYDAMAGE] = tonumber(i:match('absorb.-=.-"energy".-percent.-=.-"(.-)"')),
        [COMBAT_EARTHDAMAGE] = tonumber(i:match('absorb.-=.-"earth".-percent.-=.-"(.-)"')),
        [COMBAT_FIREDAMAGE] = tonumber(i:match('absorb.-=.-"fire".-percent.-=.-"(.-)"')),
        [COMBAT_DROWNDAMAGE] = tonumber(i:match('absorb.-=.-"water".-percent.-=.-"(.-)"')),
        [COMBAT_ICEDAMAGE] = tonumber(i:match('absorb.-=.-"ice".-percent.-=.-"(.-)"')),
        [COMBAT_HOLYDAMAGE] = tonumber(i:match('absorb.-=.-"holy".-percent.-=.-"(.-)"')),
        [COMBAT_DEATHDAMAGE] = tonumber(i:match('absorb.-=.-"death".-percent.-=.-"(.-)"')),
    }
    properties.reflects = {
        [COMBAT_PHYSICALDAMAGE] = tonumber(i:match('reflect.-=.-"physical".-percent.-=.-"(.-)"')),
        [COMBAT_ENERGYDAMAGE] = tonumber(i:match('reflect.-=.-"energy".-percent.-=.-"(.-)"')),
        [COMBAT_EARTHDAMAGE] = tonumber(i:match('reflect.-=.-"earth".-percent.-=.-"(.-)"')),
        [COMBAT_FIREDAMAGE] = tonumber(i:match('reflect.-=.-"fire".-percent.-=.-"(.-)"')),
        [COMBAT_DROWNDAMAGE] = tonumber(i:match('reflect.-=.-"water".-percent.-=.-"(.-)"')),
        [COMBAT_ICEDAMAGE] = tonumber(i:match('reflect.-=.-"ice".-percent.-=.-"(.-)"')),
        [COMBAT_HOLYDAMAGE] = tonumber(i:match('reflect.-=.-"holy".-percent.-=.-"(.-)"')),
        [COMBAT_DEATHDAMAGE] = tonumber(i:match('reflect.-=.-"death".-percent.-=.-"(.-)"')),
    }
    properties.primeTypes = {
        [COMBAT_ENERGYDAMAGE] = tonumber(i:match('primarydamage.-=.-"energy".-enabled.-=.-"(.-)"')),
        [COMBAT_EARTHDAMAGE] = tonumber(i:match('primarydamage.-=.-"earth".-enabled.-=.-"(.-)"')),
        [COMBAT_FIREDAMAGE] = tonumber(i:match('primarydamage.-=.-"fire".-enabled.-=.-"(.-)"')),
        [COMBAT_DROWNDAMAGE] = tonumber(i:match('primarydamage.-=.-"water".-enabled.-=.-"(.-)"')),
        [COMBAT_ICEDAMAGE] = tonumber(i:match('primarydamage.-=.-"ice".-enabled.-=.-"(.-)"')),
        [COMBAT_HOLYDAMAGE] = tonumber(i:match('primarydamage.-=.-"holy".-enabled.-=.-"(.-)"')),
        [COMBAT_DEATHDAMAGE] = tonumber(i:match('primarydamage.-=.-"death".-enabled.-=.-"(.-)"')),
        -- [COMBAT_LIFEDRAIN] = tonumber(i:match('primarydamage.-=.-"lifesteal".-enabled.-=.-"(.-)"')),
        -- [COMBAT_MANADRAIN] = tonumber(i:match('primarydamage.-=.-"manasteal".-enabled.-=.-"(.-)"')),
    }
    properties.secondTypes = {
        [COMBAT_ENERGYDAMAGE] = tonumber(i:match('secondarydamage.-=.-"energy".-enabled.-=.-"(.-)"')),
        [COMBAT_EARTHDAMAGE] = tonumber(i:match('secondarydamage.-=.-"earth".-enabled.-=.-"(.-)"')),
        [COMBAT_FIREDAMAGE] = tonumber(i:match('secondarydamage.-=.-"fire".-enabled.-=.-"(.-)"')),
        [COMBAT_DROWNDAMAGE] = tonumber(i:match('secondarydamage.-=.-"water".-enabled.-=.-"(.-)"')),
        [COMBAT_ICEDAMAGE] = tonumber(i:match('secondarydamage.-=.-"ice".-enabled.-=.-"(.-)"')),
        [COMBAT_HOLYDAMAGE] = tonumber(i:match('secondarydamage.-=.-"holy".-enabled.-=.-"(.-)"')),
        [COMBAT_DEATHDAMAGE] = tonumber(i:match('secondarydamage.-=.-"death".-enabled.-=.-"(.-)"')),
        -- [COMBAT_LIFEDRAIN] = tonumber(i:match('secondarydamage.-=.-"lifesteal".-enabled.-=.-"(.-)"')),
        -- [COMBAT_MANADRAIN] = tonumber(i:match('secondarydamage.-=.-"manasteal".-enabled.-=.-"(.-)"')),
    }
    local requirements = {
        ["level"] = tonumber(i:match('level.-=.-"(.-)"')),
        ["magiclevel"] = tonumber(i:match('magiclevel.-=.-"(.-)"')),
        ["premium"] = i:match('premium.-=.-"(.-)"'),
        ["vocation"] = i:match('vocation.-=.-"(.-)"'),
    }

    local itemType = ItemType(properties.baseItem)
    local group = itemType:getGroup()
    if not group == (ITEM_GROUP_WEAPON or ITEM_GROUP_ARMOR) then
        print("Error item " ..properties.attributes["name"].. " is not a valid weapon or armor! Was not added to CustomEquipment!")
    else
        local weaponType = itemType:getWeaponType()
        if weaponType == WEAPON_WAND then
            print("Error item " ..properties.attributes["name"].. " is a wand, wand's are currently not supported, was not added to CustomEquipment!")
        end
        if weaponType == WEAPON_AMMO then
            print("Error item " ..properties.attributes["name"].. " is a type of ammo, ammo type's are not supported, was not added to CustomEquipment!")
        end
        if not table.contains(baseItemList, properties.baseItem) then
            table.insert(baseItemList, properties.baseItem, requirements) --- add third parameter as value, table, with requirements.
        end
        customEquipment[properties.attributes["name"]] = properties
    end
end

for key , _table in pairs(baseItemList) do
    local equipEvent = MoveEvent()
    local deEquipEvent = MoveEvent()
   
    equipEvent:id(key)
    deEquipEvent:id(key)

    function equipEvent.onEquip(player, item, slot, isCheck)
        if isCheck == false then
            if customEquipment[item:getName()] then
                player:applyEquipmentConditions(item, slot)
                return true
            end
        end
        return true
    end

    function deEquipEvent.onDeEquip(player, item, slot, isCheck)
        if isCheck == false then
            if customEquipment[item:getName()] then
                player:removeEquipmentConditions(item, slot)
                return true
            end
        end
        return true
    end

    equipEvent:register()
    deEquipEvent:register()
end

--- returns false if it is ammo or backpack
local function getConditionIdForSlot(slotType)
    local list = {
        [CONST_SLOT_HEAD] = CONDITIONID_HEAD,
        [CONST_SLOT_NECKLACE] = CONDITIONID_NECKLACE,
        [CONST_SLOT_ARMOR] = CONDITIONID_ARMOR,
        [CONST_SLOT_RIGHT] = CONDITIONID_RIGHT,
        [CONST_SLOT_LEFT] = CONDITIONID_LEFT,
        [CONST_SLOT_LEGS] = CONDITIONID_LEGS,
        [CONST_SLOT_FEET] = CONDITIONID_FEET,
        [CONST_SLOT_RING] = CONDITIONID_RING
    }
    return list[slotType] or false
end

function Player:addCustomEquipment(name)
    if customEquipment[name] then
        local item = self:addItem(customEquipment[name].baseItem)
        for attr, val in pairs(customEquipment[name].attributes) do
            item:setAttribute(attr, val)
        end
    end
end

function Player:applyEquipmentConditions(item, slot)
    local equipment = customEquipment[item:getName()]
    local conditionId = getConditionIdForSlot(slot)
    local count = 0
    if conditionId and equipment then
        for _index, value in pairs(equipment.conditions) do
            local key = equipConditions[_index]
            if key and value then
                local condition = Condition(key.type, conditionId)
                if condition then
                    count = count + 1
                    local sub = conditionId + item:getId()
                    condition:setParameter(key.param, value)
                    condition:setTicks(-1)
                    condition:setParameter(CONDITION_PARAM_SUBID, sub)
                    self:addCondition(condition, true)
                end
            end
        end
        print("Condition Count is " ..count.. " for " ..item:getName().. " ")
    end
end

function Player:removeEquipmentConditions(item, slot)
    local equipment = customEquipment[item:getName()]
    local conditionId = getConditionIdForSlot(slot)
    if conditionId and equipment then
        for _index, value in pairs(equipment.conditions) do
            local key = equipConditions[_index]
            if key and value then
                local sub = conditionId + item:getId()
                self:removeCondition(key.type, conditionId, sub)
            end
        end
    end
end

local lookEvent = EventCallback

lookEvent.onLook = function(self, thing, position, distance, description)
    if thing:isItem() then
        if thing:getCustomAttribute("CustomEquipmentId") then
            description = string.format("%s\nEquip ID: %d", description, thing:getCustomAttribute("CustomEquipmentId"))
        end
    end
    return description
end

lookEvent:register(1)

console prints
Condition Count is 2 for zelda sword
Condition Count is 4 for blade of the ruined king
Post automatically merged:

I have tried with both

self:addCondition(condition, true)

and

self:addCondition(condition)
Post automatically merged:

a test script to get the equipments in question


Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    player:addCustomEquipment("zelda sword")
    player:addCustomEquipment("blade of the ruined king")
end
 
Last edited:
Solution
You are not generating unique IDs for each condition, you must make sure to correctly create unique identities, using the index of each condition for each item

Use a counter in the loop and use a base so as not to interfere with possible identifiers in the future, here is an example
Lua:
local uniqueId = (100 + (conditionId * CONST_SLOT_AMMO)) + conditionCount

Sarah Wesker

ค∂vαηcε รүηтαx ❤
Support Team
Joined
Mar 16, 2017
Messages
997
Solutions
100
Reaction score
1,033
Location
London
GitHub
MillhioreBT
You are not generating unique IDs for each condition, you must make sure to correctly create unique identities, using the index of each condition for each item

Use a counter in the loop and use a base so as not to interfere with possible identifiers in the future, here is an example
Lua:
local uniqueId = (100 + (conditionId * CONST_SLOT_AMMO)) + conditionCount
 
Last edited:
Solution
Top