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

Action [TFS 1.3] Advanced Annihilator System

Apollos

Dude who does stuff
Joined
Apr 22, 2009
Messages
829
Solutions
123
Reaction score
655
Location
United States
Features:
  • Supports multiple different creatures
  • Supports custom participant amount
  • Automatic reset
  • Fully customizable
  • Error notifications
  • Should work for other TFS 1.X servers

annihilator.lua
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(position, cid_array)
    local tile = Tile(position)
    local item = tile and tile:getItemById(config.pulled_id)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[#monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, toPosition, cid_array)
    return true
end

annihilator_chest.lua
Lua:
local storage_id = 2000

local rewards = {
    [2001] = {reward_id = 2494, reward_count = 1}, -- [chest uid] = {reward item id, reward item count},
    [2002] = {reward_id = 2400, reward_count = 1},
    [2003] = {reward_id = 2431, reward_count = 1},
    [2004] = {reward_id = 2421, reward_count = 1}
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local storage = player:getStorageValue(storage_id)
    if storage > 0 then
        return player:sendTextMessage(MESSAGE_INFO_DESCR, "It is empty.")
    end

    local reward = rewards[item.uid]
    local reward_type = reward and ItemType(reward.reward_id)
    if reward_type then
        if player:addItem(reward.reward_id, reward.reward_count, false, 1, CONST_SLOT_WHEREEVER) then
            player:sendTextMessage(MESSAGE_INFO_DESCR, "You have found a " .. reward_type:getName():lower() .. ".")
            player:setStorageValue(storage_id, 1)
        else
            local weight = reward_type:getWeight()
            player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have found an item weighing ' .. weight / 100 .. ' oz it\'s too heavy or you do not have enough room.')
        end
    end
    return true
end

quest_range explanation
1570240581921.png
 
The only problem I see is players that are in the quest can stay in there if I am not mistaken.
 
The only problem I see is players that are in the quest can stay in there if I am not mistaken.
Yeah, you're right. I can check for players within the existing set positions, but then it would still leave the possibility for a player to be standing in the doorway still. Otherwise I could add a parameter of an array of players joined to resetAnnihilator and check within a range to see if they are there.

If you got a better idea let me know, otherwise i'll add this fix later on.
 
Made some changes based on Itutorial's suggestion. Included isInRange check for players inside quest area within resetAnnihilator.

quest_range explanation
35537

annihilator.lua
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(uid, cid_array)
    local item = Item(uid)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, item.uid, cid_array)
    return true
end
 
Dumb mistake found regarding resetting of lever. Sorry for any inconvenience. If a mod happens along this post, I would be really grateful if you updated the original posts annihilator.lua with this one.

annihilator.lua
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(position, cid_array)
    local tile = Tile(position)
    local item = tile and tile:getItemById(config.pulled_id)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, toPosition, cid_array)
    return true
end
 
This script gives me different rewards to those that are established.
Lua:
local storage_id = 2000

local rewards = {
    [1] = {chest_uid = 2001, reward_id = 2494, reward_count = 1},
    [2] = {chest_uid = 2002, reward_id = 2400, reward_count = 1},
    [3] = {chest_uid = 2003, reward_id = 2431, reward_count = 1},
    [4] = {chest_uid = 2004, reward_id = 2421, reward_count = 1}
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local storage = player:getStorageValue(storage_id)
    if storage > 0 then
        return player:sendTextMessage(MESSAGE_INFO_DESCR, "It is empty.")
    end

    local reward
    for i = 1, #rewards do
        if rewards[i].chest_uid == item.uid then
            reward = rewards[i]
            break
        end
    end

    local reward_type = ItemType(reward.reward_id)
    if reward_type then
        if player:addItem(reward.reward_id, reward.reward_count, false, 1, CONST_SLOT_WHEREEVER) then
            player:sendTextMessage(MESSAGE_INFO_DESCR, "You have found a " .. reward_type:getName():lower() .. ".")
            player:setStorageValue(storage_id, 1)
        else
            local weight = reward_type:getWeight()
            player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have found an item weighing ' .. weight / 100 .. ' oz it\'s too heavy or you do not have enough room.')
        end
    end
    return true
end

19:00 You have found a dead orc.
19:00 You have found a dead goblin.
19:00 You have found a dead elf.
19:00 You have found a remains of a mummy.
 
Dumb mistake found regarding resetting of lever. Sorry for any inconvenience. If a mod happens along this post, I would be really grateful if you updated the original posts annihilator.lua with this one.

annihilator.lua
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(position, cid_array)
    local tile = Tile(position)
    local item = tile and tile:getItemById(config.pulled_id)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, toPosition, cid_array)
    return true
end
Hello, it doesnt reset Annihilator. This is what it says when its pulled
14:33 You see a lever.
Item ID: 1946, Action ID: 1573
as you can see its pulled_id = 1946 -- id of lever after pulled
but it doesnt reset
 
Hello, it doesnt reset Annihilator. This is what it says when its pulled
14:33 You see a lever.
Item ID: 1946, Action ID: 1573
as you can see its pulled_id = 1946 -- id of lever after pulled
but it doesnt reset
Did you try the most recent update? The last reply I posted on this thread?
 
Did you try the most recent update? The last reply I posted on this thread?
Yes i did ctrl+c your entire
function doResetAnnihilator(position, cid_array)
and
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
 
