• 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 Conjure runes from backpack - TFS 0.4 - 8.6

hanzoha

New Member
Joined
May 8, 2016
Messages
87
Reaction score
2
Hello guys, I was wondering if someone could help me with this.

In my ot, the players have to put the blank rune in the hand in order to conjure the rune. What I need is to remove that action and let player being able to conjure runes without putting the blank rune in the hand.

I found this thread, and it suggest to remove the reagentId="" from spells.xml. It works but the problem is that blank runes become useless and I need them too.

Is there a way to edit this without editing sources and just edit the Lua? What can I do?

Thanks in advance!
 
i preferred doing this in lua rather than sources, if you want him to use source edits instead feel free to instruct him on what to do :)

@hanzoha i slightly edited it again, if you can not conjure a rune and get the error message you will now only be shown the types of runes you have enough level to conjure
also instead of using param you can use strings functions
 
Why wouldn't he just use something like this?

Code:
local rune = 1111
local blank = 1111

function onCastSpell(creature, var, isHotkey)
    if doPlayerRemoveItem(blank, 1) then
        doPlayerAddItem(rune, 1)
    else
        doPlayerSendCancelMessage(cid, "You do not have a blank rune.")
end
end
 
Then in spells.xml change the code from

Code:
<conjure name="Light Magic Missile" words="adori min vis" lvl="15" mana="120" soul="1" reagentId="2260" conjureId="2287" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">

to

Code:
<conjure name="Light Magic Missile" words="adori min vis" lvl="15" mana="120" soul="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="conjure_rune">
 
@StreamSide what? i use param because talkactions cant have more than 1 space in the command so for "adori vita vis" "vis" is the param

@Itutorial that would require one script per rune
oh oh sorry, was thinking about tfs 1.x+ series, ur solution is pretty smart, but you can do the same with an spell script and not with talkactions
edit.
lolol yeah that would require 1 script per spell my bad, going to check how spells works and if you can go trought what the players says and use it as param
edit2.
im super high trying to analyze this rofl
 
oh oh sorry, was thinking about tfs 1.x+ series, ur solution is pretty smart, but you can do the same with an spell script and not with talkactions
i was thinking about that, but all i know is
Code:
onCastSpell(cid, var)
and that doesn't pass along the spell words (which would be required to find which rune ID to add to the player unless you have one script per spell, which would be awful)
 
maybe you can link the constant words to castSpell function and pass it thought the lua variant "var" then check it with something like var.words
but i dont know that much of c++ :rolleyes:
this is going to be an awesome homework for tomorrow
 
too much work for my liking, considering the lua script works fine, and even if you find a way to pass the spell words it will be essentially the same function :p
 
There is nothing wrong with having a different spell for each conjured rune? Its not like it will make your server slower in anyway. Just make a folder called runes...Ez pz unless ur lazy

Then it will be done the correct way.
 
There is nothing wrong with having a different spell for each conjured rune? Its not like it will make your server slower in anyway. Just make a folder called runes...Ez pz unless ur lazy

Then it will be done the correct way.
but why 20+ instead of 1-2?
 
An alternative, since you have t
Why wouldn't he just use something like this?

Code:
local rune = 1111
local blank = 1111

function onCastSpell(creature, var, isHotkey)
    if doPlayerRemoveItem(blank, 1) then
        doPlayerAddItem(rune, 1)
    else
        doPlayerSendCancelMessage(cid, "You do not have a blank rune.")
end
end
Make sure to return properly, or the player will spend mana.
Code:
local rune = 1111
local blank = 1111

function onCastSpell(creature, var, isHotkey)
    if doPlayerRemoveItem(blank, 1) then
        doPlayerAddItem(rune, 1)
    else
        -- send POFF animation
        doPlayerSendCancelMessage(cid, "You do not have a blank rune.")
        return false
    end
    return true
end
 
Hello again guys...

Everything's good so far, but It happened something funny... I was testing the server when I conjured a Sudden Death Rune with a paladin and it worked, lol.

That's when I just realized that the script does not have voc restriction and also, I want to know if it would be posibble to add the spell "Adori blank" ( which is used to conjure a blank rune) as an exception for the script in needing a blank rune for the spell.

That would be awesome.
Thanks again!
 
print_r(var) in 0.3.6/0.4 gives me
Code:
[09/05/2016 13:35:38] table: 0F932B80 {
[09/05/2016 13:35:38]   [pos] => table: 0F932B80 {
[09/05/2016 13:35:38]              [y] => 996
[09/05/2016 13:35:38]              [x] => 995
[09/05/2016 13:35:38]              [stackpos] => 0
[09/05/2016 13:35:38]              [z] => 7
[09/05/2016 13:35:38]            }
[09/05/2016 13:35:38]   [type] => 2
[09/05/2016 13:35:38] }
so cant do it your way, because you cant get the spellwords in any way i know of

@hanzoha forgot to add vocation checks, i will add adori blank in a bit, gonna change script some
 
Code:
local exhaustTime = 1000

local exhaust = createConditionObject(CONDITION_EXHAUST)
setConditionParam(exhaust, CONDITION_PARAM_TICKS, exhaustTime)

local function conjuration(cid, t, word)
    doPlayerAddMana(cid, -(t[word].manaCost))
    doPlayerAddItem(cid, t[word].runeID, t[word].runeAmount)
    doPlayerAddSoul(cid, -(t[word].soulCost))
    doSendMagicEffect(getCreaturePosition(cid), CONST_ME_MAGIC_BLUE)
    doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You conjured "..(t[word].runeAmount).." "..(getItemNameById(t[word].runeID)).." runes.")
    doAddCondition(cid, exhaust)
