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

RevScripts โค โ„ฑ๐“‡๐‘’๐‘’ ๐’ฎ๐’ธ๐“‡๐’พ๐“…๐“‰๐’พ๐“ƒ๐‘” ๐’ฎ๐‘’๐“‡๐“‹๐’พ๐’ธ๐‘’ ๐’ฏโ„ฑ๐’ฎ ๐Ÿท.๐Ÿป+ โค

Sarah Wesker

ฦฦ–ั”gฮฑฮทั‚ Sัƒฮทั‚ฮฑx โค
Staff member
TFS Developer
Support Team
Joined
Mar 16, 2017
Messages
1,422
Solutions
155
Reaction score
1,986
Location
London
GitHub
MillhioreBT
Twitch
millhiorebt
โค ๐…๐ซ๐ž๐ž ๐’๐œ๐ซ๐ข๐ฉ๐ญ๐ข๐ง๐  ๐’๐ž๐ซ๐ฏ๐ข๐œ๐ž ๐Ÿ.๐Ÿ“+ โค

๐Ÿ“š (ใฃโ—”โ—กโ—”)ใฃ โ„๐“ƒ๐’ป๐‘œ๐“‡๐“‚๐’ถ๐“‰๐’พ๐‘œ๐“ƒ ๐Ÿ“š
โค โ„ฐ๐“ƒ๐‘”๐’พ๐“ƒ๐‘’: ๐’ฏโ„ฑ๐’ฎ ๐’ช๐’ป๐’พ๐’ธ๐’พ๐’ถ๐“
โค โ„ฐ๐“ƒ๐‘”๐’พ๐“ƒ๐‘’ ๐’ฑ๐‘’๐“‡๐“ˆ๐’พ๐‘œ๐“ƒ: ๐Ÿท.๐Ÿป+

