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

Don't show monster spells on !spells and spellbook

ralke

(҂ ͠❛ ෴ ͡❛)ᕤ
Joined
Dec 17, 2011
Messages
1,759
Solutions
31
Reaction score
999
Location
Santiago - Chile
GitHub
ralke23
Twitch
ralke23
Using OTX 2 (0.3.7)

Hi again, there's some monsters on my server that needs custom spells, the problem is that the spells are appearing on spellbooks and !spell commands. Tried with enabled = 0 on spells.xml but doesn't work. Here's an image explaining it better.

!spells.png

The ideas that comes to my mind are:
[1] Set a level limit to the spells that are shown (only show spells that are less that "level 9999").
[2] Make an onUse script that show spells as doPlayerSendTextMessage depending of player vocation, the annoying thing is that I will have to manually write all spells and it's statics.

Please help me with this! I'm sure the first idea could work better, or there might be another ways to make it work as intended (you guys know how to do it better than me).

Spellbook
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local t = {}
    for i = 0, getPlayerInstantSpellCount(cid) - 1 do
        local spell = getPlayerInstantSpellInfo(cid, i)
        if(spell.level ~= 0) then
            if(spell.manapercent > 0) then
                spell.mana = spell.manapercent .. "%"
            end

            table.insert(t, spell)
        end
    end

    table.sort(t, function(a, b) return a.level < b.level end)
    local text, prevLevel = "", -1
    for i, spell in ipairs(t) do
        local line = ""
        if(prevLevel ~= spell.level) then
            if(i ~= 1) then
                line = "\n"
            end

            line = line .. "Spells for Level " .. spell.level .. "\n"
            prevLevel = spell.level
        end

        text = text .. line .. "  " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n"
    end

    doShowTextDialog(cid, item.itemid, text)
    return true
end

Talkaction
Code:
function onSay(cid, words, param)
    local count = getPlayerInstantSpellCount(cid)
    local text = ""
    local t = {}
    for i = 0, count - 1 do
        local spell = getPlayerInstantSpellInfo(cid, i)
        if spell.level ~= 0 then
            if spell.manapercent > 0 then
                spell.mana = spell.manapercent .. "%"
            end
            table.insert(t, spell)
        end
    end
    table.sort(t, function(a, b) return a.level < b.level end)
    local prevLevel = -1
    for i, spell in ipairs(t) do
        local line = ""
        if prevLevel ~= spell.level then
            if i ~= 1 then
                line = "\n"
            end
            line = line .. "Spells for Level " .. spell.level .. "\n"
            prevLevel = spell.level
        end
        text = text .. line .. "  " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n"
    end
    doShowTextDialog(cid, 2175, text)
    return TRUE
end

Here's another reference script that might be usefull for the second idea (using tables)
Code:
function onAdvance(cid, skill, oldLevel, newLevel)
    if skill == SKILL__LEVEL then      
        local spells = {}
        for index = 0,     getPlayerInstantSpellCount(cid) - 1 do
            local spell = getPlayerInstantSpellInfo(cid, index)
      
            if spell.level > oldLevel and spell.level <= newLevel then
                table.insert(spells, " [".. spell.name .."] \"".. spell.words .. "\" Mana[".. spell.mana .."]")
            end
        end
  
        if #spells > 0 then          
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have just advanced to level ".. newLevel .." and learned new spells!")

            for _, v in pairs(spells) do
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, v)
            end
        end
    end
      
    return true
end

Thanks in advance!
 
Last edited:
Solution
Why do you even register it in spells.xml at all? Bind it to the monster's attack via the script attribute instead of relying on attack name that has to be looked up through the registered spells

XML:
<attack script="monsters/gaz'haragoth ice ue.lua" interval="2000" chance="24" min="-1500" max="-1500"/>

This will look for the file in data/spells/monsters/gaz'haragoth ice ue.lua
Using OTX 2 (0.3.7)

Hi again, there's some monsters on my server that needs custom spells, the problem is that the spells are appearing on spellbooks and !spell commands. Tried with enabled = 0 on spells.xml but doesn't work. Here's an image explaining it better.

View attachment 54562

The ideas that comes to my mind are:
[1] Set a level limit to the spells that are shown (only show spells that are less that "level 9999").
[2] Make an onUse script that show spells as doPlayerSendTextMessage depending of player vocation, the annoying thing is that I will have to manually write all spells and it's statics.

Please help me with this! I'm sure the first idea could work better, or there might be another ways to make it work as intended (you guys know how to do it better than me).

Spellbook
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local t = {}
    for i = 0, getPlayerInstantSpellCount(cid) - 1 do
        local spell = getPlayerInstantSpellInfo(cid, i)
        if(spell.level ~= 0) then
            if(spell.manapercent > 0) then
                spell.mana = spell.manapercent .. "%"
            end

            table.insert(t, spell)
        end
    end

    table.sort(t, function(a, b) return a.level < b.level end)
    local text, prevLevel = "", -1
    for i, spell in ipairs(t) do
        local line = ""
        if(prevLevel ~= spell.level) then
            if(i ~= 1) then
                line = "\n"
            end

            line = line .. "Spells for Level " .. spell.level .. "\n"
            prevLevel = spell.level
        end

        text = text .. line .. "  " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n"
    end

    doShowTextDialog(cid, item.itemid, text)
    return true
