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

NPC [TFS 1.X] Blessings NPC (with original cost and twist of fate)

ralke

(҂ ͠❛ ෴ ͡❛)ᕤ
Joined
Dec 17, 2011
Messages
1,514
Solutions
27
Reaction score
867
Location
Santiago - Chile
GitHub
ralke23
Twitch
ralke23
Hi! The following script have been tested on TFS 1.4 downgrade by nekiro (8.60). I saw some threads where blessings NPC are not working properly. Today I did my best to solve this and figured out that blessings are registered as decimals on MySQL, this means, that five blessings are represented with value 31, and six blessings are represented by value 63.

Try yourself here Binary to Decimal Converter (https://www.rapidtables.com/convert/number/binary-to-decimal.html), if you write 11111 (that means 5 true values) it will outcome 31, and if you write 111111 it will outcome 63 (that means 6 true values)

According to this, I did this two NPCs. The first one allows to buy the first fifth blessings with a configurable formula (same that blessings of the inquisition at Henricus). Just change getBlessingsCost(player:getLevel()) * 5 * 1.1 and fit to your taste (1.1 is the default value for Henricus that means x1.1 the original bless price).

Jassu.lua
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

local function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local player = Player(cid)
    local totalBlessPrice = getBlessingsCost(player:getLevel()) * 5 * 1.1
 
    if npcHandler.topic[cid] == 0 then
        if msgcontains(msg, "blessing") or msgcontains(msg, "bless") then
            local inquisitionComplete = true
            if inquisitionComplete then
                npcHandler:say("Do you want to receive the {common} blessings - which means all five available blessings - for " .. totalBlessPrice .. " (1.1% extra gold)?", cid)
                npcHandler.topic[cid] = 1
            else
                npcHandler:say("Fine. You are free to decline my offer.", cid)
                npcHandler.topic[cid] = 0
            end
        end
    elseif npcHandler.topic[cid] == 1 then
        if msgcontains(msg, "yes") then
            if player:getBlessings() == 5 then -- should probably check how many blessings in order to determine totalBlessPrice
                npcHandler:say("You already have been blessed!", cid)
            elseif player:removeMoney(totalBlessPrice) then
                npcHandler:say("You have been blessed by all of five gods!", cid)
                player:addBlessing(32) ----------- bit representation
                player:setStorageValue(PlayerStorageKeys.Blessings, 1)
                player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
            else
                npcHandler:say("Come back when you have enough money.", cid)
            end
        elseif msgcontains(msg, "no") then
            npcHandler:say("Then no.", cid)
        end
        npcHandler.topic[cid] = 0
    end
end

keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Jassu, a Kilika monk.'})

npcHandler:setMessage(MESSAGE_GREET, "Greetings fellow {believer}, would you like to receive {blessings} protection |PLAYERNAME|?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Always be on guard, |PLAYERNAME|!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "This ungraceful haste is most suspicious!")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

For the sixth blessing (that is the "pvp blessing", twist of fate) I did the following NPC that checks a storage given on the one above before giving you the option of buy the blessing.

Amanda.lua
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

local function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local player = Player(cid)
    local blessPrice = getPvpBlessingCost(player:getLevel())
  
    if npcHandler.topic[cid] == 0 then
        if msgcontains(msg, "twist of fate") or msgcontains(msg, "twist") then
           npcHandler:say("Do you have the fifth blessings?", cid)
           npcHandler.topic[cid] = 1
            if player:getStorageValue(PlayerStorageKeys.Blessings) == 1 then
                npcHandler:say("Do you want to receive the {twist of fate} blessing - which protect all five blessings on pvp combat - for " .. blessPrice .. "?", cid)
                npcHandler.topic[cid] = 2
            else
                npcHandler:say("You don't have the first {fifth blessings} or already have bought twist of fate.", cid)
                npcHandler.topic[cid] = 0
            end
        end
    elseif npcHandler.topic[cid] == 2 then
        if msgcontains(msg, "yes") then
            if player:getBlessings() == 6 then -- should probably check how many blessings in order to determine totalBlessPrice
                npcHandler:say("You already have twist of fate blessing!", cid)
            elseif player:removeMoney(blessPrice) then
                npcHandler:say("You have been blessed with twist of fate!", cid)
                player:addBlessing(64)
                player:setStorageValue(PlayerStorageKeys.Blessings, -1)
                player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
            else
                npcHandler:say("Come back when you have enough money.", cid)
            end
        elseif msgcontains(msg, "no") then
            npcHandler:say("Then no.", cid)
        end
        npcHandler.topic[cid] = 0
    end
end

keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Go see Henricus to begin The Inquisition Quest, I have no mission for you, child.'})
keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Amanda, a Kilika nun.'})
keywordHandler:addKeyword({'fifth'}, StdModule.say, {npcHandler = npcHandler, text = 'To get the first fifth blessings you must talk to Jassu.'})
keywordHandler:addKeyword({'bless'}, StdModule.say, {npcHandler = npcHandler, text = 'To get the first fifth blessings you must talk to Jassu.'})

npcHandler:setMessage(MESSAGE_GREET, "Welcome, young |PLAYERNAME|! Would you like to receive {twist of fate} protection?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Always be on guard, |PLAYERNAME|!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "This ungraceful haste is most suspicious!")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Not sure why but adding player:addBlessing(32) makes the player change it's blessing value to 31 in database, and player:addBlessing(64) outcomes in 63. This is how is going to look on mysql database:

mysql.png

After adding this two NPCs, you must add the following at global.lua:
global.lua
Lua:
function getBlessingsCost(level)

    if level <= 30 then
    print(work1)
        return 2000
    elseif level >= 120 then
    print(work2)
        return 20000
    else
    print(work3)
        return (level - 20) * 200
    end
end

function getPvpBlessingCost(level)
    if level <= 30 then
        return 2000
    elseif level >= 270 then
        return 50000
    else
        return (level - 20) * 200
    end
end

function Player.getBlessings(self)
    local blessings = 0
    for i = 1, 5 do
        if self:hasBlessing(i) then
            blessings = blessings + 1
        end
    end
    return blessings
end

And finally add the custom storage I added for the NPCs
Go to data/lib/core/storages.lua and inside PlayerStorageKeys = {
Lua:
Blessings = 50139,

For easy testing you can use this code, just place it in data/scripts
Lua:
local blessings = {
    "Spiritual Shielding",
    "Embrace of the World",
    "Fire of the Suns",
    "Spark of the Phoenix",
    "Wisdom of Solitude",
    "Twist of Fate"
}

local checkBless = Action()

function checkBless.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local message = {"Received blessings:"}
    for i, blessing in pairs(blessings) do
        if player:hasBlessing(i) then
            message[#message + 1] = blessing
        end
    end

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, #message == 1 and "No blessings received." or table.concat(message, '\n'))
    return true
end

checkBless:id(12424, 6561)
checkBless:register()

And that's it. If theres any error while adding this two NPCs just reply it here.
Hope this helps, regards!
 
Last edited:
so that blessing_charms doesn't work?
Hmm this has been specifialy done for 8.6 downgrade, charms have been introduced on 11.X. I'm not sure if TFS 1.5 is working with the correct values (meaning that value 1 is blessing #1), you must test it and see.

According to this conversion table from binary to decimal, the MySQL value for each blessing must be:
  • Blessing #1 = 1
  • Blessing #2 = 3
  • Blessing #3 = 7
  • Blessing #4 = 15
  • Blessing #5 = 31
  • Blessing #6 = 63
But i'm not sure if for example: If I add blessing by using player:addBlessing(7) the result is player with bless #1, #2, and #3, or, player with blessing #3 only. The conclusion I take of this is that blessings should be separated tables (with this way we will be able to see separately if player has the specific blessing), not a single one that holds the binary values, but that's not how it's been done.

Regards!
 
this is not working for me i have done everything the npc says that im blessed but im losing backpack with the five bless. no errors in console
the weird this is that with the talk action taken from here it works normally, the check bless item says that im blessed and bless works normally
Solved - !bless with real price´s (https://otland.net/threads/bless-with-real-price-s.228694/#post-2388583) i

the npc says that im bless but im not ( no errors in console)
Code:
13:38 Testi [6]: bless
13:38 Norf: Do you want to receive the {common} blessings - which means all five available blessings - for 11000 (1.1% extra gold)?
13:38 Testi [6]: yes
13:38 Norf: You have been blessed by all of five gods!
Code:
13:39 No blessings received.

it does not gives bless but it detect if i'm blessed
Lua:
13:56 Norf: Do you want to receive the {common} blessings - which means all five available blessings - for 11000 (1.1% extra gold)?
13:56 Testi [6]: yes
13:56 Norf: You already have been blessed!
 
Last edited:
if somebody want it and have problem i've solved the 5 bless npc issue
Lua:
local player = Player(cid)
    local totalBlessPrice = getBlessingsCost(player:getLevel()) * 5 * 1.1
 
    if npcHandler.topic[cid] == 0 then
        if msgcontains(msg, "xblessing") or msgcontains(msg, "xbless") then
            --local inquisitionComplete = true
           -- if inquisitionComplete then
           --if player:getLevel() >= 1 then
                npcHandler:say("Do you want to receive the {common} blessings - which means all five available blessings - for " .. totalBlessPrice .. " (1.1% extra gold)?", cid)
                npcHandler.topic[cid] = 1
            else
                npcHandler:say("Fine. You are free to decline my offer.", cid)
                npcHandler.topic[cid] = 0
        end
    elseif npcHandler.topic[cid] == 1 then
        if msgcontains(msg, "yes") then
              for i = 1, 5 do
       if player:hasBlessing(i) then
                npcHandler:say("You already have been blessed!", cid)
            elseif player:removeMoney(totalBlessPrice) then
                player:setStorageValue(PlayerStorageKeys.Blessings, 1)
                player:addBlessing(i) ----------- bit representation
                player:setStorageValue(50139)
                player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)

            else
                npcHandler:say("Come back when you have enough money.", cid)
            end
            end
        elseif msgcontains(msg, "no") then
            npcHandler:say("Then no.", cid)
        end
        npcHandler.topic[cid] = 0
    end
end
 
Last edited:
@Felipe93 just replace for example player:addBlessing(64) for the corresponding blessing. This is kinda old and bless corrections have been commited already. I'll search the updated npc later since i'm writing on phone, regards!
 
@Felipe93 just replace for example player:addBlessing(64) for the corresponding blessing. This is kinda old and bless corrections have been commited already. I'll search the updated npc later since i'm writing on phone, regards!
thank u bro but i solved the issue just by taking the code lines from the orts and editing yours or replacing. anyway this thread was super useful
thank to you.
also i posted how i solved the issue
 
Back
Top