โš™๐Ÿ”งโ„‹๐‘œ๐“Œ ๐“‰๐‘œ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰ ๐’ถ ๐“ˆ๐’ธ๐“‡๐’พ๐“…๐“‰?
โค โ„ณ๐’ถ๐“€๐‘’ ๐“ˆ๐“Š๐“‡๐‘’ ๐“Ž๐‘œ๐“Š ๐“‚๐‘’๐‘’๐“‰ ๐“‰๐’ฝ๐‘’ ๐’ธ๐‘œ๐“‡๐“‡๐‘’๐’ธ๐“‰ ๐“‹๐‘’๐“‡๐“ˆ๐’พ๐‘œ๐“ƒ ๐’ถ๐“ƒ๐’น ๐‘’๐“ƒ๐‘”๐’พ๐“ƒ๐‘’.
โค ๐’ฏ๐“‡๐“Ž ๐“ƒ๐‘œ๐“‰ ๐“‰๐‘œ ๐“‚๐’ถ๐“€๐‘’ ๐“Ž๐‘œ๐“Š๐“‡ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰ ๐“‰๐‘œ๐‘œ ๐’ธ๐‘œ๐“‚๐“…๐“๐‘’๐“, ๐’ถ๐“ˆ ๐“‰๐’ฝ๐‘’ ๐“ˆ๐’พ๐“‚๐“…๐“๐‘’๐“ˆ๐“‰ ๐‘œ๐“ƒ๐‘’๐“ˆ ๐“Œ๐’พ๐“๐“ ๐’ท๐‘’ ๐“‰๐’ถ๐“€๐‘’๐“ƒ ๐’ธ๐’ถ๐“‡๐‘’ ๐‘œ๐’ป ๐’ป๐’พ๐“‡๐“ˆ๐“‰.
โค ๐’ด๐‘œ๐“Š ๐’ถ๐‘”๐“‡๐‘’๐‘’ ๐“ƒ๐‘œ๐“‰ ๐“‰๐‘œ ๐’ป๐’พ๐“๐‘’ ๐’ถ ๐‘”๐“‡๐’พ๐‘’๐“‹๐’ถ๐“ƒ๐’ธ๐‘’๐“ˆ ๐’พ๐’ป ๐“Ž๐‘œ๐“Š๐“‡ ๐’ถ๐“…๐“…๐“๐’พ๐’ธ๐’ถ๐“‰๐’พ๐‘œ๐“ƒ ๐’พ๐“ˆ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰๐‘’๐’น ๐’ท๐“Š๐“‰ ๐“ƒ๐‘’๐“‹๐‘’๐“‡ ๐“‡๐‘’๐“ˆ๐‘œ๐“๐“‹๐‘’๐’น.
โค ๐’ด๐‘œ๐“Š ๐“‚๐“Š๐“ˆ๐“‰ ๐’ฝ๐’ถ๐“‹๐‘’ ๐’ถ ๐’ธ๐‘’๐“‡๐“‰๐’ถ๐’พ๐“ƒ ๐“‡๐‘’๐“…๐“Š๐“‰๐’ถ๐“‰๐’พ๐‘œ๐“ƒ ๐’พ๐“ƒ ๐“‰๐’ฝ๐‘’ ๐’ป๐‘œ๐“‡๐“Š๐“‚, โ„ ๐’น๐‘œ ๐“ƒ๐‘œ๐“‰ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰๐“ˆ ๐’ป๐‘œ๐“‡ ๐“ƒ๐‘’๐“Œ ๐‘œ๐“‡ ๐“ˆ๐“Š๐“ˆ๐“…๐’พ๐’ธ๐’พ๐‘œ๐“Š๐“ˆ ๐’ถ๐’ธ๐’ธ๐‘œ๐“Š๐“ƒ๐“‰๐“ˆ, ๐“‰๐“‡๐“Ž ๐“ƒ๐‘œ๐“‰ ๐“‰๐‘œ ๐“Š๐“ˆ๐‘’ โ„ฑ๐’œ๐’ฆโ„ฐ๐’ฎ.
โค โ„›๐‘’๐“‚๐‘’๐“‚๐’ท๐‘’๐“‡ ๐“‹๐‘’๐“‡๐“Ž ๐“Œ๐‘’๐“๐“ ๐“‰๐’ฝ๐’ถ๐“‰ ๐’พ๐“‰ ๐’พ๐“ˆ ๐’ป๐‘œ๐“‡ ๐’ช๐’ป๐’ป๐’พ๐’ธ๐’พ๐’ถ๐“ ๐’ฏโ„ฑ๐’ฎ ๐“ˆ๐‘œ ๐’น๐‘œ๐“ƒ'๐“‰ ๐’ท๐‘œ๐“‰๐’ฝ๐‘’๐“‡ ๐’ถ๐“ˆ๐“€๐’พ๐“ƒ๐‘” ๐’ป๐‘œ๐“‡ ๐“ˆ๐‘œ๐“‚๐‘’๐“‰๐’ฝ๐’พ๐“ƒ๐‘” ๐’ป๐‘œ๐“‡ ๐“Ž๐‘œ๐“Š๐“‡ ๐‘œ๐“‰๐’ฝ๐‘’๐“‡ ๐‘’๐“ƒ๐‘”๐’พ๐“ƒ๐‘’, ๐’ถ๐“ˆ โ„ ๐“Œ๐’พ๐“๐“ ๐’พ๐‘”๐“ƒ๐‘œ๐“‡๐‘’ ๐“ˆ๐’ถ๐’พ๐’น ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰.
โค ๐’ฏ๐’ฝ๐‘’ ๐’น๐‘’๐“ˆ๐’ธ๐“‡๐’พ๐“…๐“‰๐’พ๐‘œ๐“ƒ ๐“‚๐“Š๐“ˆ๐“‰ ๐’ท๐‘’ ๐’พ๐“ƒ โ„ฐ๐“ƒ๐‘”๐“๐’พ๐“ˆ๐’ฝ ๐’ถ๐“ƒ๐’น ๐“Œ๐‘’๐“๐“ ๐‘’๐“๐“…๐“๐’ถ๐’พ๐“ƒ๐‘’๐’น ๐“Œ๐’พ๐“‰๐’ฝ๐‘œ๐“Š๐“‰ ๐“‰๐‘œ๐‘œ ๐“‚๐’ถ๐“ƒ๐“Ž ๐“Œ๐‘œ๐“‡๐’น๐“ˆ.

๐ŸŽ€โ„‹๐‘œ๐“Œ ๐’น๐‘œ โ„ ๐“€๐“ƒ๐‘œ๐“Œ ๐’พ๐’ป ๐“‚๐“Ž ๐’ถ๐“…๐“…๐“๐’พ๐’ธ๐’ถ๐“‰๐’พ๐‘œ๐“ƒ ๐“Œ๐’ถ๐“ˆ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰๐‘’๐’น?๐ŸŽ€
โค โ„๐’ป ๐“Ž๐‘œ๐“Š๐“‡ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰ ๐’ฝ๐’ถ๐“ˆ ๐“‚๐“Ž ๐“๐’พ๐“€๐‘’, ๐’พ๐“‰ ๐“‚๐‘’๐’ถ๐“ƒ๐“ˆ ๐“‰๐’ฝ๐’ถ๐“‰ ๐’พ๐“‰ ๐“Œ๐’ถ๐“ˆ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰๐‘’๐’น.
โค โ„๐’ป ๐“Ž๐‘œ๐“Š๐“‡ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰ ๐’พ๐“ˆ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰๐‘’๐’น, ๐“Ž๐‘œ๐“Š ๐’ฟ๐“Š๐“ˆ๐“‰ ๐’ฝ๐’ถ๐“‹๐‘’ ๐“‰๐‘œ ๐“Œ๐’ถ๐’พ๐“‰ ๐’ป๐‘œ๐“‡ ๐“‚๐‘’ ๐“‰๐‘œ ๐’ถ๐“ƒ๐“ˆ๐“Œ๐‘’๐“‡ ๐“Ž๐‘œ๐“Š๐“‡ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰.

