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

TFS 1.X+ Monster spell is damaging players inside PZ

jakub742

Active Member
Joined
May 1, 2010
Messages
199
Solutions
3
Reaction score
42
Location
Slovakia
Hello, i was trying to do a monster spell that would hit all players within specific range using Game.getSpectators() after delay using addEvent.

However not sure why when using
Code:
combat:execute(parameters.creatureId, Variant(player:getId()))
it will attack player even if he's standing in protection zone. I thought that it will do checks for pz and path is clear aswell.

In spells.xml i have following attributes
aggressive="1" needlearn="1" blockwalls="1"

Am i missing something or do i need to manually check that in my lua ?

LUA:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_LARGEROCK)
combat:setFormula(COMBAT_FORMULA_DAMAGE, -100, 0, -200, 0)



function onCastSpell(creature, variant)
     parameters = {creatureId = creature:getId(), position = creature:getPosition()}
    addEvent(castUltimate, 1500, parameters)
end
    


function castUltimate(parameters)
    local players = Game.getSpectators(parameters.position, false, true, 7, 7, 6, 6)
    for _, player in pairs(players) do
            if player.getId ~= nil then
            combat:execute(parameters.creatureId, Variant(player:getId()))
            end       
    end
    
end
 
First check if you have no pvp tools in rme on the same field. Because PZ tool alone is not enough.
Checked that and i didnt but after adding no pvp aswell player still gets damaged. Probably will do checks in LUA manually but its weird since
LUA:
void Combat::doCombat(Creature* caster, Creature* target) const
contains bool check canCombat
 
@jakub742
There are 2 problems:
  • only casting spell to tile (not to playerId) checks for TILESTATE_PROTECTIONZONE
  • only spells casted by Player (not Monster) to Player check for TILESTATE_NOPVPZONE

Why don't you use combat with area - you can setup area of same size/shape as yours getSpectators range - and Variant(oldPosition) to configure position of spell to monster position?
Then you can block damage to other monsters by executing damage in second combat with isPlayer() check:
LUA:
local targetCombat = Combat()
targetCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
targetCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_LARGEROCK)
targetCombat:setFormula(COMBAT_FORMULA_DAMAGE, -100, 0, -200, 0)

local areaCombat = Combat()
areaCombat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER)
areaCombat:setArea(createCombatArea(AREA_CIRCLE5X5))

function onTargetCreature(creature, target)
    -- block damage to other monsters
    if target:isPlayer() then
        targetCombat:execute(creature, Variant(target:getId()))
    end

    return true
end

areaCombat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature")

local function delayedSpellOnOldPosition(creatureId, position)
    -- make sure that spell only execute when attacking creature is alive
    local creature = Creature(creatureId)
    if not creature then
        return
    end

    areaCombat:execute(creature, Variant(position))
end

function onCastSpell(creature, variant)
    addEvent(delayedSpellOnOldPosition, 1000, creature:getId(), creature:getPosition())
    return true
end
areaCombat lists creatures that can be attacked (outside PZ, not behind wall) and shows area magic effect (you can move it to targetCombat to show effect only of players hit by spell)
targetCombat does damage and animates distance shot.

If you change:
LUA:
local function delayedSpellOnOldPosition(creatureId, position)
    -- make sure that spell only execute when attacking creature is alive
    local creature = Creature(creatureId)
    if not creature then
        return
    end

    areaCombat:execute(creature, Variant(position))
end
to:
LUA:
local function delayedSpellOnOldPosition(creatureId, position)
    areaCombat:execute(creatureId, Variant(position))
end
It will hit players after monster death, but there will be no 'attacker' defined, so they will get damage from nothing:
Code:
17:00 You lose 156 hitpoints due to an attack by a troll.
17:00 You lose 170 hitpoints. <<<--- after monster death
 
Last edited:
@jakub742
There are 2 problems:
  • only casting spell to tile (not to playerId) checks for TILESTATE_PROTECTIONZONE
  • only spells casted by Player (not Monster) to Player check for TILESTATE_NOPVPZONE

Why don't you use combat with area - you can setup area of same size/shape as yours getSpectators range - and Variant(oldPosition) to configure position of spell to monster position?
Then you can block damage to other monsters by executing damage in second combat with isPlayer() check:
LUA:
local targetCombat = Combat()
targetCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
targetCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_LARGEROCK)
targetCombat:setFormula(COMBAT_FORMULA_DAMAGE, -100, 0, -200, 0)

local areaCombat = Combat()
areaCombat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER)
areaCombat:setArea(createCombatArea(AREA_CIRCLE5X5))

function onTargetCreature(creature, target)
    -- block damage to other monsters
    if target:isPlayer() then
        targetCombat:execute(creature, Variant(target:getId()))
    end

    return true
end

areaCombat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature")

local function delayedSpellOnOldPosition(creatureId, position)
    -- make sure that spell only execute when attacking creature is alive
    local creature = Creature(creatureId)
    if not creature then
        return
    end

    areaCombat:execute(creature, Variant(position))
end

function onCastSpell(creature, variant)
    addEvent(delayedSpellOnOldPosition, 1000, creature:getId(), creature:getPosition())
    return true
end
areaCombat lists creatures that can be attacked (outside PZ, not behind wall) and shows area magic effect (you can move it to targetCombat to show effect only of players hit by spell)
targetCombat does damage and animates distance shot.

If you change:
LUA:
local function delayedSpellOnOldPosition(creatureId, position)
    -- make sure that spell only execute when attacking creature is alive
    local creature = Creature(creatureId)
    if not creature then
        return
    end

    areaCombat:execute(creature, Variant(position))
end
to:
LUA:
local function delayedSpellOnOldPosition(creatureId, position)
    areaCombat:execute(creatureId, Variant(position))
end
It will hit players after monster death, but there will be no 'attacker' defined, so they will get damage from nothing:
Code:
17:00 You lose 156 hitpoints due to an attack by a troll.
17:00 You lose 170 hitpoints. <<<--- after monster death
Thank you for such detailed answer ;) I’ll have a look into it. Always pleasure reading your posts, cheers.
 
Back
Top