• 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 NPC keywordHandler:addKeyword Overriding other keywords

eagv

New Member
Joined
Nov 25, 2012
Messages
8
Reaction score
1
Good day,

I have an NPC that sells (teaches) spells. The NPC is coded so that it can teach multiple similarly-named spells. For example, "berserk" and "fierce berserk".

However, in-game the NPC only gives me the option to learn "berserk", even when the key word is "fierce berserk". Example in-game conversation:

18:53 Gregor: Greetings! This is the knight's guild. What do you want?
18:54 Bronc [1]: berserk
18:54 Gregor: Would you like to learn berserk for 2500 gp?
18:54 Bronc [1]: fierce berserk
18:54 Gregor: Would you like to learn berserk for 2500 gp?


What's the way to implement on the handler so that it can exactly match the string provided?


The addKeyword handlers within the Gregor.lua file:

Lua:
local node15 = keywordHandler:addKeyword({'berserk'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn berserk for 2500 gp?'})
node15:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = true, spellName = 'berserk', vocation = 4, price = 2500, level = 35})
node15:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Cant you handle the power of the spell?', reset = true})

Lua:
local node23 = keywordHandler:addKeyword({'fierce berserk'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn fierce berserk for 5000 gp?'})
node23:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = true, spellName = 'fierce berserk', vocation = 4, price = 5000, level = 90})
node23:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Cant you handle the power of the spell?', reset = true})


The learnSpell module within the modules.lua file:

Lua:
    function StdModule.learnSpell(cid, message, keywords, parameters, node)
   
        local npcHandler = parameters.npcHandler
       
        if npcHandler == nil then
            error("StdModule.learnSpell called without any npcHandler instance.")
        end

        if not npcHandler:isFocused(cid) then
            return false
        end

        local player = Player(cid)
       
       
        if player:hasLearnedSpell(parameters.spellName) then
            npcHandler:say("You already know how to cast this spell.", cid)
        elseif player:getLevel() < parameters.level then
            npcHandler:say("You have to be level " .. parameters.level .. " to learn this spell.", cid)
        elseif not player:removeTotalMoney(parameters.price) then
            npcHandler:say("Return when you have enough gold.", cid)
        else
            npcHandler:say("Here you are. Look in your spellbook for the pronunciation of this spell.", cid)
            player:learnSpell(parameters.spellName)
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
        end


        npcHandler:resetNpc(cid)
        return true
    end

Thank you!

Edit:
Also happens with other spells (example: haste vs. strong haste. light vs. light healing, etc...).
 
Last edited:
Good day,

I have an NPC that sells (teaches) spells. The NPC is coded so that it can teach multiple similarly-named spells. For example, "berserk" and "fierce berserk".

However, in-game the NPC only gives me the option to learn "berserk", even when the key word is "fierce berserk". Example in-game conversation:

18:53 Gregor: Greetings! This is the knight's guild. What do you want?
18:54 Bronc [1]: berserk
18:54 Gregor: Would you like to learn berserk for 2500 gp?
18:54 Bronc [1]: fierce berserk
18:54 Gregor: Would you like to learn berserk for 2500 gp?


What's the way to implement on the handler so that it can exactly match the string provided?


The addKeyword handlers within the Gregor.lua file:

Lua:
local node15 = keywordHandler:addKeyword({'berserk'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn berserk for 2500 gp?'})
node15:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = true, spellName = 'berserk', vocation = 4, price = 2500, level = 35})
node15:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Cant you handle the power of the spell?', reset = true})

Lua:
local node23 = keywordHandler:addKeyword({'fierce berserk'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to learn fierce berserk for 5000 gp?'})
node23:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, premium = true, spellName = 'fierce berserk', vocation = 4, price = 5000, level = 90})
node23:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Cant you handle the power of the spell?', reset = true})


The learnSpell module within the modules.lua file:

Lua:
    function StdModule.learnSpell(cid, message, keywords, parameters, node)
  
        local npcHandler = parameters.npcHandler
      
        if npcHandler == nil then
            error("StdModule.learnSpell called without any npcHandler instance.")
        end

        if not npcHandler:isFocused(cid) then
            return false
        end

        local player = Player(cid)
      
      
        if player:hasLearnedSpell(parameters.spellName) then
            npcHandler:say("You already know how to cast this spell.", cid)
        elseif player:getLevel() < parameters.level then
            npcHandler:say("You have to be level " .. parameters.level .. " to learn this spell.", cid)
        elseif not player:removeTotalMoney(parameters.price) then
            npcHandler:say("Return when you have enough gold.", cid)
        else
            npcHandler:say("Here you are. Look in your spellbook for the pronunciation of this spell.", cid)
            player:learnSpell(parameters.spellName)
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
        end


        npcHandler:resetNpc(cid)
        return true
    end

Thank you!

Edit:
Also happens with other spells (example: haste vs. strong haste. light vs. light healing, etc...).
Yo!

Try changing spell order in npc file.

fierce berserker before beserker
 
Hi mano368, thank you for replying.

Ohh, I see.. I tried your suggestion with multiple spells, and seems like it does the job right! Looks like those spells with multiple words on their name should be listed first.

I am wondering if there is an actual function, or some modification that could be done, that performs an "exact match" of the entire keyword provided? That would ease the pain of having to rearrange some codes I got in my quest files that use similar input keywords as well.

But if there is not, this method is still feasible. đź‘Ť Appreciate your help a lot!
 
you only need to put light after all lights words, even ultimate light.
haste after strong haste
ultimate healing after healing rune, also intense

I really don`t know, there's always a way to make it work, but that way you don't have to add anything, you just have the rework of ordering the spells
 
you only need to put light after all lights words, even ultimate light.
haste after strong haste
ultimate healing after healing rune, also intense

I really don`t know, there's always a way to make it work, but that way you don't have to add anything, you just have the rework of ordering the spells
Got it! Many thanks!
 
Well, it all depends.

You could create an additional parameter in the addKeyword method, that looks for the exact match. However, you will also need to create a separate table to store these, and when matching keywords against the string, you would need to check these first, before it checks any normal keyword.
 
Back
Top