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

Lua [TFS 1.3] Free Scripting Service 📝

Status
Not open for further replies.

Sarah Wesker

ƐƖєgαηт Sуηтαx ❤
Staff member
TFS Developer
Support Team
Joined
Mar 16, 2017
Messages
1,408
Solutions
154
Reaction score
1,958
Location
London
GitHub
MillhioreBT
Twitch
millhiorebt
I am bored, and I have some days in which I will not have much to do, if you need a script you can post here what you want and if it meets the requirements below, I will do it for you

🗒 Requirements:
🔶 TFS engine 1.3+
🔶 That does not include changes in the sources (if you don't know what this is, you can still ask💬)
🔶 I'll only do one script per person so don't spam🔇too much, until a second chance ...
🔶 It depends on what you ask, I will make the decision to accept or not to do it👀
🔶 I know that several people have posted threads similar to this one, but to add more variety, also not all can be available at the same time👌

Don't be afraid to ask 🤗

👍 If I like your post it means that I have taken the task! 👍
 
Last edited:
that system or the like so i can go up or down, any direction
Lua:
local storage = 5845

local config = {
    first_room_pos = {x = 173, y = 223, z = 5}, -- posicao da primeira pos (linha 1 coluna 1)
    distX= 4, -- distancia em X entre cada sala (de uma mesma linha)
    distY= 8, -- distancia em Y entre cada sala (de uma mesma coluna)
    rX= 2, -- numero de colunas
    rY= 2 -- numero de linhas
}

local function isBusyable(position)
    local player = Tile(position):getTopCreature()
    if player then
        if player:isPlayer() then
            return false
        end
    end

    local tile = Tile(position)
    if not tile then
        return false
    end

    local ground = tile:getGround()
    if not ground or ground:hasProperty(CONST_PROP_BLOCKSOLID) then
        return false
    end

    local items = tile:getItems()
    for i = 1, tile:getItemCount() do
        local item = items[i]
        local itemType = item:getType()
        if itemType:getType() ~= ITEM_TYPE_MAGICFIELD and not itemType:isMovable() and item:hasProperty(CONST_PROP_BLOCKSOLID) then
            return false
        end
    end

    return true
end

local function addTrainers(position, arrayPos)
    if not isBusyable(position) then
        for places = 1, #arrayPos do
            local trainer = Tile(arrayPos[places]):getTopCreature()
            if not trainer then
                local monster = Game.createMonster("Trainer", arrayPos[places])
                monster:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            end
        end
    end
end

local function calculatingRoom(uid, position, coluna, linha)
    local player = Player(uid)
    if coluna >= config.rX then
        coluna = 0
        linha = linha < (config.rY -1) and linha + 1 or false
    end

    if linha then
        local room_pos = {x = position.x + (coluna * config.distX), y = position.y + (linha * config.distY), z = position.z}
        if isBusyable(room_pos) then
            player:teleportTo(room_pos)
            player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
            addTrainers(room_pos, {{x = room_pos.x - 1, y = room_pos.y + 1, z = room_pos.z}, {x = room_pos.x + 1 , y = room_pos.y + 1, z = room_pos.z}})
        else
            calculatingRoom(uid, position, coluna + 1, linha)
        end
    else
        player:sendCancelMessage("Couldn't find any position for you right now.")
    end
end

function onStepIn(creature, item, position, fromPosition)
    if not creature:isPlayer() then
        return false
    end

    if creature:getStorageValue(storage) - os.time() > 0 then
        creature:sendTextMessage(MESSAGE_INFO_DESCR, "You gotta wait a few seconds before you can enter trainning room again")
        creature:teleportTo(fromPosition, true)
        return true
    end

    calculatingRoom(creature.uid, config.first_room_pos, 0, 0)

    return true
end
 
Last edited:
Thanks for your review, the problem is solved!
Post automatically merged:


Hi @robert100

OPTION 1 (eventcallbacks):
open the file: data/scripts/eventcallbacks/player/default_onGainExperience.lua

look for this code: local ev = EventCallback
now above this code you are going to paste the following:
Lua:
local expOnlineBonus = {
    [{5, 19}] = 5,
    [{20, 49}] = 10,
    [{50, 99}] = 15,
    [{100, 249}] = 20,
    [{250, 399}] = 25,
    [{400}] = 30
}
table.sort(expOnlineBonus, function(a, b) return a > b end)

look for this code: return exp is most likely at the end of this file.
now above this code you are going to paste the following:
Lua:
    local players = #Game.getPlayers()
    for range, bonus in pairs(expOnlineBonus) do
        if players >= range[1] and (players <= (range[2] or math.huge)) then
            exp = exp * (1 + (bonus / 100))
            break
        end
    end

OPTION 2 (classic events):
open the file: data/events/scripts/player.lua
look for this code: function Player:onGainExperience(source, exp, rawExp) is most likely at the end of this file.
now above this code you are going to paste the following:
Lua:
local expOnlineBonus = {
    [{5, 19}] = 5,
    [{20, 49}] = 10,
    [{50, 99}] = 15,
    [{100, 249}] = 20,
    [{250, 399}] = 25,
    [{400}] = 30
}
table.sort(expOnlineBonus, function(a, b) return a > b end)
look for this code: return exp is most likely at the end of this file.
View attachment 54536
now above this code you are going to paste the following:
Lua:
    local players = #Game.getPlayers()
    for range, bonus in pairs(expOnlineBonus) do
        if players >= range[1] and (players <= (range[2] or math.huge)) then
            exp = exp * (1 + (bonus / 100))
            break
        end
    end

View attachment 54537
Post automatically merged:


Hi @jacqen

data/scripts/yourscriptname.lua
Lua:
local outfitBonus = {
    [137] = { -- Hunter
        addons = 3, -- Require Addon
        [370] = {
            hp = 1,
            mp = 1,
            skill = {CONDITION_PARAM_SKILL_AXE, 1}
        },
        [368] = {
            hp = 2,
            mp = 2,
            skill = {CONDITION_PARAM_SKILL_AXE, 2}
        }
    },
    [138] = { -- Mage
        addons = 3, -- Require Addon
        [368] = {
            hp = 1, -- in %
            mp = 1, -- in %
            skill = {CONDITION_PARAM_SKILL_SWORD, 1}
        }
    }
}

local ev = EventCallback
function ev.onChangeOutfit(creature, outfit)
    local currentOutfit = creature:getOutfit()
    local bonus = outfitBonus[currentOutfit.lookType]
    if bonus and currentOutfit.lookAddons >= bonus.addons then
        local mount = bonus[currentOutfit.lookMount]
        if mount then
            creature:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_COMBAT, 500 + currentOutfit.lookMount, true)
            creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        end
    end
    local bonus = outfitBonus[outfit.lookType]
    if bonus and outfit.lookAddons >= bonus.addons then
        local mount = bonus[outfit.lookMount]
        if mount then
            local condition = Condition(CONDITION_ATTRIBUTES)
            condition:setParameter(CONDITION_PARAM_TICKS, -1)
            condition:setParameter(CONDITION_PARAM_SUBID, 500 + outfit.lookMount)
            if mount.hp then
                condition:setParameter(CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT, 100 + mount.hp)
            end
            if mount.mp then
                condition:setParameter(CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT, 100 + mount.mp)
            end
            if mount.skill then
                condition:setParameter(mount.skill[1], mount.skill[2])
            end
            creature:addCondition(condition)
            creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
        end
    end
    return true