Yes i did ctrl+c your entire
function doResetAnnihilator(position, cid_array)
and
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
Try this one out.
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(position, cid_array)
    local tile = Tile(position)
    local item = tile and tile:getItemById(config.pulled_id)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[#monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, toPosition, cid_array)
    return true
end
 
Try this one out.
Lua:
local config = {
    duration = 30, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 4, -- minimum players to join quest
    lever_id = 1945, -- id of lever before pulled
    pulled_id = 1946 -- id of lever after pulled
}

local player_positions = {
    [1] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [2] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [3] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)},
    [4] = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)}
}

local monsters = {
    [1] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [2] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [3] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [4] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [5] = {pos = Position(1000, 1000, 7), name = "Demon"},
    [6] = {pos = Position(1000, 1000, 7), name = "Demon"}
}

local quest_range = {fromPos = Position(1000, 1000, 7), toPos = Position(1000, 1000, 7)} -- see image in thread for explanation

local exit_position = Position(1000, 1000, 7) -- Position completely outside the quest area

function doResetAnnihilator(position, cid_array)
    local tile = Tile(position)
    local item = tile and tile:getItemById(config.pulled_id)
    if not item then
        return
    end

    local monster_names = {}
    for key, value in pairs(monsters) do
        if not isInArray(monster_names, value.name) then
            monster_names[#monster_names + 1] = value.name
        end
    end

    for i = 1, #monsters do
        local creatures = Tile(monsters[i].pos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for i = 1, #player_positions do
        local creatures = Tile(player_positions[i].toPos):getCreatures()
        for key, creature in pairs(creatures) do
            if isInArray(monster_names, creature:getName()) then
                creature:remove()
            end
        end
    end

    for key, cid in pairs(cid_array) do
        local participant = Player(cid)
        if participant and isInRange(participant:getPosition(), quest_range.fromPos, quest_range.toPos) then
            participant:teleportTo(exit_position)
            exit_position:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end

    item:transform(config.lever_id)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid ~= config.lever_id then
        return player:sendCancelMessage("The quest is currently in use. Cooldown is " .. config.duration .. " minutes.")
    end

    local participants, pull_player = {}, false
    for i = 1, #player_positions do
        local fromPos = player_positions[i].fromPos
        local tile = Tile(fromPos)
        if not tile then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. fromPos.x .. ", " .. fromPos.y .. ", " .. fromPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end

        local creature = tile:getBottomCreature()
        if creature then
            local participant = creature:getPlayer()
            if not participant then
                return player:sendCancelMessage(participant:getName() .. " is not a valid participant.")
            end

            if participant:getLevel() < config.level_req then
                return player:sendCancelMessage(participant:getName() .. " is not the required level.")
            end

            if participant.uid == player.uid then
                pull_player = true
            end

            participants[#participants + 1] = {participant = participant, toPos = player_positions[i].toPos}
        end
    end

    if #participants < config.min_players then
        return player:sendCancelMessage("You do not have the required amount of participants.")
    end

    if not pull_player then
        return player:sendCancelMessage("You are in the wrong position.")
    end

    for i = 1, #monsters do
        local toPos = monsters[i].pos
        if not Tile(toPos) then
            print(">> ERROR: Annihilator tile does not exist for Position(" .. toPos.x .. ", " .. toPos.y .. ", " .. toPos.z .. ").")
            return player:sendCancelMessage("There is an issue with this quest. Please contact an administrator.")
        end
        Game.createMonster(monsters[i].name, monsters[i].pos, false, true)
    end

    local cid_array = {}
    for i = 1, #participants do
        participants[i].participant:teleportTo(participants[i].toPos)
        participants[i].toPos:sendMagicEffect(CONST_ME_TELEPORT)
        cid_array[#cid_array + 1] = participants[i].participant.uid
    end

    item:transform(config.pulled_id)
    addEvent(doResetAnnihilator, config.duration * 60 * 1000, toPosition, cid_array)
    return true
end
Still same :/
 
I just tested it. Make sure you reload the file and try again. If it's still not working check the console for any errors and if there are post them here.
I swear to god i reloaded everything multiple times checked everything multiple times either. No errors in console
Before -
15:51 You see a lever.
Item ID: 1945, Action ID: 1573
Position: 543, 722, 7

(After) And this is when someone is in ani
15:52 You see a lever.
Item ID: 1946, Action ID: 1573
Position: 543, 722, 7

duration is 1min, waited for 5mins didnt reseted. Maybe it doesnt reset for tfs 1.2it has some kind of bug or something
 
I swear to god i reloaded everything multiple times checked everything multiple times either. No errors in console
Before -
15:51 You see a lever.
Item ID: 1945, Action ID: 1573
Position: 543, 722, 7

(After) And this is when someone is in ani
15:52 You see a lever.
Item ID: 1946, Action ID: 1573
Position: 543, 722, 7

duration is 1min, waited for 5mins didnt reseted. Maybe it doesnt reset for tfs 1.2it has some kind of bug or something
I'm not sure, it was original made for 1.3, hence the title. But I have tested on base 1.2 with no issues. I'll have to double check later on today but are you sure this is a base TFS and not some editted version like ninjas 8.6 or something?
 
I'm not sure, it was original made for 1.3, hence the title. But I have tested on base 1.2 with no issues. I'll have to double check later on today but are you sure this is a base TFS and not some editted version like ninjas 8.6 or something?
Yea its edited by ninja i think 50% of people are using his version
 
Back
Top