• 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 Help with sendMagicEffect appearing on the player

Icaraii

Well-Known Member
Joined
Jan 5, 2020
Messages
469
Solutions
1
Reaction score
58
I have this spell, that is a summon bomb and it works perfectly. However, when I put sprites bigger than 32x32, I need to put offset (x,y) for the effect to appear where I want, but when I do this, the effect is appearing on the caster, instead of appearing where the summon died. What am I doing wrong?

spell.lua:
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setArea(createCombatArea(AREA_SQUARE1X1))
combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true)
combat:setParameter(COMBAT_PARAM_BLOCKSHIELD, true)

function onGetFormulaValues(player, skill, attack, skill, factor)
    local maxHealth = player:getMaxHealth()
    local maxMana = player:getMaxMana()
    local playlvl = player:getLevel()
    
    local min = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 0,55
    local max = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 1,1
    
    return -min, -max   
end
combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues")


function onCastSpell(cid, var)
    local player = Player(cid)
    if player == nil then
        return false
    end
 
    local playerPos = player:getPosition()
    if #player:getSummons() >= 2 then
        player:sendCancelMessage("You cannot summon more creatures.")
        playerPos:sendMagicEffect(CONST_ME_POFF)
        return false
    end

    local creatureId = doSummonCreature("Barrelbomb", playerPos)
    if creatureId == false then
        player:sendCancelMessage(RET_NOTENOUGHROOM)
        playerPos:sendMagicEffect(CONST_ME_POFF)
        return false
    end

    local monster = Monster(creatureId)
    monster:setMaster(player)
    monster:registerEvent("barrelbomb")

    addEvent(function(cid)
        local creature = Creature(cid)
        if creature ~= nil then
            local player = creature:getMaster()
            if player then
                combat:execute(player, numberToVariant(cid))
            else
                combat:execute(creature, numberToVariant(cid))
            end
            local creaturePos = creature:getPosition()
            creaturePos.x = creaturePos.x +1
            creaturePos.y = creaturePos.y +1
            creaturePos:sendMagicEffect(122)
            creature:remove()
        end
    end, 5000, creatureId)

    monster:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
    playerPos:sendMagicEffect(CONST_ME_MAGIC_BLUE)
    return true
end

creaturescript.lua:
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setArea(createCombatArea(AREA_SQUARE1X1))
combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true)
combat:setParameter(COMBAT_PARAM_BLOCKSHIELD, true)

function onGetFormulaValues(player, skill, attack, skill, factor)
    local maxHealth = player:getMaxHealth()
    local maxMana = player:getMaxMana()
    local playlvl = player:getLevel()
    
    local min = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 0,55
    local max = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 1,1
    
    return -min, -max   
end
combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues")

function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
    local master = creature:getMaster()
    if master then
        combat:execute(master, numberToVariant(cid))
    else
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        combat:execute(creature, numberToVariant(cid))
    end
    return true
end
 
Lua:
function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
    local master = creature:getMaster()
    if master then
        combat:execute(master, numberToVariant(cid))
    else
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        combat:execute(creature, numberToVariant(cid))
    end
    return true
end

This means that if there is a master it will execute:
Code:
combat:execute(master, numberToVariant(cid))
meaning that the latter part which is containing sending the effect will never be executed if the monster is a summon (because summon always has master).
 
combat:execute(master, numberToVariant(cid))
So for it to work like I need, I should take off this part?
Lua:
if master then
        combat:execute(master, numberToVariant(cid))

I took it off, but still appear the effet on master instead of summon local position.

Is there a way to solve this and achiev what I need?
 
So for it to work like I need, I should take off this part?
Lua:
if master then
        combat:execute(master, numberToVariant(cid))
Try this:
Lua:
function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
    local master = creature:getMaster()
    if master then
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        combat:execute(creature, numberToVariant(cid))
    end
    return true
end
 
Try this:
Lua:
function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
    local master = creature:getMaster()
    if master then
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        combat:execute(creature, numberToVariant(cid))
    end
    return true
end
So I tested this, and no errors appear on tfs, but the effet doesnt appear
 
Did you register the script at monster.xml file?
No. I only made the spell and registered the creaturescript.

XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<monster name="Barrel" namedescription="a Barrel" race="blood" experience="0" speed="0" manacost="0">
    <health now="1" max="1" />
    <look type="1168"/>
    <targetchange interval="4000" chance="0" />
    <flags>
        <flag summonable="0" />
        <flag attackable="1" />
        <flag hostile="0" />
        <flag illusionable="0" />
        <flag convinceable="0" />
        <flag pushable="0" />
        <flag canpushitems="0" />
        <flag canpushcreatures="0" />
        <flag targetdistance="0" />
        <flag staticattack="0" />
        <flag runonhealth="0" />
        <flag canwalkonenergy="0" />
        <flag canwalkonfire="0" />
        <flag canwalkonpoison="0" />
    </flags>