end

Next I will show you a visual example of how it looks when you get the bonus and when you lose it due to lack of requirements
View attachment 54538

In the configuration table you can configure bonuses for each outfit, and each outfit can have its combination with a different mount, in such a way that each mount in conjunction with your outfit can give you different bonuses
somebody can help me with this script? idontknow where to put the code im using otservbr 1.3
 
Hi @Sneaky Diller

data/scripts/yourscriptname.lua
Lua:
local configQuest = {
    actionId = 901,
    players = { -- Positions where players are standing to enter
        Tile(3051, 1828, 8),
        Tile(3051, 1829, 8),
        Tile(3051, 1830, 8),
        Tile(3051, 1831, 8),
        Tile(3051, 1832, 8),
        Tile(3051, 1833, 8),
        Tile(3051, 1834, 8)
    },
    minPlayers = 1, -- Minimum number of players that can enter. in this case 1 or more
    destination = Position(3056, 1831, 8), -- Position where the players will be teleported when entering the room
    requirements = {
        level = 2000, -- level required to enter the room
        storages = {} -- if you need some storage to be able to enter or several storages
    },
    room = {
        centerPos = Position(3068, 1831, 8), -- center of the room
        fromPos = Position(3055, 1812, 8), -- the upper left corner of the room
        toPos = Position(3084, 1844, 8) -- the lower right corner of the room
    },
    boss = {
        name = "Demon", -- boss name
        spawnPos = Position(3068, 1831, 8), -- spawn boss position
        exitIn = 1 -- minutes to get out of the room
    },
    debug = {
        enabled = false, -- for testing with /reload scripts
        exitPos = Position(3051, 1826, 8), -- Position to which players will be sent off after a while
        leverIds = {1945, 1946}, -- lever on / lever off
        admins = false -- detect administrators in the room
    }
}

