• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Lua Silence zone

Ciosny

Member
Joined
Aug 16, 2024
Messages
131
Solutions
1
Reaction score
16
Hi :)

I'm trying to create a boss spell where players can't use spells or runes (both offensive and defensive) in a 3x3 area.

The mechanic works so that the boss casts an area spell (3x3) on a random player, and within this zone, for the duration of its effect, it is not possible to use offensive or defensive spells or runes.

I've set it up in various ways, but they can still use them. I'm doing something wrong, and any help would be appreciated :)
TFS 1.4.2

LUA:
local spell = Spell("instant")
spell:name("Silence Zone")
spell:words("silencezone")
spell:isAggressive(true)
spell:needLearn(false)
spell:vocation("no") -- boss spell, not for players

local ZONE_DURATION = 6000 -- 6 sekund
local RADIUS = 1 -- 3x3 area
local EFFECT = CONST_ME_PURPLEENERGY
local fieldId = ITEM_ENERGYFIELD_PVP

local function removeField(fieldUid)
    local field = Game.getUniqueItem(fieldUid)
    if field then
        field:remove()
    end
end

local function silencePlayer(player)
    local mute = Condition(CONDITION_MUTED)
    mute:setParameter(CONDITION_PARAM_TICKS, ZONE_DURATION)
    player:addCondition(mute)

    local pacify = Condition(CONDITION_PACIFIED)
    pacify:setParameter(CONDITION_PARAM_TICKS, ZONE_DURATION)
    player:addCondition(pacify)
end

function onCastSpell(creature, variant)
    -- Wybierz losowego gracza z areny
    local players = Game.getPlayers()
    if #players == 0 then return false end

    local validTargets = {}
    for _, player in ipairs(players) do
        if player:getPosition():getDistance(creature:getPosition()) <= 10 then
            table.insert(validTargets, player)
        end
    end

    if #validTargets == 0 then return false end

    local target = validTargets[math.random(#validTargets)]
    local centerPos = target:getPosition()
    centerPos:sendMagicEffect(EFFECT)

    for dx = -RADIUS, RADIUS do
        for dy = -RADIUS, RADIUS do
            local pos = Position(centerPos.x + dx, centerPos.y + dy, centerPos.z)
            local tile = Tile(pos)
            if tile then
                -- Ucisz graczy na danej kratce
                for _, creatureInTile in ipairs(tile:getCreatures()) do
                    if creatureInTile:isPlayer() then
                        silencePlayer(creatureInTile)
                    end
                end

                -- Dodaj pole wyciszenia
                if tile:isWalkable() then
                    local field = Game.createItem(fieldId, 1, pos)
                    if field then
                        field:setActionId(45000) -- dla np. dodatkowej logiki
                        addEvent(removeField, ZONE_DURATION, field:getUniqueId())
                    end
                end
            end
        end
    end
    return true
end

spell:register()
 
Solution
Hi :)

I'm trying to create a boss spell where players can't use spells or runes (both offensive and defensive) in a 3x3 area.

The mechanic works so that the boss casts an area spell (3x3) on a random player, and within this zone, for the duration of its effect, it is not possible to use offensive or defensive spells or runes.

I've set it up in various ways, but they can still use them. I'm doing something wrong, and any help would be appreciated :)
TFS 1.4.2

LUA:
local spell = Spell("instant")
spell:name("Silence Zone")
spell:words("silencezone")
spell:isAggressive(true)
spell:needLearn(false)
spell:vocation("no") -- boss spell, not for players

local ZONE_DURATION = 6000 -- 6 sekund
local RADIUS = 1 -- 3x3 area
local...
Hi :)

I'm trying to create a boss spell where players can't use spells or runes (both offensive and defensive) in a 3x3 area.

The mechanic works so that the boss casts an area spell (3x3) on a random player, and within this zone, for the duration of its effect, it is not possible to use offensive or defensive spells or runes.

I've set it up in various ways, but they can still use them. I'm doing something wrong, and any help would be appreciated :)
TFS 1.4.2

LUA:
local spell = Spell("instant")
spell:name("Silence Zone")
spell:words("silencezone")
spell:isAggressive(true)
spell:needLearn(false)
spell:vocation("no") -- boss spell, not for players

local ZONE_DURATION = 6000 -- 6 sekund
local RADIUS = 1 -- 3x3 area
local EFFECT = CONST_ME_PURPLEENERGY
local fieldId = ITEM_ENERGYFIELD_PVP

local function removeField(fieldUid)
    local field = Game.getUniqueItem(fieldUid)
    if field then
        field:remove()
    end
end

local function silencePlayer(player)
    local mute = Condition(CONDITION_MUTED)
    mute:setParameter(CONDITION_PARAM_TICKS, ZONE_DURATION)
    player:addCondition(mute)

    local pacify = Condition(CONDITION_PACIFIED)
    pacify:setParameter(CONDITION_PARAM_TICKS, ZONE_DURATION)
    player:addCondition(pacify)
end

function onCastSpell(creature, variant)
    -- Wybierz losowego gracza z areny
    local players = Game.getPlayers()
    if #players == 0 then return false end

    local validTargets = {}
    for _, player in ipairs(players) do
        if player:getPosition():getDistance(creature:getPosition()) <= 10 then
            table.insert(validTargets, player)
        end
    end

    if #validTargets == 0 then return false end

    local target = validTargets[math.random(#validTargets)]
    local centerPos = target:getPosition()
    centerPos:sendMagicEffect(EFFECT)

    for dx = -RADIUS, RADIUS do
        for dy = -RADIUS, RADIUS do
            local pos = Position(centerPos.x + dx, centerPos.y + dy, centerPos.z)
            local tile = Tile(pos)
            if tile then
                -- Ucisz graczy na danej kratce
                for _, creatureInTile in ipairs(tile:getCreatures()) do
                    if creatureInTile:isPlayer() then
                        silencePlayer(creatureInTile)
                    end
                end

                -- Dodaj pole wyciszenia
                if tile:isWalkable() then
                    local field = Game.createItem(fieldId, 1, pos)
                    if field then
                        field:setActionId(45000) -- dla np. dodatkowej logiki
                        addEvent(removeField, ZONE_DURATION, field:getUniqueId())
                    end
                end
            end
        end
    end
    return true
end

spell:register()
Do not use the Game.getPlayers() function. You dont need to iterate through the entire server every time a monster casts a spell

The same goes for the spell effect:
Add it using the combat object like this:
LUA:
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE)
The spell radius should also be defined through combat:
Code:
combat:setArea(createCombatArea(AREA_SQUAREWAVE6))

Use this script as a reference:
Code:
local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 8000)
condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, 85)

local combat = Combat()
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE)
combat:setArea(createCombatArea(AREA_SQUAREWAVE6))
combat:setCondition(condition)

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

Try writing it yourself without AI. Its not difficult case
 
Solution
Do not use the Game.getPlayers() function. You dont need to iterate through the entire server every time a monster casts a spell

The same goes for the spell effect:
Add it using the combat object like this:
LUA:
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE)
The spell radius should also be defined through combat:
Code:
combat:setArea(createCombatArea(AREA_SQUAREWAVE6))

Use this script as a reference:
Code:
local condition = Condition(CONDITION_ATTRIBUTES)
condition:setParameter(CONDITION_PARAM_TICKS, 8000)
condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, 85)

local combat = Combat()
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE)
combat:setArea(createCombatArea(AREA_SQUAREWAVE6))
combat:setCondition(condition)

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

Try writing it yourself without AI. Its not difficult case
Done :) Thanks
 
Last edited:
Back
Top