• 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 Passive party heal TFS 1.3

Icaraii

Well-Known Member
Joined
Jan 5, 2020
Messages
469
Solutions
1
Reaction score
58
Hello,

I would like some directions of how to make a spell that works with this variations:

-Player cast a spell that works like a passive healing spell.
-It would have the same attributes as "exura sio" but without a fixed target.
-Player need to be on party to cast the spell.
-The heal can work like math.random. Example, math.random between 1 to 100, where between 1 to 10 heal happens, between 11 to 100 nothing happens.
-Everytime someone is healed from this spell, the target loses 100 mana.
-If math.random is between 1 to 10, it looks for player in the party that has lowest % of health of the moment and heals him.
-If every player in the party is with max health, nothing happens.
-The spell will be on loop for 1 minute.
-Also I would like to make possible only to cast the spell if player is using item x on weapon(id of some weapons) and item y on shield(id of some spellbooks)

->What would the spell do?
Player cast spell and at a random time heals party target that has lower % of health.

@Xikini, @Sarah Wesker, @Leo32, Can any of you guys help me out with this? Remember that I'm very noob at script, I might need a simple explanation or a example to try to create this spell.
 
Last edited:
Solution
I used this line in spells.xml for testing.
Make sure you update spellid to be a unique number in your spells list.
Lua:
<instant group="healing" spellid="160" name="Blah Blah" words="blah blah" level="1" mana="165" premium="1" aggressive="0" selftarget="1" cooldown="60000" groupcooldown="1000" needlearn="0" script="healing/blah_blah.lua">
        <vocation name="Sorcerer" />
        <vocation name="Paladin" />
        <vocation name="Knight" />
        <vocation name="Royal Paladin" />
        <vocation name="Elite Knight" />
    </instant>
and here's the spell
Lua:
local config = {
    buffTimer = 60, -- in seconds
    requiredMemberDistance = {tiles = 15, floors = 2},
    mathRandom = 100,
    chance...
I used this line in spells.xml for testing.
Make sure you update spellid to be a unique number in your spells list.
Lua:
<instant group="healing" spellid="160" name="Blah Blah" words="blah blah" level="1" mana="165" premium="1" aggressive="0" selftarget="1" cooldown="60000" groupcooldown="1000" needlearn="0" script="healing/blah_blah.lua">
        <vocation name="Sorcerer" />
        <vocation name="Paladin" />
        <vocation name="Knight" />
        <vocation name="Royal Paladin" />
        <vocation name="Elite Knight" />
    </instant>
and here's the spell
Lua:
local config = {
    buffTimer = 60, -- in seconds
    requiredMemberDistance = {tiles = 15, floors = 2},
    mathRandom = 100,
    chance = 10, -- chance used in conjunction with (mathRandom) default: 10/100 -> 10% chance
    manaRequired = 100,
    allowCasterToSupplementMana = true, -- allows the caster to supplement mana requirement if the target does not have enough mana to receive the heal
    itemsRequired = {leftHand = {2190, 1111, 1111}, rightHand = {2175, 2222, 2222}} -- require both left & right hand items. (wand and spellbook)
}

-- heal
local combatHeal = Combat()
combatHeal:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combatHeal:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combatHeal:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combatHeal:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.3) + 45
    local max = (level / 5) + (magicLevel * 14.4) + 90 -- same formula as exura sio.
    return min, max
end

combatHeal:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

-- buff icon
local combatBuffIcon = Combat()
combatBuffIcon:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combatBuffIcon:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local condition = Condition(CONDITION_REGENERATION)
condition:setParameter(CONDITION_PARAM_TICKS, config.buffTimer * 1000) -- 1 minute
condition:setParameter(CONDITION_PARAM_BUFF_SPELL, true)
combatBuffIcon:addCondition(condition)

local function passiveHealParty(casterId, ticks, distance, mathRandom, chance, manaRequired, allowCasterToSupplementMana, itemsRequired)
    -- confirm caster exists
    local caster = Player(casterId)
    if not caster then
        return
    end
    -- loop function
    if ticks > 0 then
        addEvent(passiveHealParty, 1000, casterId, ticks - 1, distance, mathRandom, chance, manaRequired, allowCasterToSupplementMana, itemsRequired)
    end
    -- check item requirements
    local leftHand, rightHand = caster:getSlotItem(CONST_SLOT_LEFT), caster:getSlotItem(CONST_SLOT_RIGHT)
    if not leftHand or not rightHand or not table.contains(itemsRequired.leftHand, leftHand:getId()) or not table.contains(itemsRequired.rightHand, rightHand:getId()) then
        if ticks % 5 == 0 and ticks > 0 then
            caster:sendCancelMessage("Wand or Spellbook not found in hand slots. Healing effect is suspended.")
        end
        return
    end
    -- confirm party exists
    local party = caster:getParty()
    if not party then
        if ticks % 10 == 0 and ticks > 0 then
            caster:sendCancelMessage("No party detected. Healing effect is suspended.")
        end
        return
    end
    -- find all party members and confirm they are within an acceptable distance
    local members = party:getMembers()
    table.insert(members, party:getLeader())
    local casterPos, memberPos = caster:getPosition()
    for i = #members, 1, -1 do
        if caster ~= members[i] then
            memberPos = members[i]:getPosition()
            if casterPos:getDistance(memberPos) > distance.tiles then
                table.remove(members, i)
            elseif memberPos.z > casterPos.z + distance.floors or memberPos.z < casterPos.z - distance.floors then
                table.remove(members, i)
            end
        end
    end
    if #members < 2 then
        if ticks % 5 == 0 and ticks > 0 then
            caster:sendCancelMessage("Party currently has fewer then 2 players in range. Healing effect is suspended.")
        end
        return
    end
    -- spell activation chance
    local rand = math.random(mathRandom)
    if rand > chance then
        return
    end
    -- find lowest health party member, with enough mana to be auto-healed
    local memberToBeHealed, MTBHpercentHealth
    local currentHealth, maxHealth, percentHealth
    for i = 1, #members do
        currentHealth = members[i]:getHealth()
        maxHealth = members[i]:getMaxHealth()
        if currentHealth < maxHealth then
            if members[i]:getMana() >= manaRequired or allowCasterToSupplementMana and caster:getMana() >= manaRequired then
                percentHealth = currentHealth / maxHealth
                if memberToBeHealed == nil or percentHealth < MTBHpercentHealth then
                    memberToBeHealed = members[i]
                    MTBHpercentHealth = percentHealth
                end
            end
        end
    end
    -- if a party member was found to be healed..
    -- heal party member with caster's attributes (magicLevel, level), and remove mana from target
    if memberToBeHealed ~= nil then
        combatHeal:execute(caster, Variant(memberToBeHealed:getId()))
        if memberToBeHealed:getMana() >= manaRequired then
            memberToBeHealed:addMana(-manaRequired, true)
        else
            caster:addMana(-manaRequired, true)
        end
    end
end

function onCastSpell(creature, variant)
    passiveHealParty(creature:getId(), config.buffTimer, config.requiredMemberDistance, config.mathRandom, config.chance, config.manaRequired, config.allowCasterToSupplementMana, config.itemsRequired)
    return combatBuffIcon:execute(creature, variant)
end
 
Solution
Back
Top