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

Lua Elane learning spells for paladins

kibo433

New Member
Joined
Sep 6, 2010
Messages
12
Solutions
1
Reaction score
3
Hi. I have problem with my Elane NPC. Elane should learns spells for only paladins/royal paladins. I have learned Light Healing spell when I was sorcerer. Anybody knows how to solve it? This is code:

P.S. TFS 1.5 by Nekiro downgrade to 8.6

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid)              npcHandler:onCreatureAppear(cid)            end
function onCreatureDisappear(cid)           npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)      npcHandler:onCreatureSay(cid, type, msg)    end
function onThink()                          npcHandler:onThink()                        end

keywordHandler:addKeyword({'spells'}, StdModule.say, {npcHandler = npcHandler, text = 'I can teach the spells \'Light\', \'Light Healing\', \'Find Person\', \'Cure Poison\', \'Conjure Arrow\', \'Great Light\', \'Conjure Poisoned Arrow\', \'Destroy Field Rune\', \'Intense Healing\', \'Conjure Explosive Arrow\' and \'Divine Healing\'.'})


    local node1 = keywordHandler:addKeyword({'light healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light Healing for 170 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light healing',vocation = 3, price = 170, level = 8})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'light'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light for 100 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light', vocation = 3, price = 100, level = 8})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'find person'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Find Person for 80 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'find person', vocation = 3, price = 80, level = 8})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'cure poison'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Cure Poison for 150 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'cure poison', vocation = 3, price = 150, level = 10})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'conjure arrow'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Conjure Arrow for 450 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'conjure arrow', vocation = 3, price = 450, level = 13})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'great light'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Great Light for 500 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'great light', vocation = 3, price = 500, level = 13})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'conjure poisoned arrow'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Conjure Poisoned Arrow for 700 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'conjure poisoned arrow', vocation = 3, price = 700, level = 16})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'destroy field rune'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Destroy Field Rune for 700 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'destroy field rune', vocation = 3, price = 700, level = 17})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'intense healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Intense Healing for 350 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'intense healing', vocation = 3, price = 350, level = 20})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'conjure explosive arrow'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Conjure Explosive Arrow for 1000 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'conjure explosive arrow', vocation = 3, price = 1000, level = 25})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})

    local node1 = keywordHandler:addKeyword({'divine healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Divine Healing for 3000 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'divine healing', vocation = 3, price = 3000, level = 35})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Can\'t you handle the power of the spell?', reset = true})



npcHandler:addModule(FocusModule:new())
 
Solution
You can't add some random config property and expert it to work ;)
What about promoted players? I'd either define vocation as an array.
You need to modify the module to handle it first:

I'd add something like that there (parameter vocations as list of vocation ID's):
Lua:
local vocationId = player:getVocation():getBase():getId()
local vocations = parameters.vocations or { vocationId }

if not table.contains(vocations, vocationId) then
    local vocationNames = {}
    for _, vocId in ipairs(vocations) do
        local vocation = Vocation(vocId)
        table.insert(vocationNames...
You can't add some random config property and expert it to work ;)
What about promoted players? I'd either define vocation as an array.
You need to modify the module to handle it first:

I'd add something like that there (parameter vocations as list of vocation ID's):
Lua:
local vocationId = player:getVocation():getBase():getId()
local vocations = parameters.vocations or { vocationId }

if not table.contains(vocations, vocationId) then
    local vocationNames = {}
    for _, vocId in ipairs(vocations) do
        local vocation = Vocation(vocId)
        table.insert(vocationNames, vocation:getName())
    end

    npcHandler:say(("Sorry, Only %s can learn this spell."):format(table.concat(vocationNames, ", ")), cid)
elseif ...

INFO:
If you need some spells "only for promoted" get rid of that getBase()
Think of extending it with de-duplication of vocation text to only show highest-rank vocations (latest master of TFS has some utils for that)
 
Last edited:
Solution
I'm just getting to know variables, tables, loops etc. Yersterday I analized for hour what you wrote but I will come back to this post in future. Thanks for answer.
 
You can't add some random config property and expert it to work ;)
What about promoted players? I'd either define vocation as an array.
You need to modify the module to handle it first:

I'd add something like that there (parameter vocations as list of vocation ID's):
Lua:
local vocationId = player:getVocation():getBase():getId()
local vocations = parameters.vocations or { vocationId }

if not table.contains(vocations, vocationId) then
    local vocationNames = {}
    for _, vocId in ipairs(vocations) do
        local vocation = Vocation(vocId)
        table.insert(vocationNames, vocation:getName())
    end

    npcHandler:say(("Sorry, Only %s can learn this spell."):format(table.concat(vocationNames, ", ")), cid)
elseif ...

INFO:
If you need some spells "only for promoted" get rid of that getBase()
Think of extending it with de-duplication of vocation text to only show highest-rank vocations (latest master of TFS has some utils for that)
Is it possible to use something like
Lua:
local vocationId = parameters.vocation < 5 and player:getVocation():getBase():getId() or player:getVocation():getId()
?
 
Is it possible to use something like
Lua:
local vocationId = parameters.vocation < 5 and player:getVocation():getBase():getId() or player:getVocation():getId()
?
Yea but I didn’t want to write code that has assumption that there are only 4 base vocations. Latest master of TFS comes with nice utils to get base vocations only and get promoted/demoted Vocation. Which would work on every server, no mater how many base vocation there is (and how many promotion levels there are).

 
After few hours acquainted with topic my mission have ended succesfully. NPCs teach spells to define vocations. But now I have new problem:

22:34 Royal Paladin [190]: light
22:34 Elane: Would you like to learn Light for 100 gp?
22:34 Royal Paladin [190]: light healing
22:34 Elane: Would you like to learn Light for 100 gp?

Elane reacts for command "light healing" like a "light".
This is my fragment of code:
Lua:
    local node1 = keywordHandler:addKeyword({'light'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light for 100 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light', vocations = {3}, price = 100, level = 8})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

    local node1 = keywordHandler:addKeyword({'light healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light Healing for 170 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light healing', vocations = {3}, price = 170, level = 9})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

I noticed when I put fragment with "light healing" above the "light" in code, Elane is reacts correctly then. But I would rather skip such situations, when I will use more similar keyword in future.
 
After few hours acquainted with topic my mission have ended succesfully. NPCs teach spells to define vocations. But now I have new problem:

22:34 Royal Paladin [190]: light
22:34 Elane: Would you like to learn Light for 100 gp?
22:34 Royal Paladin [190]: light healing
22:34 Elane: Would you like to learn Light for 100 gp?

Elane reacts for command "light healing" like a "light".
This is my fragment of code:
Lua:
    local node1 = keywordHandler:addKeyword({'light'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light for 100 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light', vocations = {3}, price = 100, level = 8})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

    local node1 = keywordHandler:addKeyword({'light healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light Healing for 170 gp?'})
    node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light healing', vocations = {3}, price = 170, level = 9})
    node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

Not sure but as these keywords are registered in table (ordered) I'd swap it to register longer keywords first:

Lua:
local node1 = keywordHandler:addKeyword({'light healing'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light Healing for 170 gp?'})
node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light healing', vocations = {3}, price = 170, level = 9})
node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

local node1 = keywordHandler:addKeyword({'light'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn Light for 100 gp?'})
node1:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = false, spellName = 'light', vocations = {3}, price = 100, level = 8})
node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Maybe next time.', reset = true})

Edit: didn't noticed you already got such solution.
Hmm maybe instead of that you could rework the logic of KeywordHandler:processNodeMessage to match longer phrases first or implement support for some regexes light$
 
Back
Top