</monster>
 
Quick lesson:
When you create a creaturescript you need to add it to a creature somehow. For players you do it with onlogin script (usually login.lua).
For monsters you need to edit their .xml file and add:
Lua:
<script>
        <event name="Creaturevent name"/>
</script>
 
Quick lesson:
When you create a creaturescript you need to add it to a creature somehow. For players you do it with onlogin script (usually login.lua).
For monsters you need to edit their .xml file and add:
Lua:
<script>
        <event name="Creaturevent name"/>
</script>
I imagine I didn't need to do that, because it was basically working, only the effect appearing in the wrong place, but thanks for the example, I didn't know how to put the event on the monster.xml

I tested and it doesn't appear the effect and no error appear on TFS
 
Try this and tell me what happens in the console.
Lua:
function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
    local master = creature:getMaster()
    print("1")
    if master then
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        print("2")
        combat:execute(creature, numberToVariant(cid))
        print("3")
    end
    return true
end
 
function onDeath(creature, variant, cid, ...) local creature = Creature(cid) local master = creature:getMaster() print("1") if master then combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0) local creaturePos = creature:getPosition() creaturePos.x = creaturePos.x +1 creaturePos.y = creaturePos.y +1 creaturePos:sendMagicEffect(122) print("2") combat:execute(creature, numberToVariant(cid)) print("3") end return true end
Icarai has logged in.
1

just that
 
Try now
Lua:
function onDeath(creature, variant, cid, ...)
    local creature = Creature(cid)
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(122)
        combat:execute(creature, numberToVariant(cid))
    return true
end
 
function onDeath(creature, variant, cid, ...) local creature = Creature(cid) combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0) local creaturePos = creature:getPosition() creaturePos.x = creaturePos.x +1 creaturePos.y = creaturePos.y +1 creaturePos:sendMagicEffect(122) combat:execute(creature, numberToVariant(cid)) return true end
The effect appear on the master again, no error on TFS.

Also, while we are trying to fix it, I would like to use this formula to do damage:
Lua:
function onGetFormulaValues(player, skill, attack, skill, factor)
    local maxHealth = player:getMaxHealth()
    local maxMana = player:getMaxMana()
    local playlvl = player:getLevel()
    
    local min = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 0,55
    local max = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 1,1
    
    return -min, -max   
end
combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues")
I don't know if it's using the one abouve or this one:
Lua:
        combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
 
Delete this:
Lua:
combat:setFormula(COMBAT_FORMULA_DAMAGE, -10, 0, -20, 0)
It wasn't doing damage when I delete this, but I manage to make it work, don't know if that was the best way to do it, but it was the way I manage:

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setArea(createCombatArea(AREA_SQUARE1X1))
combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true)
combat:setParameter(COMBAT_PARAM_BLOCKSHIELD, true)

local function getWeapon(player)
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    
    if not weapon then
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
    end

    return weapon and ItemType(weapon:getId()) or nil
end

local function calculateDamage(player)
    local maxHealth = player:getMaxHealth()
    local maxMana = player:getMaxMana()
    local playlvl = player:getLevel()
    local mlvl = player:getMagicLevel()
    local shielding = player:getSkillLevel(SKILL_SHIELD)
    local weapon = getWeapon(player)

    local skill = weapon and player:getSkillLevel(weapon:getWeaponType()) or 1
    local attack = weapon and weapon:getAttack() or 1
    local min = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 0,825
    local max = ((playlvl < 300 and playlvl or 300) + ((maxHealth + maxMana) / 16) + (attack * 4) + (skill * 2)) * 1,65
    return math.floor(min), math.floor(max)
end

function onDeath(creature, variant, cid, ...)
    local player = creature:getMaster()
    if  not player then
        return false
    end

    local min, max = calculateDamage(player)
    combat:setFormula(COMBAT_FORMULA_DAMAGE, -min, 0, -max, 0)
        local creaturePos = creature:getPosition()
        creaturePos.x = creaturePos.x +1
        creaturePos.y = creaturePos.y +1
        creaturePos:sendMagicEffect(253)
        combat:execute(creature, numberToVariant(cid))
    return true
end
 
Good job doing it yourself. Next time if you don't know how to do something try searching something similar here on otland and simply edit it. That's how I started.
 
Back
Top