๐’ฏ๐’ฝ๐’พ๐“ˆ ๐’พ๐“ˆ ๐“‚๐“Ž ๐‘œ๐“๐’น ๐’ป๐“‡๐‘’๐‘’ ๐“ˆ๐‘’๐“‡๐“‹๐’พ๐’ธ๐‘’๐“ˆ ๐“‰๐’ฝ๐“‡๐‘’๐’ถ๐’น ๐’พ๐’ป ๐“Ž๐‘œ๐“Š'๐’น ๐“๐’พ๐“€๐‘’ ๐“‰๐‘œ ๐’ธ๐’ฝ๐‘’๐’ธ๐“€ ๐’ท๐‘’๐’ป๐‘œ๐“‡๐‘’ ๐“Ž๐‘œ๐“Š ๐’ถ๐“ˆ๐“€ ๐’ป๐‘œ๐“‡ ๐“ˆ๐‘œ๐“‚๐‘’๐“‰๐’ฝ๐’พ๐“ƒ๐‘” ๐“‡๐‘’๐“…๐‘’๐’ถ๐“‰๐‘’๐’น.

๐Ÿ“Œ โ„›๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰ ๐‘’๐“๐’ถ๐“‚๐“…๐“๐‘’: ๐Ÿ“Œ

โ„ฐ๐“ƒ๐‘”๐’พ๐“ƒ๐‘’ ๐’ถ๐“ƒ๐’น ๐’ฑ๐‘’๐“‡๐“ˆ๐’พ๐‘œ๐“ƒ โœ…
๐’Ÿ๐‘’๐“ˆ๐’ธ๐“‡๐’พ๐“…๐“‰๐’พ๐‘œ๐“ƒ ๐Ÿ“‘
...
 
Hey Sarah, TFS 1.5/ OT client mehah
Thanks for helping! :D

Okay so I have this script that upgrades a helmet and adds arm to it. What I'm trying to figure out is how to add more stats to it such as % absorb, damage, or skills. I've tried a bunch of different things but realized that those stats are not in the attribute list and someone told me that I can add those stats by creating custom attributes. Now I have no idea how to create custom attributes so if its at all possible Could you create a script for me that creates 3 custom attributes or if that's a long process then just one is fine. I don't know where to start and just having one simple script to base things off can help me tons in doing the rest. Here is the script for the helmet upgrade.

Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getActionId() == 105 and
    player:getItemCount(12403) >= 10 then
    
    item:setAttribute("armor", item:getAttribute("armor") + 5)
    item:setAttribute("description", "hello ez")
    item:setCustomAttribute("skillSword", 5)
    item:setAttribute("name", "Mountain Helmet (Journeyman)")
    player:removeItem(12403,10)
    item:setActionId(106)
    player:getPosition():sendMagicEffect(CONST_ME_BLUECHAIN)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "You have upgraded your mountain helmet from apprentice to journeyman!")
    
    elseif item:getActionId() == 105 and
    player:getItemCount(12403) < 10 then
    
    player:say("You do not have enough upgrade materials.", TALKTYPE_MONSTER_SAY)
    
        end
    return true
end

The skill sword one doesn't work ofc cause I don't have any custom attributes as I've said. Thanks again!
 
Talkaction example !magictrain and use spell Utevo mana every second and if you want stop this repeat command !magictrain
data/scripts/manatrain.lua
Lua:
local config = {
    talkAction = "!magictrain",
    regenManaPercent = 0.05,
    regenManaInterval = 1000,
    maxRegenMana = 500,
    minRegenMana = 35,
    dummySpellWords = "utamo mana"
}

local cache = {}