end

function onSay(cid, words, param, channel)
    if(hasCondition(cid, CONDITION_EXHAUST)) then
        doPlayerSendDefaultCancel(cid, RETURNVALUE_YOUAREEXHAUSTED)
        return true
    end
    local vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master sorcerer", "Elder druid", "Royal paladin", "Elite knight"}
    local cast = string.lower(words.." "..param)
    local voc = getPlayerVocation(cid)
    local lvl = getPlayerLevel(cid)
    local mana = getPlayerMana(cid)
    local errorMessage = ""
    local invalidSpell = "--- Valid conjuration spells for you are ---"
    local runes = {
    ["adori blank"] = {runeID = 2260, runeAmount = 1, manaCost = 20, soulCost = 1, levelReq = 8, vocations = {1,2,3,4,5,6,7,8}},
    ["adori vita vis"] = {runeID = 2268, runeAmount = 3, manaCost = 200, soulCost = 0, levelReq = 200, vocations = {1,2,3,4,5,6,7,8}},
    ["adori vis"] = {runeID = 2311, runeAmount = 15, manaCost = 200, soulCost = 0, levelReq = 200, vocations = {1,2,3,4,5,6,7,8}}
    }
    if runes[cast] then
        if isInArray(runes[cast].vocations, voc) then
            if lvl >= runes[cast].levelReq then
                if mana >= runes[cast].manaCost then
                    if getPlayerSoul(cid) > runes[cast].soulCost then
                        if cast ~= "adori blank" and doPlayerRemoveItem(cid, 2260, runes[cast].runeAmount) then
                            conjuration(cid, runes, cast)
                            return true
                        elseif cast == "adori blank" then
                            conjuration(cid, runes, cast)
                            return true
                        else
                            errorMessage = "You do not have enough blank runes. You need "..(runes[cast].runeAmount).."."
                        end
                    else
                        errorMessage = "You do not have enough soul. You need "..(runes[cast].soulCost).." soul."
                    end
                else
                    errorMessage = "You do not have enough mana. You have "..mana.." and you need "..runes[cast].manaCost.."."
                end
            else
                errorMessage = "You do not have the required level for this. You need level "..runes[cast].levelReq.."."
            end
        else
            errorMessage = "That spell can only be used by:\n"
            local n = #(runes[cast].vocations)
            for i=1,n,1 do
                if i == n then
                    errorMessage = errorMessage..vocations[i].."."
                else
                    errorMessage = errorMessage..vocations[i]..", "
                end
            end
        end   
    else
        errorMessage = "That conjuration spell does not exist."
    end
    for pos,val in pairs(runes) do
        if isInArray(runes[pos].vocations, voc) then
            invalidSpell = invalidSpell.."\n"..pos.." --- which costs "..(runes[pos].manaCost).." mana, "..(runes[pos].soulCost).." soul and gives you "..(runes[pos].runeAmount).." "..(getItemNameById(runes[pos].runeID))..""
            if runes[pos].runeAmount > 1 then
                invalidSpell = invalidSpell.."s."
            else
                invalidSpell = invalidSpell.."."
            end
        end
    end
    invalidSpell = errorMessage.."\n"..invalidSpell
    doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, invalidSpell)
    doAddCondition(cid, exhaust)       
    return true
end
to use this all you have to do is add this in talkactions.xml
Code:
<talkaction words="adori" event="script" value="conjure.lua"/>
    <talkaction words="adevo" event="script" value="conjure.lua"/>
    <talkaction words="adana" event="script" value="conjure.lua"/>
    <talkaction words="adura" event="script" value="conjure.lua"/>
    <talkaction words="adeto" event="script" value="conjure.lua"/>
    <talkaction words="adito" event="script" value="conjure.lua"/>

and then to add more conjuration spells put them in
Code:
local runes = {...}
in the form of
Code:
{["spellname"] = {runeID = 1, runeAmount = 2, manaCost = 3, levelReq = 4, vocations = {1,2,3}, ["spellname2"] = {runeID = 1, runeAmount = 2, manaCost = 3, levelReq = 4, vocations = {1,2,3}}
and for example for a conjuration spell for SDs it would look like this:
Code:
["adori vita vis"] = {runeID = 2268, runeAmount = 3, manaCost = 200, levelReq = 200, vocations = {1, 2, 5, 6}}
this means the words you have to say is "adori vita vis", the rune it gives you has ID 2268 (SD rune), it gives you 3 of those, it costs 200 mana to cast it, you have to be lvl 200+, and you have to be vocation 1/2/5/6 (sorc, druid, MS, ED)

no need to read further if you're just gonna use the script
i changed the table around so its now
Code:
runes["cast name"]
so the function doesn't loop through entire runes table every cast, but rather goes to the rigth index directly (afaik it should be better performance..)
i added "adori blank" to the runes table just like a regular rune, so its easy to change however you want it

i found no issues with it, and it also returns what type of error you have (e.g too low mana / level or wrong vocation and what vocations can use it.)

it does still loop through entire runes table incase you cast an invalid spell, but that shouldnt be a problem since most people should be casting a valid conjuration spell anyway..

if the player casts a valid conjuration spell its not really a long function to loop through, it creates the necessary tables/values, check a couple ifs straight to the rune table index then does conjuration, and exits the function
it may look long but its not really inefficient if people are casting valid spells
 
Last edited:
i removed all previous versions of the script and updated the last post with the final version (which i think works best) and a bit on how to iimplement and use it
 
Hi Zothion! I was testing on my ot and now I see that when the runes are conjured, the blank rune is not used. Is it me? Thanks again
 
Back
Top