end

Talkaction
Code:
function onSay(cid, words, param)
    local count = getPlayerInstantSpellCount(cid)
    local text = ""
    local t = {}
    for i = 0, count - 1 do
        local spell = getPlayerInstantSpellInfo(cid, i)
        if spell.level ~= 0 then
            if spell.manapercent > 0 then
                spell.mana = spell.manapercent .. "%"
            end
            table.insert(t, spell)
        end
    end
    table.sort(t, function(a, b) return a.level < b.level end)
    local prevLevel = -1
    for i, spell in ipairs(t) do
        local line = ""
        if prevLevel ~= spell.level then
            if i ~= 1 then
                line = "\n"
            end
            line = line .. "Spells for Level " .. spell.level .. "\n"
            prevLevel = spell.level
        end
        text = text .. line .. "  " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n"
    end
    doShowTextDialog(cid, 2175, text)
    return TRUE
end

Here's another reference script that might be usefull for the second idea (using tables)
Code:
function onAdvance(cid, skill, oldLevel, newLevel)
    if skill == SKILL__LEVEL then 
        local spells = {}
        for index = 0,     getPlayerInstantSpellCount(cid) - 1 do
            local spell = getPlayerInstantSpellInfo(cid, index)
 
            if spell.level > oldLevel and spell.level <= newLevel then
                table.insert(spells, " [".. spell.name .."] \"".. spell.words .. "\" Mana[".. spell.mana .."]")
            end
        end

        if #spells > 0 then     
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have just advanced to level ".. newLevel .." and learned new spells!")

            for _, v in pairs(spells) do
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, v)
            end
        end
    end
 
    return true
end

Thanks in advance!
Here's idea 1 for you.

change
LUA:
if(spell.level ~= 0) then
LUA:
if spell.level ~= 0 and spell.level < 9999 then
 
Last edited by a moderator:
Why do you even register it in spells.xml at all? Bind it to the monster's attack via the script attribute instead of relying on attack name that has to be looked up through the registered spells

XML:
<attack script="monsters/gaz'haragoth ice ue.lua" interval="2000" chance="24" min="-1500" max="-1500"/>

This will look for the file in data/spells/monsters/gaz'haragoth ice ue.lua
 
Solution
Why do you even register it in spells.xml at all? Bind it to the monster's attack via the script attribute instead of relying on attack name that has to be looked up through the registered spells

XML:
<attack script="monsters/gaz'haragoth ice ue.lua" interval="2000" chance="24" min="-1500" max="-1500"/>

This will look for the file in data/spells/monsters/gaz'haragoth ice ue.lua
This is the stuff I've never learned whilst refusing to work with spells.. cuz I still don't understand them. 😭
 
XML:
<attack script="monsters/gaz'haragoth ice ue.lua" interval="2000" chance="24" min="-1500" max="-1500"/>

Sorry for the delay. Tested and working as intended, thanks a lot!
By the way, a final question. I transformed the phantasm spell from 1.3 to 0.3.7, is this the right syntax? @Xikini @Alpha

1.3 spell
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)

local condition = Condition(CONDITION_DROWN)
condition:setParameter(CONDITION_PARAM_DELAYED, 1)
condition:addDamage(20, 5000, -20)

local area = createCombatArea({
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0}
})
combat:setArea(area)
combat:addCondition(condition)

function onCastSpell(creature, var)
    return combat:execute(creature, var)
end
0.3.7 spell
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)

local condition = createConditionObject(CONDITION_DROWN)
setConditionParam(condition, CONDITION_PARAM_DELAYED, 1)
addDamageCondition(condition, 20, 5000, -20)

local area = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0}
})
setCombatArea(combat, area)
setCombatCondition(combat, condition)

function onCastSpell(creature, var)
    return doCombat(cid, combat, var)
end

I'm planning to downgrade all the 1.3 monster spells except the skills reducers
Regards!
 
Last edited:
Sorry for the delay. Tested and working as intended, thanks a lot!
By the way, a final question. I transformed the phantasm spell from 1.3 to 0.3.7, is this the right syntax? @Xikini @Alpha

1.3 spell
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)

local condition = Condition(CONDITION_DROWN)
condition:setParameter(CONDITION_PARAM_DELAYED, 1)
condition:addDamage(20, 5000, -20)

local area = createCombatArea({
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0}
})
combat:setArea(area)
combat:addCondition(condition)

function onCastSpell(creature, var)
    return combat:execute(creature, var)
end
0.3.7 spell
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)

local condition = createConditionObject(CONDITION_DROWN)
setConditionParam(condition, CONDITION_PARAM_DELAYED, 1)
addDamageCondition(condition, 20, 5000, -20)

local area = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0}
})
setCombatArea(combat, area)
setCombatCondition(combat, condition)

function onCastSpell(creature, var)
    return doCombat(cid, combat, var)
end

I'm planning to downgrade all the 1.3 monster spells except the skills reducers
Regards!
Looks correct to me
 
Back
Top