local function magicTrain(playerGuid)
    local player = Player(playerGuid)
    if not player then return end
    local mana = player:getMana()
    local maxMana = player:getMaxMana()
    if mana >= maxMana then
        player:say(config.dummySpellWords, TALKTYPE_MONSTER_SAY)
        player:addMana(-mana)   
        player:addManaSpent(mana)
    else
        local manaToRegen = math.min(maxMana / 100 * config.regenManaPercent,
                                     config.maxRegenMana)
        manaToRegen = math.max(manaToRegen, config.minRegenMana)
        player:addMana(manaToRegen)
    end

    cache[playerGuid] = addEvent(magicTrain, config.regenManaInterval, playerGuid)
end

local talkAction = TalkAction(config.talkAction)

function talkAction.onSay(player, words, param, type)
    local playerGuid = player:getGuid()
    if not cache[playerGuid] then
        cache[playerGuid] = addEvent(magicTrain, config.regenManaInterval, playerGuid)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE,
                               "You have started to regenerate mana.")
    else
        stopEvent(cache[playerGuid])
        cache[playerGuid] = nil
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE,
                               "You have stopped to regenerate mana.")
    end
    return false
end

talkAction:separator(" ")
talkAction:register()
 
Last edited:
Hi Sara, I researched a lot about it, and I couldn't create a function where the vip system also adds critical dmg and chance, could you help me? source: Vip System

and another detail, I tried to adapt the Item Loot Seller to be usable in an item, but I was unsuccessful: Loot Seller

I use canary server
 
How would I change this script to be an exclusive hunt instead of a boss room?

Lua:
local config = {
    actionId = 5900, -- ActionID to use in the lever
    bossName = "Demon",
    bossPosition = Position(3111, 1846, 7), -- Position where the boss will appear
    bossArea = {
        fromPos = Position(3101, 1845, 7), -- Upper left corner of the room
        toPos = Position(3120, 1855, 7), -- Lower right corner of the room
        entrancePos = Position(3119, 1845, 7), -- Position where players will be teleported when they enter
        exitPosition = Position(3118, 1842, 7) -- If the participants take too long they will be kicked from the room to this position
    },
    allowedAnyParticipantsCount = true, -- allow any valid number of participants to enter. example: 1,2,3 or 4
    participantsPos = {
        Position(3117, 1842, 7), -- Player 1, this player should be the one to pull the lever
        Position(3118, 1842, 7), -- Player 2
        Position(3119, 1842, 7), -- Player 3
        Position(3120, 1842, 7) -- Player 4
    },
    attempts = {
        level = 200, -- Level required to enter
        storage = 20000, -- Storage where we keep the waiting time
        seconds = 72000 -- 20 hours
    },
    createTeleportPos = Position(3112, 1845, 7), -- Position where the teleport is created when the boss dies
    teleportToPosition = Position(3122, 1845, 7), -- Position where the teleport created by the boss will take you when you die
    teleportRemoveSeconds = 10, -- seconds
    kickParticipantAfterSeconds = 60 * 15, -- 15 minutes
    leverIds = {1945, 1946} -- Lever animation, on/off
}

local function getSpectators(onlyPlayers)
    if not config.centerPosition then
        config.diffX = math.ceil((config.bossArea.toPos.x - config.bossArea.fromPos.x) / 2)
        config.diffY = math.ceil((config.bossArea.toPos.y - config.bossArea.fromPos.y) / 2)
        config.centerPosition = config.bossArea.fromPos + Position(config.diffX, config.diffY, 0)
    end
    return Game.getSpectators(config.centerPosition, false, onlyPlayers, config.diffX, config.diffX, config.diffY, config.diffY)
end

local action = Action()