local function getPlayersInQuest()
    local spectators = Game.getSpectators(configQuest.room.centerPos, false, true, configQuest.radius.x, configQuest.radius.x, configQuest.radius.y, configQuest.radius.y)
    local players = {}
    for _, spectator in pairs(spectators) do
        if spectator:getGroup():getId() == 1 or configQuest.debug.admins then
            players[#players +1] = spectator
        end
    end
    return players
end

local function closeQuest()
    local ground = configQuest.players[1]:getGround()
    for _, p in pairs(getPlayersInQuest()) do
        p:teleportTo(configQuest.debug.exitPos)
    end
    local boss = Monster(ground:getCustomAttribute("bossId"))
    if boss then
        boss:remove()
    end
    ground:removeCustomAttribute("evId")
end

local action = Action()
function action.onUse(player, item, fromPos, target, toPos, isHotkey)
    if not configQuest.radius then
        configQuest.radius = {
            x = math.ceil((configQuest.room.toPos.x - configQuest.room.fromPos.x) / 2),
            y = math.ceil((configQuest.room.toPos.y - configQuest.room.fromPos.y) / 2)
        }
    end
    local leverCanUse = false
    local playerPosition = player:getPosition()
    for _, tile in pairs(configQuest.players) do
        leverCanUse = playerPosition == tile:getPosition()
        if leverCanUse then
            break
        end
    end
    if not leverCanUse then
        return false
    end
    local questPlayers = getPlayersInQuest()
    for _, p in pairs(questPlayers) do
        if configQuest.debug.enabled then
            p:teleportTo(configQuest.debug.exitPos)
        end
    end
    if configQuest.debug.enabled then
        configQuest.debug.exitPos:sendMagicEffect(CONST_ME_TELEPORT)
    end
    local ground = configQuest.players[1]:getGround()
    local boss = Monster(ground:getCustomAttribute("bossId"))
    if boss then
        if configQuest.debug.enabled or #questPlayers == 0 then
            boss:remove()
            stopEvent(ground:getCustomAttribute("evId"))
            ground:removeCustomAttribute("evId")
        else
            player:sendCancelMessage(string.format("You must wait for the boss to be defeated or wait %d seconds.", ground:getCustomAttribute("now") - os.time()))
            return true
        end
    end
    local players = {}
    for _, tile in pairs(configQuest.players) do
        local p = tile:getTopCreature()
        if p and p:isPlayer() then
            if p:getLevel() < configQuest.requirements.level then
                player:sendCancelMessage(string.format("%s must be level %d or higher.", p:getName(), configQuest.requirements.level))
                p:getPosition():sendMagicEffect(CONST_ME_POFF)
                return true
            end
            for _, storage in pairs(configQuest.requirements.storages) do
                if p:getStorageValue(storage) == -1 then
                    player:sendCancelMessage(string.format("%s still cannot face this boss.", p:getName()))
                    p:getPosition():sendMagicEffect(CONST_ME_POFF)
                    return true
                end
            end
            players[#players +1] = p
        end
    end
    if #players < configQuest.minPlayers then
        player:sendCancelMessage(string.format("Sorry, only groups of %d or more players are allowed.", configQuest.minPlayers))
        return true
    end
    for _, p in pairs(players) do
        p:getPosition():sendMagicEffect(CONST_ME_POFF)
        p:teleportTo(configQuest.destination)
    end
    configQuest.destination:sendMagicEffect(CONST_ME_TELEPORT)
    boss = Game.createMonster(configQuest.boss.name, configQuest.boss.spawnPos)
    if boss then
        ground:setCustomAttribute("bossId", boss:getId())
        ground:setCustomAttribute("evId", addEvent(closeQuest, configQuest.boss.exitIn * 60 * 1000))
        ground:setCustomAttribute("now", os.time() + (configQuest.boss.exitIn * 60))
    end
    item:transform(item:getId() == configQuest.debug.leverIds[1] and configQuest.debug.leverIds[2] or configQuest.debug.leverIds[1])
    return true
end

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

View attachment 54622View attachment 54623

Correctly configure the positions of the boss room and the required level, as well as the positions of the tiles where the players have to stand,
Do not forget to configure the maximum time you have to defeat the boss with the variable: exitIn

For the lever to work, you just have to add the actionId in your RME, or add it manually from the game for testing.

Important note: if you want to do tests, activate the debug.enabled variable and set it as true and if you want to do the tests with players with access, such as: Tutor/GM/God then you must also activate the debug.admins variable, remember to leave these two false variables in production

Suggestions:
  • Add a portal so that players can leave the room (in case they give up and want to leave before departure time)
  • The boss should have a good reward or a boss reward system
I need this scripts but respawn more monster
 
Hi sarah, coud you make a script for otx 2 7.72 that makes when u login open all container you have? please i need it so much thanks
 
Hello,
I would like a quest that works similar to tasks of tibia. What I need consists of the player talking to a npc and ask for a task, the npc then ask if the player want to deliver weapons, equipaments or supplies. Depending on player choice, a list will appear (just like tibia task) and the player can get the task to deliver the items.

- If player say weapons, the npc will say "Would you like to deliver swords, axes, clubs, claws, daggers, bows, crossbows, guns or wands?"
-- If player say swords, then a list of items will appear according to level, just like tibia. Example: Player level 1 to 9 will appear 3 knife, 2 wooden sword or 1 combat knife. Player level 10 to 30 will appear 2 sabres or 1 carlin sword.
-- If player say axes, clubs, claws, daggers, bows, crossbows, guns or wands it will follow the example above.

- If player say equipaments, the npc will say "Would you like to deliver helmets, armor, legs, boots, rings, amulets, shields or spellbooks?"
-- If player say helmets, armor, legs, boots, rings, amulets, shields or spellbooks it will follow the example of sword.

- If player say supplies, the npc will say "would you like to deliver backpacks, foods, potions or explosives?"
-- If player say backpacks, foods, potions or explosives it will follow the example of sword.

Players can get only one task at a time, but there is no cooldown between delivering one task and getting another.
Each task will have a different reward, that include exp, money, items, outfits, addons and mounts.

I know it seems a lot, but it does not have much differences from tibia task.
 
Read The Middle GIF
 
Hello, it is possible to make task NPC with low/medium/high stage mobs. When u kill mobs and report to npc you will teleport to boss room?
 
Hi, i don't have a lot of knowledge about scripts and with that I don't know if to make this script it is necessary to change the sources.

Attack level: for each attack level that a player has, he defends 1% more damage to the player in relation to his defense level. (only functional on other players).

Defense level: for every defense level a player has, he defends 1% more damage to the player in relation to his attack level. (only functional on other players).

Attack and defense levels would be assigned to the items the player has, even if I need to make 1 script for each item with the attack/defense level.

For example, if a player X is using a set that has 100 attack level, attacking a player Y that has 50 defense level, the damage he will cause will have an additional 50%, if the hit he were to hit was 100, with the set it would be 150.

A third attribute would be similar to the level of attack, the Killing Level. For each Killing Level the equipped set has, it beats 1% more in just monsters. I believe it would be a very difficult script to do, as I’ve never seen anything like it in Tibia, but can I be wrong? I already thank you in advance for the answer, even if it is not and I apologize for the English xd.
 
Hello @Sarah Wesker

Maybe You will help me :)



I wonder is there a chance, to do a new skill like a immunity to e.g energy.
Also every energy attack thick will rise Your skill.
Like a shielding for e.g Energy

How should it work:
Energy fiels takes from you 20 HP points. (1 lvl skill)

You got skill "Resist Energy" on 1 lvl = enegry attack takes form You 20 HP
When you get 10 skill lvl - energy field will take just 18 HP (10 lvl = 10%)
etc..

I have done so far, just a new skill and get it into client - but I dont have it "linked/writed" to train that resist and decreasing energy attacks.
What to look for in the code, what to change to make it work?

If is it in C++ of server just tell me :) or it could be done just with LUA? Maybe it require both... ?

Regards :)
 
Status
Not open for further replies.
Back
Top