• 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+ Avoid player death at Annhilator

ralke

(҂ ͠❛ ෴ ͡❛)ᕤ
Joined
Dec 17, 2011
Messages
1,643
Solutions
28
Reaction score
927
Location
Santiago - Chile
GitHub
ralke23
Twitch
ralke23
Hi there! May I request a little modification for this script? I got this annihilator script to use as base for a dungeon system, what I need is that if player dies inside local quest_range, they get teleported to local exit_position instead of dying and sending to the temple.

LUA:
local config = {
    duration = 10, -- time till reset, in minutes
    level_req = 100, -- minimum level to do quest
    min_players = 1, -- 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(1010, 1163, 11), toPos = Position(1007, 1151, 11)},
    [2] = {fromPos = Position(1009, 1163, 11), toPos = Position(1006, 1151, 11)},
    [3] = {fromPos = Position(1008, 1163, 11), toPos = Position(1005, 1151, 11)},
    [4] = {fromPos = Position(1007, 1163, 11), toPos = Position(1004, 1151, 11)}
}
 
local monsters = {
    [1] = {pos = Position(1004, 1149, 11), name = "Demon"},
    [2] = {pos = Position(1006, 1149, 11), name = "Demon"},
    [3] = {pos = Position(1008, 1151, 11), name = "Annihilator"},
    [4] = {pos = Position(1009, 1151, 11), name = "Annihilator"},
    [5] = {pos = Position(1005, 1153, 11), name = "Demon"},
    [6] = {pos = Position(1007, 1153, 11), name = "Demon"}
}
 
local quest_range = {fromPos = Position(1003, 1146, 11), toPos = Position(1022, 1154, 11)} -- see image in thread for explanation
 
local exit_position = Position(998, 1163, 11) -- 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

Regards!
 
Solution
I'm on my smartphone, but I think this might help you come up with an idea

LUA:
-- CreatureEvents --
local creatureevent = CreatureEvent("questDeath")
function creatureevent.onPrepareDeath(creature, killer)
	if not creature:isPlayer() then
		return true
	end
	
	local player = Player(creature)
    local fromPos = Position(1003, 1146, 11)
    local toPos = Position(1022, 1154, 11)
	if player and player:getPosition():isInRange(fromPos, toPos) then		
		player:teleportTo(Position(998, 1163, 11))
		player:addHealth(player:getMaxHealth())
		player:addMana(player:getMaxMana())
		return false
	end
	return true
end
creatureevent:register()

In login.lua add
LUA:
player:registerEvent("questDeath")
I'm on my smartphone, but I think this might help you come up with an idea

LUA:
-- CreatureEvents --
local creatureevent = CreatureEvent("questDeath")
function creatureevent.onPrepareDeath(creature, killer)
	if not creature:isPlayer() then
		return true
	end
	
	local player = Player(creature)
    local fromPos = Position(1003, 1146, 11)
    local toPos = Position(1022, 1154, 11)
	if player and player:getPosition():isInRange(fromPos, toPos) then		
		player:teleportTo(Position(998, 1163, 11))
		player:addHealth(player:getMaxHealth())
		player:addMana(player:getMaxMana())
		return false
	end
	return true
end
creatureevent:register()

In login.lua add
LUA:
player:registerEvent("questDeath")
 
Solution
I'm on my smartphone, but I think this might help you come up with an idea

LUA:
-- CreatureEvents --
local creatureevent = CreatureEvent("questDeath")
function creatureevent.onPrepareDeath(creature, killer)
    if not creature:isPlayer() then
        return true
    end
   
    local player = Player(creature)
    local fromPos = Position(1003, 1146, 11)
    local toPos = Position(1022, 1154, 11)
    if player and player:getPosition():isInRange(fromPos, toPos) then       
        player:teleportTo(Position(998, 1163, 11))
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())
        return false
    end
    return true
end
creatureevent:register()

In login.lua add
LUA:
player:registerEvent("questDeath")
Excellent! This looks really clean and seems to work for any time I need to achieve this in a frompos/topos area. Thanks a lot!
 
Back
Top