function action.onUse(player, item, fromPos, target, toPos, isHotkey)
    local participants = {}
    for index, pos in pairs(config.participantsPos) do
        local tile = Tile(pos)
        if not tile then error("[Warning - Tile not found]") end
        local participant = tile:getTopVisibleCreature(player)
        if participant and participant:isPlayer() then
            if index == 1 and participant ~= player then
                player:sendCancelMessage("Only the first participant can pull the lever.")
                return true
            end

            if participant:getStorageValue(config.attempts.storage) >= os.time() then
                player:sendCancelMessage(string.format("The player %s must wait a while before being able to enter again.", participant:getName()))
            elseif participant:getLevel() < config.attempts.level then
                player:sendCancelMessage(string.format("The player %s is not level %d.", participant:getName(), config.attempts.level))
            else
                participants[#participants +1] = participant
            end
        end
    end

    if #participants == 0 then
        player:sendCancelMessage("You need at least one participant.")
        return true
    elseif not config.allowedAnyParticipantsCount and #participants ~= #config.participantsPos then
        player:sendCancelMessage("You need all participants.")
        return true
    end

    if #getSpectators(true) > 0 then
        player:sendCancelMessage("At this time the room is occupied, please try again later.")
        return true
    end

    stopEvent(config.kickEventId)

    for _, monsterSpectator in pairs(getSpectators()) do
        monsterSpectator:remove()
    end

    local boss = Game.createMonster(config.bossName, config.bossPosition)
    if not boss then
        player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return true
    end

    boss:registerEvent("bossSystemDeath")

    for index, participant in pairs(participants) do
        participant:getPosition():sendMagicEffect(CONST_ME_POFF)
        participant:teleportTo(config.bossArea.entrancePos, false)
        participant:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
        participant:setStorageValue(config.attempts.storage, os.time() + config.attempts.seconds)
    end

    config.kickEventId = addEvent(function ()
        for _, spectator in pairs(getSpectators()) do
            if spectator:isPlayer() then
                spectator:getPosition():sendMagicEffect(CONST_ME_POFF)
                spectator:teleportTo(config.bossArea.exitPosition, false)
                spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                spectator:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It's been a long time and you haven't managed to defeat the boss.")
            else
                spectator:remove()
            end
        end
    end, config.kickParticipantAfterSeconds * 1000)
    item:transform(item:getId() == config.leverIds[1] and config.leverIds[2] or config.leverIds[1])
    return true
end

action:aid(config.actionId)
action:register()

local creatureEvent = CreatureEvent("bossSystemDeath")

function creatureEvent.onDeath()
    stopEvent(config.kickEventId)
    local teleport = Game.createItem(1387, 1, config.createTeleportPos)
    if teleport then
        teleport:setDestination(config.teleportToPosition)
        addEvent(function ()
            local tile = Tile(config.createTeleportPos)
            if tile then
                local teleport = tile:getItemById(1387)
                if teleport then
                    teleport:remove()
                    config.teleportToPosition:sendMagicEffect(CONST_ME_POFF)
                end
            end

            for _, spectator in pairs(getSpectators()) do
                if spectator:isPlayer() then
                    spectator:getPosition():sendMagicEffect(CONST_ME_POFF)
                    spectator:teleportTo(config.teleportToPosition, false)
                    spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                else
                    spectator:remove()
                end
            end
        end, config.teleportRemoveSeconds * 1000)
    end
    return true
end

creatureEvent:register()
 
data/scripts/roomDoorTomas.lua

Lua:
local config = {
    closedDoorId = 6250,
    openDoorId = 6251,
    doorActionId = 30000,
    roomArea = {
        fromPosition = Position(3196, 1804, 7),
        toPosition = Position(3198, 1806, 7)
    },
    withTime = false,
    time = {
        from = {
            hour = 7,
            minute = 40
        },
        to = {
            hour = 7,
            minute = 45
        }
    }
}

config.roomArea.diffX = config.roomArea.toPosition.x - config.roomArea.fromPosition.x
config.roomArea.diffY = config.roomArea.toPosition.y - config.roomArea.fromPosition.y
config.roomArea.centerPosition = Position(config.roomArea.fromPosition.x + config.roomArea.diffX / 2, config.roomArea.fromPosition.y + config.roomArea.diffY / 2, config.roomArea.fromPosition.z)

local function getTime()
    local time = os.date("*t")
    return {
        hour = time.hour,
        minute = time.min
    }
end

local action = Action()

function action.onUse(player, item, fromPos, target, toPos, isHotkey)
    if config.withTime then
        local time = getTime()
        if time.hour < config.time.from.hour or (time.hour == config.time.from.hour and time.minute < config.time.from.minute) then
            player:sendTextMessage(MESSAGE_STATUS_WARNING, string.format("The door is not available yet.\nIt will be available from %d:%d to %d:%d.", config.time.from.hour, config.time.from.minute, config.time.to.hour, config.time.to.minute))
            return true
        end
        if time.hour > config.time.to.hour or (time.hour == config.time.to.hour and time.minute > config.time.to.minute) then
            player:sendTextMessage(MESSAGE_STATUS_WARNING, string.format("The door is not available yet.\nIt will be available from %d:%d to %d:%d.", config.time.from.hour, config.time.from.minute, config.time.to.hour, config.time.to.minute))
            return true
        end
    end
    local spectators = Game.getSpectators(config.roomArea.centerPosition, false, true, config.roomArea.diffX, config.roomArea.diffX, config.roomArea.diffY, config.roomArea.diffY)
    if #spectators ~= 0 then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "There is already a player in this room.")
        return true
    end
    item:transform(item:getId() == config.openDoorId and config.closedDoorId or config.openDoorId)
    return true
end

action:aid(config.doorActionId)
action:register()

local moveEvent = MoveEvent()

function moveEvent.onStepIn(creature, item, pos, fromPosition)
    if not creature:isPlayer() then
        return true
    end

    local player = creature:getPlayer()
    local tile = Tile(pos)
    if tile:getCreatureCount() > 1 then
        player:teleportTo(fromPosition, false)
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot pass.")
        return true
    end
    return true
end

moveEvent:aid(config.doorActionId)
moveEvent:register()

local moveEvent = MoveEvent()

function moveEvent.onStepOut(creature, item, pos, fromPosition)
    if not creature:isPlayer() then
        return true
    end

    local tile = Tile(pos)
    if tile:getCreatureCount() == 0 then
        item:transform(config.closedDoorId)
    end
    return true
end

moveEvent:aid(config.doorActionId)
moveEvent:register()

You must remember to set the IDs of the door you are using.
If you want the door to work with time just change config.withTime to true
If you want to have two gates, one with time and one not, just duplicate the file and set your other gate with a different actionID...
View attachment 68817View attachment 68818
Dear Sarah,

This script works well very well! However I would like to ask you if you could change time option rather than limits doors to certain times.
Required item to enter and It will kick player from the area after xxxx time they entered and maybe will cooldown so they cannot enter straight after they finished?

But if they leave earlier for some reason they cannot go back inside until cooldown finishes.


You're Great!
 
Last edited:
Hello there Sarah,

Tfs 1.5 nekiro 8.6 downgrade
Creature kill missions from module window.

If it is possible to get that working would be awesome.
Maybe from an npc? You say mission or whatever and it opens the module window specified in the npc for that mission?

So npc 1 gives rat mission module window with info regarding the mission to kill for example 20 rats and then the rewards?

Npc 2 gives spider mission module window woth info regarding the mission to kill for example 40 spiders and the rewards etc
 
how to add a function (!autoloot add, remove, list etc) in autoloot script, base canary ?
local autoLoot = TalkAction("!autoloot")

function autoLoot.onSay(player, words, param)
if not configManager.getBoolean(configKeys.AUTOLOOT) then
return true
end
if configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) and configManager.getBoolean(configKeys.VIP_AUTOLOOT_VIP_ONLY) and not player:isVip() then
player:sendCancelMessage("You need to be VIP to use this command!")
return true
end
if param == "" then
player:sendCancelMessage("You need to specify on/off param.")
return true
end
if param == "on" then
player:setStorageValue(STORAGEVALUE_AUTO_LOOT, 1)
player:sendTextMessage(MESSAGE_LOOK, "You have successfully enabled your automatic looting!")
elseif param == "off" then
player:setStorageValue(STORAGEVALUE_AUTO_LOOT, 0)
player:sendTextMessage(MESSAGE_LOOK, "You have successfully disabled your automatic looting!")
end
return true
end

autoLoot:separator(" ")
autoLoot:groupType("normal")
autoLoot:register()
 
There is one thing I would like to do that is to add into the source a getTotalSkillTries, that, depending on the amount of it, you will gain a % of extra skill. So for example, would be to create a script that would do this:
If you have axe 40 100% to go to 41; this means, for example, that you have 10000 tries. If I want to add 1%, you will get 10100 tries, meaning still 40 axe, but with 95% to go. This means that the higher your skill, the higher the bonus will be.
As far as I looked, there is no such a thing in .cpp, only addSkillTries, required etc, but not the Total amount of it.
Would you do such a thing?
 
โ„‹๐‘’๐“๐“๐‘œ, โ„ ๐’ฝ๐’ถ๐“‹๐‘’ ๐’ถ๐’ธ๐’ธ๐‘’๐“…๐“‰๐‘’๐’น ๐“Ž๐‘œ๐“Š๐“‡ ๐“‡๐‘’๐“†๐“Š๐‘’๐“ˆ๐“‰. โœ…

โ„ ๐’ฝ๐‘œ๐“…๐‘’ ๐“‰๐’ฝ๐’ถ๐“‰ ๐“‰๐’ฝ๐‘’ ๐“‡๐‘’๐“ˆ๐“Š๐“๐“‰ ๐’พ๐“ˆ ๐“ˆ๐’พ๐“‚๐’พ๐“๐’ถ๐“‡ ๐‘’๐“ƒ๐‘œ๐“Š๐‘”๐’ฝ ๐“‰๐‘œ ๐“Œ๐’ฝ๐’ถ๐“‰ ๐“Ž๐‘œ๐“Š ๐’ถ๐“ˆ๐“€๐‘’๐’น ๐’ป๐‘œ๐“‡ ๐’ถ๐“ƒ๐’น ๐“‰๐’ฝ๐’ถ๐“‰ ๐“Ž๐‘œ๐“Š ๐“๐’พ๐“€๐‘’ ๐’พ๐“‰ ๐’ถ ๐“๐‘œ๐“‰.
โ„›๐‘’๐“ˆ๐“Š๐“๐“‰:
data/scripts/darkenergy_buff.lua
Lua:
local config = {
    talkAction = "!darkenergy", --Only for ACCOUNT_TYPE_GOD accounts
    actionId = 56500,
    storageBase = 88000,
    successMessages = "You have absorbed the dark energy.",
    successSay = "Damn i feel so much stronger!",
    successEffect = CONST_ME_MAGIC_GREEN,
    failMessage = "You already absorbed that dark energy!",
    failEffect = CONST_ME_MAGIC_RED,

    rewards = {
    --[[1]] { type=SKILL_SWORD, value=10 },
    --[[2]] { type=SKILL_AXE, value=10 },
    --[[3]] { type=SKILL_CLUB, value=10 },
    --[[4]] { type=SKILL_DISTANCE, value=10 },
    --[[5]] { type=SKILL_SHIELD, value=10 },
    --[[6]] { type=SKILL_FIST, value=10 },
    --[[7]] { type=SKILL_FISHING, value=10 },
    --[[8]] { type=SPECIALSKILL_CRITICALHITCHANCE, value=10 },
    --[[9]] { type=SPECIALSKILL_CRITICALHITAMOUNT, value=10 },
    --[[10]] { type=SPECIALSKILL_LIFELEECHCHANCE, value=10 },
    --[[11]] { type=SPECIALSKILL_LIFELEECHAMOUNT, value=10 },
    --[[12]] { type=SPECIALSKILL_MANALEECHCHANCE, value=10 },
    --[[13]] { type=SPECIALSKILL_MANALEECHAMOUNT, value=10 },
    --[[14]] { type=STAT_MAXHITPOINTS, value=1000 },
    --[[15]] { type=STAT_MAXMANAPOINTS, value=1000 },
    --[[16]] { type=STAT_MAGICPOINTS, value=10 }
    }
}

local conditions = {
    --[[1]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_SWORD},
    --[[2]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_AXE},
    --[[3]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_CLUB},
    --[[4]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_DISTANCE},
    --[[5]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_SHIELD},
    --[[6]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_FIST},
    --[[7]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SKILL_FISHING},
    --[[8]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE},
    --[[9]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    --[[10]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_LIFELEECHCHANCE},
    --[[11]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_LIFELEECHAMOUNT},
    --[[12]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_MANALEECHCHANCE},
    --[[13]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_SPECIALSKILL_MANALEECHAMOUNT},
    --[[14]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_STAT_MAXHITPOINTS},
    --[[15]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_STAT_MAXMANAPOINTS},
    --[[16]] {type=CONDITION_ATTRIBUTES, param=CONDITION_PARAM_STAT_MAGICPOINTS}
}

local function getCustomSkillLevel(player, index)
    local storageBase = config.storageBase + index
    if player.storage[storageBase] == -1 then
        player.storage[storageBase] = 0
        return 0
    end

    return player.storage[storageBase]
end

local function setCustomSkillLevel(player, index, skillId, value)
    player.storage[config.storageBase + index] = value
    local reward = conditions[index]
    if not reward then
        return error("WTF!")
    end
    if not value or value == 0 then
        local condition = player:getCondition(reward.type, CONDITIONID_DEFAULT, config.storageBase + index)
        if not condition then
            return
        end
        return player:removeCondition(condition)
    end
    local condition = Condition(reward.type, CONDITIONID_DEFAULT)
    condition:setParameter(CONDITION_PARAM_TICKS, -1)
    condition:setParameter(CONDITION_PARAM_SUBID, config.storageBase + index)
    condition:setParameter(reward.param, value)
    return player:addCondition(condition)
end

local function addPlayerDarkEnergy(player, fromPosition)
    if player.storage[config.storageBase] ~= 1 then
        player.storage[config.storageBase] = 1
        for index, reward in pairs(config.rewards) do
            setCustomSkillLevel(player, index, reward.type, reward.value)
        end
        player:getPosition():sendMagicEffect(config.successEffect)
        player:sendTextMessage(MESSAGE_INFO_DESCR, config.successMessages)
        player:say(config.successSay, TALKTYPE_MONSTER_SAY)
    else
        player:teleportTo(fromPosition)
        player:sendTextMessage(MESSAGE_INFO_DESCR, config.failMessage)
        player:getPosition():sendMagicEffect(config.failEffect)
    end
end

local moveevent = MoveEvent()

function moveevent.onStepIn(creature, item, pos, fromPosition)
    local player = creature:getPlayer()
    if not player then
        return true
    end
    addPlayerDarkEnergy(player, fromPosition)
    return true
end

moveevent:aid(config.actionId)
moveevent:register()

local creatureEvent = CreatureEvent("DarkEnergyLoad")

function creatureEvent.onLogin(player)
    for index, reward in pairs(config.rewards) do
        local value = getCustomSkillLevel(player, index)
        if value ~= 0 then
            setCustomSkillLevel(player, index, reward.type, value)
        end
    end
    return true
end

creatureEvent:register()

local talkAction = TalkAction(config.talkAction)

function talkAction.onSay(player, words, param, type)
    local split = param:split(",")
    if split[1] == "reset" then
        local target = Player(split[2]) or player
        target.storage[config.storageBase] = -1
        for index, reward in pairs(config.rewards) do
            setCustomSkillLevel(target, index, reward.type, 0)
        end
        return false
    elseif split[1] == "give" then
        addPlayerDarkEnergy(Player(split[2]) or player, player:getPosition())
        return false
    end

    player:popupFYI(string.format("Available parameters:\nreset\ngive\n\nExamples:\n%s give\n%s reset\n\nIf you want to apply the effects to another player,\njust write the player's name as the second parameter.\nExamples:\n%s give,Sarah\n%s reset,Sarah", config.talkAction, config.talkAction, config.talkAction, config.talkAction))
    return false
end

talkAction:accountType(ACCOUNT_TYPE_GOD)
talkAction:separator(" ")
talkAction:register()

๐’ฉ๐‘œ๐“‰๐‘’: ๐“‡๐‘’๐“‚๐‘’๐“‚๐’ท๐‘’๐“‡ ๐“‰๐’ฝ๐’ถ๐“‰ ๐“Ž๐‘œ๐“Š ๐’ธ๐’ถ๐“ƒ ๐“Š๐“ˆ๐‘’ ๐“‰๐’ฝ๐‘’ ๐’ธ๐‘œ๐“ƒ๐’ป๐’พ๐‘”.๐“‰๐’ถ๐“๐“€๐’œ๐’ธ๐“‰๐’พ๐‘œ๐“ƒ ๐“‰๐’ถ๐“๐“€๐’ถ๐’ธ๐“‰๐’พ๐‘œ๐“ƒ ๐“‰๐‘œ ๐’ถ๐’น๐’น ๐‘œ๐“‡ ๐“‡๐‘’๐“‚๐‘œ๐“‹๐‘’ ๐“‰๐’ฝ๐’พ๐“ˆ ๐’ท๐“Š๐’ป๐’ป ๐’ป๐“‡๐‘œ๐“‚ ๐’ถ ๐“…๐“๐’ถ๐“Ž๐‘’๐“‡.
โ„ฐ๐“๐’ถ๐“‚๐“…๐“๐‘’๐“ˆ:
โค !darkenergy give Laniakea
โค !darkenergy reset Laniakea
๐’ช๐“‡ ๐’ป๐‘œ๐“‡ ๐“Ž๐‘œ๐“Š๐“‡๐“ˆ๐‘’๐“๐’ป:

โค !darkenergy give
โค !darkenergy reset
โ—โ„๐“‚๐“…๐‘œ๐“‡๐“‰๐’ถ๐“ƒ๐“‰โ—: ๐’ฏ๐’ฝ๐’พ๐“ˆ ๐“‰๐’ถ๐“๐“€๐’ถ๐’ธ๐“‰๐’พ๐‘œ๐“ƒ ๐’พ๐“ˆ ๐’ป๐‘œ๐“‡ ๐’ข๐’ช๐’Ÿ ๐’ถ๐’ธ๐’ธ๐‘œ๐“Š๐“ƒ๐“‰ ๐‘œ๐“ƒ๐“๐“Ž.


๐ŸŽž ๐’ฑ๐’พ๐“ˆ๐“Š๐’ถ๐“๐’พ๐“๐’ถ๐“‰๐’พ๐‘œ๐“ƒ ๐‘œ๐’ป ๐’ถ ๐“…๐“๐’ถ๐“Ž๐‘’๐“‡ ๐’ถ๐’ธ๐“‰๐’พ๐“‹๐’ถ๐“‰๐’พ๐“ƒ๐‘” ๐‘œ๐“ƒ๐’ฎ๐“‰๐‘’๐“…โ„๐“ƒ ๐ŸŽž


View attachment 68234


It could be used in the Canary Islands base
 
Back
Top