• 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 Xikini's Free Scripting Service TFS 1.3

Status
Not open for further replies.

Xikini

I whore myself out for likes
Senator
Premium User
Joined
Nov 17, 2010
Messages
6,787
Solutions
581
Reaction score
5,354
Please request
actions / creatureevents / globalevents / npcs / movements / talkactions

Do not request
spells / weapons / monsters / source editing / database queries

My goal of this thread is to learn TFS 1.3 scripting.

------------------------------------
Support

If you have an issue with one of my scripts, I will attempt to help you, but not in this thread.
Make a thread in the support board.
Ensure to follow all rules of the support board.
Without all neccesary information it's impossible to help you.

------------------------------------
I will only be scripting for TFS 1.3

Not TFS 1.1 / 1.2
Not OTServBR / OTX
and certainly not TFS 0.4

When requesting a script, don't ask for "this script I saw on super popular OT".

I don't care where the idea came from.
I don't want to see a video of the script in action.

I'm here to learn how to script better.
Just describe what the script is supposed to do, and I'll try to make it.

Any script that I make in response to a request from this thread will be shared publically, here, in this thread.

I'm not going to make anything in private, so post your request in this thread only.
Please, for the love of god, don't pm me asking to make a script.
I will actually add you to my ignore list if you do that.
--------------

Anyways!

Thanks for coming by and checking the thread out.
If you think there is a better way to script something, feel free to let me know.
I'm here to learn.

Cheers,

Xikini

----

Completed Scripts

DPS Dummy -> using RevScripts
!playerinfo character name -> using RevScripts
Positional Text talkaction -> using RevScripts
||--> Updated version that can use text & effects
Vocational Item Bonus's -> using RevScripts
||--> Updated version with easier config.
Simple damge buff potion -> using Revscripts
Kill monster in specific area, remove stone for x seconds -> using RevScripts
Training Room Teleporter -> using RevScripts
Lever that removes/adds/transforms objects or ground tiles -> using RevScripts
Loot from monster goes into single backpack, no matter how much loot there is.
Extra loot in monsters, based on chance and tier list -> using RevScripts
||--> Updated version that allows specific monsters to have their own loot table
Random Item chest that disappears after use, and respawns after x time -> using RevScripts
Multiple players required to open passageway.
Monster Arena Lever (x amount of waves, complete all waves, teleport appears) -> using RevScripts
Daily Boosted Creatures (experience & loot chance of items)
||--> Updated main file of boosted creatures, so that it triggers at midnight, instead of when the server starts up.
Reward Chest - Extremely simple. -> using Revscripts
Simple Npc that can sell an item, via text.

----

Extremely useful libs that I use quite often.

data/lib/core/player.lua
Give player items by table

data/lib/core/container.lua
getContainerFreeSlots

----

To-Do List

Shalaby - Player death counter. (Movement and talkaction)
Shalaby - Npc kill monster task, with item reward.
Shalaby - Boss respawn after x time.

-------

Last spot I've read messages
 
Last edited:
system of war between monsters
1598488912968.pnglions vs usurper1598488890771.png
all monsters in certain areas would attack each other until death
 
i seen you wrote (infinity rooms) i don't mean this, look i have like 200 rooms done already i need to add like startpos northwest, endpost southeast and player go to one of empty rooms in between the 2 pos and if he leave room is emptied or storage remove so it dont read as he is there, reason i no need infinity rooms cuz maybe i need add stamina ontile or action unique or one thing so need my mapped rooms start from northwest pos to southeast pos
Post a screenshot of your map, please.
Lua:
function onStepIn(cid, item, position, fromPosition)
for i = 17000, 18015 do
local pos = getThingPos(i)
if not isPlayer(getTopCreature(pos).uid) then
I really trying to wrap my head around how that even functions..
It's literally not getting any position.. since you need x, y and z..

Can @anyone explain how that would scan for players?

-- edit
Answer here.

  • After rolling the tier it will roll items from the tier list thet got choosen ( items also got different % to chance to drop, and also only 1 item can be choosen )
I'm trying to understand this part still.

So as an example.. (config would let you adjust percentages.)

50% chance of no items.
If items..
randomly choose between tiers. (50% normal, 35% enchanted, 10% epic, 5% legendary)..

each tier has it's own item list, with chance of drop.. {{1111, 10}, {2222, 20}} -- 10% and 20%
If the item chance allows it to be dropped.. then
choose a random 1 item from that list, and add it to the loot?

Code:
if chance of items == success then
-> choose tier
-> loop through all items in that tier, checking dropChance, and adding them to a temporary table
-> choose 1 item randomly from the temporary table to add to loot.

If that isn't correct, please explain it more/differently. lol
 
Last edited:
Code:
Code:
if chance of items == success then
-> choose tier
-> loop through all items in that tier, checking dropChance, and adding them to a temporary table
-> choose 1 item randomly from the temporary table to add to loot.
Exactly like that
 
Can u make a script if there's 3 players step in 3 different SQM positons they open a gate like stone and the gate wait for 4 second then it goes gone. 2nd a script to how many dies u died like if you step in portal it teleport u and it send a text message with monster say gives u how much u died like you have died "number of times plus using this command !hmdies".
3rd script a npc gives u an items if you killed 2 different monsters, 1 monster for 200 times and the other monster for 20 time.
4th script a monster spawn in some area every 7 hours.
 
Last edited:
This might be a simple one but I've always wondered how to do it.

A spell that creates a stack on a monster. That stack can then be consumed for an effect.

Example:

Spell - Envenom

Launches a projectile at an enemy, dealing Earth damage. It also applies a debuff of Envenom. Each stack of Envenom lasts 10 seconds and the duration is refreshed if a new stack of Envenom is applied. The amount of stacks is displayed on the monster every 2 seconds with green letters saying "Envenom: X". Each person who casts this spell only sees their stack amount and cannot interact with other players' stacks.

Spell - Expunge

Consumes all stacks of Envenom on all targets, dealing damage based on the total amount of Envenom consumed.

Damage: ((Level * 2) + (Magic Level * 3))(Envenom Stacks)
 
This might be a simple one but I've always wondered how to do it.

A spell that creates a stack on a monster. That stack can then be consumed for an effect.

Example:

Spell - Envenom

Launches a projectile at an enemy, dealing Earth damage. It also applies a debuff of Envenom. Each stack of Envenom lasts 10 seconds and the duration is refreshed if a new stack of Envenom is applied. The amount of stacks is displayed on the monster every 2 seconds with green letters saying "Envenom: X". Each person who casts this spell only sees their stack amount and cannot interact with other players' stacks.

Spell - Expunge

Consumes all stacks of Envenom on all targets, dealing damage based on the total amount of Envenom consumed.

Damage: ((Level * 2) + (Magic Level * 3))(Envenom Stacks)
I don't do spells in this thread, but I'll explain how you'd want to do this.

So basically, you'll want to create a global_table in order to hold the information.
add whatever new/fake stuff you want to the table.
data/lib/core/custom_tables.lua -- as an example file_name
Lua:
global_creature_stacks = {
    ["envenom"] = {},
    --["bleed"] = {},
    --["holy"] = {}
}
Whenever you cast your spell, you'd want to update the table with information.
Use the creatureid as the main index
Lua:
local creature_id = creature:getId()
if not global_creature_stacks["envenom"][creature_id] then
    global_creature_stacks["envenom"][creature_id] = {}
end
and put the playerid as the sub index.
Lua:
local player_id = player:getId()
if not global_creature_stacks["envenom"][creature_id][player_id] then
    global_creature_stacks["envenom"][creature_id][player_id] = 0
end
so in theory, your table will look like this after you add the information.
Lua:
global_creature_stacks = {
    ["envenom"] = {
        [6565467656] = { -- creatureid
            [9843798734] = 0 -- playerid = stacks
        }
    },
    --["bleed"] = {},
    --["holy"] = {}
}
Then you can simply modify / get the stack information whenever you want.
Lua:
local stacks_to_add = 5
local stackIndex = global_creature_stacks["envenom"][creature_id][player_id]
stackIndex = stackIndex + stacks_to_add

local damage = stackIndex * weaponDamage -- or whatever. lol
stackIndex = 0
Then, whenever the creature dies / no longer exists, just remove the table information.
Lua:
table.remove(global_creature_stacks["envenom"][creature_id])
 
I don't do spells in this thread, but I'll explain how you'd want to do this.

So basically, you'll want to create a global_table in order to hold the information.
add whatever new/fake stuff you want to the table.
data/lib/core/custom_tables.lua -- as an example file_name
Lua:
global_creature_stacks = {
    ["envenom"] = {},
    --["bleed"] = {},
    --["holy"] = {}
}
Whenever you cast your spell, you'd want to update the table with information.
Use the creatureid as the main index
Lua:
local creature_id = creature:getId()
if not global_creature_stacks["envenom"][creature_id] then
    global_creature_stacks["envenom"][creature_id] = {}
end
and put the playerid as the sub index.
Lua:
local player_id = player:getId()
if not global_creature_stacks["envenom"][creature_id][player_id] then
    global_creature_stacks["envenom"][creature_id][player_id] = 0
end
so in theory, your table will look like this after you add the information.
Lua:
global_creature_stacks = {
    ["envenom"] = {
        [6565467656] = { -- creatureid
            [9843798734] = 0 -- playerid = stacks
        }
    },
    --["bleed"] = {},
    --["holy"] = {}
}
Then you can simply modify / get the stack information whenever you want.
Lua:
local stacks_to_add = 5
local stackIndex = global_creature_stacks["envenom"][creature_id][player_id]
stackIndex = stackIndex + stacks_to_add

local damage = stackIndex * weaponDamage -- or whatever. lol
stackIndex = 0
Then, whenever the creature dies / no longer exists, just remove the table information.
Lua:
table.remove(global_creature_stacks["envenom"][creature_id])

Thanks a lot! I'll try to crack it myself and reference this post.
 
could you make two scripts for tfs 1.3 please. ?

if lever is used remove a wall. If it's used again add wall, but checking if a corpse , person or item is in there ( on the sqm where the wall will be created or added. if that is the case push the player, item, corpse, magic field 1 sqm back.

the second script works very similar but consists on;

if lever is used remove x roof or floor id. if a player or an item, corpse monster.. is standing on the sqm that will be removed when the lever is being used, they should fall down. if there is an magic field when the on the floor when the lever it used it should disappear. if the lever is used again add the roof / or floor id again


thanks in advance
 
What about a quest chest that gives random loot table (item id, ammount, dropchance) and disapears after using it. Then it will respawn again after x time.
 
Can you make a teleport scroll, but saying the city where u wanna go?

like !town thias, carlin, etc?
Post automatically merged:

Alright, so I finally got around to it. xD

There are 32 different attributes you can apply to an item.

When registering an item you need to put the itemid in 3 spots.
Config Table, onEquip and onDeEquip.

I should note here that if the item is already registered in regular movements.xml, this code won't work on that item.

data\scripts\movements\ vocations_item_bonus.lua
Lua:
local config  = {
    [1111] = { -- itemid
        slot = "ammo", -- ("head", "necklace", "backpack", "armor", "shield", "weapon", "legs", "feet", "ring", "ammo")
        {
            [{1, 5}] = { -- vocation 1 and vocation 5
                ["statMain"] = {
                    -- flat_bonus_stats
                    {"life increase", 50},
                    {"mana increase", -200}, -- negative numbers will reduce a players stats
                    {"magic", 5},
                    {"melee", 15}, -- sword/axe/club
                    {"fist", 5},
                    {"club", 5}, -- if both melee and club exist on a single item, club will be the one that will trigger.
                    {"sword", 5}, -- example: (melee 20) -> (sword 5) ----> Result: (club 20) (sword 5) (axe 20)
                    {"axe", 5},
                    {"distance", 5},
                    {"shield", 5},
                    {"fishing", 5},
                    {"critical hit chance", 5},
                    {"critical hit damage", 5},
                    {"life leech chance", 5},
                    {"life leech amount", 5},
                    {"mana leech chance", 5},
                    {"mana leech amount", 5},
                    -- percent_bonus_stats
                    {"life increase percent", 200}, -- If using flat_bonus_stats and percent_bonus_stats on the same item, the percent_bonus_stats is the only one that will trigger.
                    {"mana increase percent", 200}, -- same idea as melee/club, but for flat/percent
                    {"magic percent", 3000},
                    {"melee percent", 200},
                    {"fist percent", 200}, -- 200 = 200%  -> 15 fisting would turn into 30
                    {"club percent", 200},
                    {"sword percent", 200},
                    {"axe percent", 200},
                    {"distance percent", 200},
                    {"shield percent", 200},
                    {"fishing percent", 200}
                },
                ["statSpeed"] = {
                    {"speed", 1000} -- when testing, it only gave half of this value. Might just be my client though
                },
                ["statRegen"] = {
                    {"life regen", 5, 5000}, --{type, amount, ticks_in_milliseconds}
                    {"mana regen", 5, 5000}  -- (can't go lower then 1 second)
                },
                ["statSoulRegen"] = {
                    {"soul regen", 5, 5000}
                },
            },
            [{2, 6}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            },
            [{3, 7}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            },
            [{4, 8}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            }
        }
    },
    [2222] = {
        slot = "armor",
        {
            [{1, 5}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            },
            [{2, 6}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            },
            [{3, 7}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            },
            [{4, 8}] = {
                ["statMain"] = {},
                ["statSpeed"] = {},
                ["statRegen"] = {},
                ["statSoulRegen"] = {}
            }
        }
    },
    [3333] = {
        slot = "ammo",
        {
            [{1, 5}] = {["statMain"] = {{"magic", 5}} },
            [{2, 6}] = {["statSpeed"] = {{"speed", 500}} },
            [{3, 7}] = {["statRegen"] = {{"life regen", 5, 5000}} },
            [{4, 8}] = {["statSoulRegen"] = {{"soul regen", 5, 5000}} }
        }
    }
}

local function convertSlotTextToNumber(slot)
    local text = nil
    if slot == "head" then
        slot = 1
    elseif slot == "necklace" then
        slot = 2
    elseif slot == "backpack" then
        slot = 3
    elseif slot == "armor" then
        slot = 4
    elseif slot == "shield" then
        slot = 5
    elseif slot == "weapon" then
        slot = 6
    elseif slot == "legs" then
        slot = 7
    elseif slot == "feet" then
        slot = 8
    elseif slot == "ring" then
        slot = 9
    elseif slot == "ammo" then
        slot = 10
    end
    return slot
end

local condition_ids = {
    CONDITIONID_HEAD,
    CONDITIONID_NECKLACE,
    CONDITIONID_BACKPACK,
    CONDITIONID_ARMOR,
    CONDITIONID_RIGHT,
    CONDITIONID_LEFT,
    CONDITIONID_LEGS,
    CONDITIONID_FEET,
    CONDITIONID_RING,
    CONDITIONID_AMMO
}

local conditions = {
    ["life increase"] = {CONDITION_PARAM_STAT_MAXHITPOINTS},
    ["mana increase"] = {CONDITION_PARAM_STAT_MAXMANAPOINTS},
    ["speed"] = {CONDITION_PARAM_SPEED},
    ["magic"] = {CONDITION_PARAM_STAT_MAGICPOINTS},
    ["melee"] = {CONDITION_PARAM_SKILL_MELEE},
    ["fist"] = {CONDITION_PARAM_SKILL_FIST},
    ["club"] = {CONDITION_PARAM_SKILL_CLUB},
    ["sword"] = {CONDITION_PARAM_SKILL_SWORD},
    ["axe"] = {CONDITION_PARAM_SKILL_AXE},
    ["distance"] = {CONDITION_PARAM_SKILL_DISTANCE},
    ["shield"] = {CONDITION_PARAM_SKILL_SHIELD},
    ["fishing"] = {CONDITION_PARAM_SKILL_FISHING},
    ["critical hit chance"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE},
    ["critical hit damage"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    ["life leech chance"] = {CONDITION_PARAM_SPECIALSKILL_LIFELEECHCHANCE},
    ["life leech amount"] = {CONDITION_PARAM_SPECIALSKILL_LIFELEECHAMOUNT},
    ["mana leech chance"] = {CONDITION_PARAM_SPECIALSKILL_MANALEECHCHANCE},
    ["mana leech amount"] = {CONDITION_PARAM_SPECIALSKILL_MANALEECHAMOUNT},
    ["life increase percent"] = {CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT},
    ["mana increase percent"] = {CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT},
    ["magic percent"] = {CONDITION_PARAM_STAT_MAGICPOINTSPERCENT},
    ["melee percent"] = {CONDITION_PARAM_SKILL_MELEEPERCENT},
    ["fist percent"] = {CONDITION_PARAM_SKILL_FISTPERCENT},
    ["club percent"] = {CONDITION_PARAM_SKILL_CLUBPERCENT},
    ["sword percent"] = {CONDITION_PARAM_SKILL_SWORDPERCENT},
    ["axe percent"] = {CONDITION_PARAM_SKILL_AXEPERCENT},
    ["distance percent"] = {CONDITION_PARAM_SKILL_DISTANCEPERCENT},
    ["shield percent"] = {CONDITION_PARAM_SKILL_SHIELDPERCENT},
    ["fishing percent"] = {CONDITION_PARAM_SKILL_FISHINGPERCENT},
    ["life regen"] = {CONDITION_PARAM_HEALTHGAIN, CONDITION_PARAM_HEALTHTICKS},
    ["mana regen"] = {CONDITION_PARAM_MANAGAIN, CONDITION_PARAM_MANATICKS},
    ["soul regen"] = {CONDITION_PARAM_SOULGAIN, CONDITION_PARAM_SOULTICKS}
}

local main_attributes = {CONDITION_ATTRIBUTES, CONDITION_HASTE, CONDITION_REGENERATION, CONDITION_SOUL}
local main_stats = {"statMain", "statSpeed", "statRegen", "statSoulRegen"}

local function giveItemBonus(playerid)
    local player = Player(playerid)
    local player_equipment = {}
 
    -- find all player equipment
    for i = 1, 10 do
        local slotItem = player:getSlotItem(i)
        if slotItem then
            slotItem = slotItem.itemid
            if not config[slotItem] or convertSlotTextToNumber(config[slotItem].slot) ~= i then
                slotItem = 0
            end
        else
            slotItem = 0
        end
        table.insert(player_equipment, slotItem)
    end
 
    -- remove all buffs from armor
    for i = 1, 10 do
        for n = 1, 4 do
            if player:getCondition(main_attributes[n], condition_ids[i]) then
                player:removeCondition(main_attributes[n], condition_ids[i])
            end
        end
    end
 
    -- add all buffs from equipment
    local vocation = player:getVocation():getId()
    for i = 1, 10 do
        local itemID = player_equipment[i]
        if itemID ~= 0 then
            for voc, _ in pairs(config[itemID][1]) do
                if isInArray(voc, vocation) then
                    for n = 1, 4 do
                        if config[itemID][1][voc][main_stats[n]] then
                            local condition = Condition(main_attributes[n], condition_ids[i])
                            condition:setParameter(CONDITION_PARAM_TICKS, -1)
                            local itemBonusIndex = config[itemID][1][voc][main_stats[n]]
                            for h = 1, #itemBonusIndex do
                                for p = 1, #conditions[itemBonusIndex[h][1]] do
                                    condition:setParameter(conditions[itemBonusIndex[h][1]][p], itemBonusIndex[h][2])
                                end
                            end
                            player:addCondition(condition)
                        end
                    end
                end
            end
        end
    end
    return true
end


-- HEAD -------------------------------------------------------------------------------
local onEquip_Head = MoveEvent()

function onEquip_Head.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Head:slot("head")
onEquip_Head:id(1111, 2222, 3333)
onEquip_Head:register()


local onDeEquip_Head = MoveEvent()

function onDeEquip_Head.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Head:slot("head")
onDeEquip_Head:id(1111, 2222, 3333)
onDeEquip_Head:register()



-- NECKLACE -------------------------------------------------------------------------------
local onEquip_Necklace = MoveEvent()

function onEquip_Necklace.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Necklace:slot("necklace")
onEquip_Necklace:id(1111, 2222, 3333)
onEquip_Necklace:register()


local onDeEquip_Necklace = MoveEvent()

function onDeEquip_Necklace.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Necklace:slot("necklace")
onDeEquip_Necklace:id(1111, 2222, 3333)
onDeEquip_Necklace:register()


-- BACKPACK -------------------------------------------------------------------------------
local onEquip_Backpack = MoveEvent()

function onEquip_Backpack.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Backpack:slot("backpack")
onEquip_Backpack:id(1111, 2222, 3333)
onEquip_Backpack:register()


local onDeEquip_Backpack = MoveEvent()

function onDeEquip_Backpack.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Backpack:slot("backpack")
onDeEquip_Backpack:id(1111, 2222, 3333)
onDeEquip_Backpack:register()


-- ARMOR -------------------------------------------------------------------------------
local onEquip_Armor = MoveEvent()

function onEquip_Armor.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Armor:slot("armor")
onEquip_Armor:id(1111, 2222, 3333)
onEquip_Armor:register()


local onDeEquip_Armor = MoveEvent()

function onDeEquip_Armor.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Armor:slot("armor")
onDeEquip_Armor:id(1111, 2222, 3333)
onDeEquip_Armor:register()


-- WEAPONS AND SHIELDS (hands) --------------------------------------------------------
local onEquip_Hands = MoveEvent()

function onEquip_Hands.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Hands:slot("hand")
onEquip_Hands:id(1111, 2222, 3333)
onEquip_Hands:register()

local onDeEquip_Hands = MoveEvent()

function onDeEquip_Hands.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Hands:slot("hand")
onDeEquip_Hands:id(1111, 2222, 3333)
onDeEquip_Hands:register()

-- LEGS -------------------------------------------------------------------------------
local onEquip_Legs = MoveEvent()

function onEquip_Legs.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Legs:slot("legs")
onEquip_Legs:id(1111, 2222, 3333)
onEquip_Legs:register()


local onDeEquip_Legs = MoveEvent()

function onDeEquip_Legs.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Legs:slot("legs")
onDeEquip_Legs:id(1111, 2222, 3333)
onDeEquip_Legs:register()


-- FEET -------------------------------------------------------------------------------
local onEquip_Feet = MoveEvent()

function onEquip_Feet.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Feet:slot("feet")
onEquip_Feet:id(1111, 2222, 3333)
onEquip_Feet:register()


local onDeEquip_Feet = MoveEvent()

function onDeEquip_Feet.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Feet:slot("feet")
onDeEquip_Feet:id(1111, 2222, 3333)
onDeEquip_Feet:register()


-- RING -------------------------------------------------------------------------------
local onEquip_Ring = MoveEvent()

function onEquip_Ring.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Ring:slot("ring")
onEquip_Ring:id(1111, 2222, 3333)
onEquip_Ring:register()


local onDeEquip_Ring = MoveEvent()

function onDeEquip_Ring.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Ring:slot("ring")
onDeEquip_Ring:id(1111, 2222, 3333)
onDeEquip_Ring:register()


-- AMMO -------------------------------------------------------------------------------
local onEquip_Ammo = MoveEvent()

function onEquip_Ammo.onEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onEquip_Ammo:slot("ammo")
onEquip_Ammo:id(1111, 2222, 3333)
onEquip_Ammo:register()


local onDeEquip_Ammo = MoveEvent()

function onDeEquip_Ammo.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        addEvent(giveItemBonus, 0, player:getId())
    end
    return true
end

onDeEquip_Ammo:slot("ammo")
onDeEquip_Ammo:id(1111, 2222, 3333)
onDeEquip_Ammo:register()


-- LOGIN ------------------------------------------------------------------------------
local loginEvent = CreatureEvent("newLoginEvent")
loginEvent:type("login")

function loginEvent.onLogin(player)
    addEvent(giveItemBonus, 0, player:getId())
    return true
end

loginEvent:register()

i got errors
Post automatically merged:

Can you make a teleport scroll, but saying the city where u wanna go?

like !town thias, carlin, etc?
Post automatically merged:



i got errors
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
...vbr-global-develop\data\scripts\movements\bonusitems.lua:157: attempt to get length of a nil value
stack traceback:
[C]: in function '__len'
...vbr-global-develop\data\scripts\movements\bonusitems.lua:157: in function <...vbr-global-develop\data\scripts\movements\bonusitems.lua:117>
 
Last edited:
Can you make a teleport scroll, but saying the city where u wanna go?

like !town thias, carlin, etc?
Post automatically merged:



i got errors
Post automatically merged:


Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
...vbr-global-develop\data\scripts\movements\bonusitems.lua:157: attempt to get length of a nil value
stack traceback:
[C]: in function '__len'
...vbr-global-develop\data\scripts\movements\bonusitems.lua:157: in function <...vbr-global-develop\data\scripts\movements\bonusitems.lua:117>

I can only guarantee that it works 100% in my test environment.
You'd have to make a support thread for it.., so myself and others can help you there.

line 117 is elseif slot == "armor" then
line 157 is ["axe"] = {CONDITION_PARAM_SKILL_AXE},

As you can see above, once you've made modifications to the table, it's impossible to troubleshoot without asking to see what you've changed, and I don't want to spam this thread with troubleshooting posts.

Feel free to @Xikini in your thread.
 
What about a quest chest that gives random loot table (item id, ammount, dropchance) and disapears after using it. Then it will respawn again after x time.

What about another edition of this with features as like:
Random loot table
Adds storage to player
Storage is removed after x time


Example how it could be used:
This would make it possible to spawn chest upon a monsters death and everyone could loot and get their participant reward.
Lets say this boss spawns every sunday and therefor the storage would be removed after x amount of time, possibly by the next server save.
But since the "boss" only respawns every sunday therefor none would be able to abuse it since chest ain't there anymore.

(I'm not requesting the chest upon killing monster)
 
@Abdelmaksod
Training Room script is finished. :)

Below gif shows the script in action.
If a character x-logs or disconnects from the game, the script will count that room as empty.

When the server starts, the script starts checking every tile inbetween north_west and south_east from config table.
It finds every playerTile, and calculates the position to spawn the training creatures using the teleporter item.
This process takes awhile, simply due to how many tiles need to be checked..
But it doesn't really matter as it's unlikely to affect players, and works in the background.

bandicam-2020-08-28-05-56-42-258.gif

Untitled.png

data\scripts\ onStepIn_TrainingRoomTeleporter.lua
Lua:
local positionData = {}

local config = {
    actionids = {45001, 45002, 45003}, -- {entryTile, playerTile, exitTile}
    trainingPartner = "rat",
    exitPosition = Position(100, 100, 7), -- use Position(x, y, z) OR false -- false will teleport player to their home town.
    boundaries = {{x = 90, y = 90}, {x = 110, y = 110}, z = 7}, -- {{north_west_corner}, {south_east_corner}, floor_level}
    portalID = 1387
}

local moveEvent = MoveEvent()
moveEvent:type("stepin")

function moveEvent.onStepIn(player, item, position, fromPosition)
    if not player:isPlayer() then
        return true
    end
  
    local actionID = item:getActionId()
  
    -- if teleporting out of trainers
    if actionID == config.actionids[3] then
        -- teleport player out
        local exit_position = config.exitPosition
        if exit_position == false then
            exit_position = player:getTown():getTemplePosition()
        end
        player:teleportTo(exit_position)
      
        -- remove creatures
        local spec = Game.getSpectators(fromPosition, false, false, 1, 1, 1, 1)
        for i = 1, #spec do
            spec[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            spec[i]:remove()
        end
        return true
      
    -- if teleporting into trainers
    elseif actionID == config.actionids[1] then
        for i = 1, #positionData do
            local spec, players = Game.getSpectators(positionData[i][1], false, false, 1, 1, 1, 1), 0
          
            -- if creatures exist in training position, check if any are a player
            if #spec > 0 then
                for i = 1, #spec do
                    if spec[i]:isPlayer() then
                        if spec[i]:getIp() ~= 0 then -- if player is still online (not x-logged or disconnected)
                            players = 1
                        end
                        break
                    end
                end
            end
          
            -- if no online player found, and creatures exist, remove all creatures in training room.
            if players == 0 and #spec > 0 then
                for i = 1, #spec do
                    spec[i]:remove()
                end
                spec = {} -- clear spectator table
            end
          
            -- if empty, teleport in and create training creatures
            if #spec < 1 then
                player:teleportTo(positionData[i][1])
                for n = 1, 2 do
                    Game.createMonster(config.trainingPartner, positionData[i][n + 1])
                end
                return true
            end
        end
    end
  
    -- no locations available to teleport to
    local text = "Sorry, no training tiles are available. Try again later."
    if not positionData[1] then
        text = "Training tiles are still being populated by the server. Please wait 10 seconds."
    end
    player:sendTextMessage(MESSAGE_STATUS_WARNING, text)
    player:teleportTo(fromPosition, true)
    return true
end

moveEvent:aid(config.actionids[1], config.actionids[3])
moveEvent:register()


local direction = {
    {-1, 0, -1, 1, -1, -1}, -- west
    {1, 0, 1, 1, 1, -1}, -- east
    {0, -1, 1, -1, -1, -1}, -- north
    {0, 1, 1, 1, -1, 1} -- south
}

local function collect_positionData(current_x, current_y)
    local position = Position(current_x, current_y, config.boundaries.z)
    local tile = Tile(position)
  
    -- if tile exists
    if tile then
        -- if tile has actionid
        local item = Item(tile:getGround().uid)
        if item:getActionId() == config.actionids[2] then
            -- find positions to spawn training creatures
            for i = 1, 4 do -- 4 possible directions
                -- make sure tile exists
                local check_tile = Tile(Position(current_x + direction[i][1], current_y + direction[i][2], config.boundaries.z))
                if check_tile then
                    -- if teleport exists on tile
                    local teleport_count = check_tile:getItemCountById(config.portalID)
                    if teleport_count > 0 then
                        -- we know which direction to spawn training creatures
                        local pos_1 = Position(current_x + direction[i][3], current_y + direction[i][4], config.boundaries.z)
                        local pos_2 = Position(current_x + direction[i][5], current_y + direction[i][6], config.boundaries.z)
                         -- add positions into table
                        positionData[#positionData + 1] = {position, pos_1, pos_2}
                        break
                    end
                end
            end
        end
    end
  
    -- calculate next tile
    if current_x == config.boundaries[2].x then
        current_x = config.boundaries[1].x
        current_y = current_y + 1
    else
        current_x = current_x + 1
    end
  
    -- check if next tile is within check area
    if config.boundaries[2].y + 1 ~= current_y then
        addEvent(collect_positionData, 1, current_x, current_y)
    end
end

local globalEvent = GlobalEvent()
globalEvent:type("startup")

function globalEvent.onStartup()
    addEvent(collect_positionData, 1000, config.boundaries[1].x, config.boundaries[1].y)
    return true
end

globalEvent:register()



local loginEvent = CreatureEvent("onLogin_trainingRoomTeleporter")
loginEvent:type("login")

function loginEvent.onLogin(player)
    local north_west = Position(config.boundaries[1].x, config.boundaries[1].y, config.boundaries.z)
    local south_east = Position(config.boundaries[2].x, config.boundaries[2].y, config.boundaries.z)
    if player:getPosition():isInRange(north_west, south_east) then
        local exit_position = config.exitPosition
        if exit_position == false then
            exit_position = player:getTown():getTemplePosition()
        end
        player:teleportTo(exit_position)
    end
    return true
end

loginEvent:register()
 
Last edited:
@Abdelmaksod
Training Room script is finished. :)

Below gif shows the script in action.
If a character x-logs or disconnects from the game, the script will count that room as empty.

When the server starts, the script starts checking every tile inbetween north_west and south_east from config table.
It finds every playerTile, and calculates the position to spawn the training creatures using the teleporter item.
This process takes awhile, simply due to how many tiles need to be checked..
But it doesn't really matter as it's unlikely to affect players, and works in the background.

View attachment 49336

View attachment 49339

data\scripts\ onStepIn_TrainingRoomTeleporter.lua
Lua:
local positionData = {}

local config = {
    actionids = {45001, 45002, 45003}, -- {entryTile, playerTile, exitTile}
    trainingPartner = "rat",
    exitPosition = Position(100, 100, 7), -- use Position(x, y, z) OR false -- false will teleport player to their home town.
    boundaries = {{x = 90, y = 90}, {x = 110, y = 110}, z = 7}, -- {{north_west_corner}, {south_east_corner}, floor_level}
    portalID = 1387
}

local moveEvent = MoveEvent()
moveEvent:type("stepin")

function moveEvent.onStepIn(player, item, position, fromPosition)
    if not player:isPlayer() then
        return true
    end
  
    local actionID = item:getActionId()
  
    -- if teleporting out of trainers
    if actionID == config.actionids[3] then
        -- teleport player out
        local exit_position = config.exitPosition
        if exit_position == false then
            exit_position = player:getTown():getTemplePosition()
        end
        player:teleportTo(exit_position)
      
        -- remove creatures
        local spec = Game.getSpectators(fromPosition, false, false, 1, 1, 1, 1)
        for i = 1, #spec do
            spec[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            spec[i]:remove()
        end
        return true
      
    -- if teleporting into trainers
    elseif actionID == config.actionids[1] then
        for i = 1, #positionData do
            local spec, players = Game.getSpectators(positionData[i][1], false, false, 1, 1, 1, 1), 0
          
            -- if creatures exist in training position, check if any are a player
            if #spec > 0 then
                for i = 1, #spec do
                    if spec[i]:isPlayer() then
                        if spec[i]:getIp() ~= 0 then -- if player is still online (not x-logged or disconnected)
                            players = 1
                        end
                        break
                    end
                end
            end
          
            -- if no online player found, and creatures exist, remove all creatures in training room.
            if players == 0 and #spec > 0 then
                for i = 1, #spec do
                    spec[i]:remove()
                end
                spec = {} -- clear spectator table
            end
          
            -- if empty, teleport in and create training creatures
            if #spec < 1 then
                player:teleportTo(positionData[i][1])
                for n = 1, 2 do
                    Game.createMonster(config.trainingPartner, positionData[i][n + 1])
                end
                return true
            end
        end
    end
  
    -- no locations available to teleport to
    local text = "Sorry, no training tiles are available. Try again later."
    if not positionData[1] then
        text = "Training tiles are still being populated by the server. Please wait 10 seconds."
    end
    player:sendTextMessage(MESSAGE_STATUS_WARNING, text)
    player:teleportTo(fromPosition, true)
    return true
end

moveEvent:aid(config.actionids[1], config.actionids[3])
moveEvent:register()


local direction = {
    {-1, 0, -1, 1, -1, -1}, -- west
    {1, 0, 1, 1, 1, -1}, -- east
    {0, -1, 1, -1, -1, -1}, -- north
    {0, 1, 1, 1, -1, 1} -- south
}

local function collect_positionData(current_x, current_y)
    local position = Position(current_x, current_y, config.boundaries.z)
    local tile = Tile(position)
  
    -- if tile exists
    if tile then
        -- if tile has actionid
        local item = Item(tile:getGround().uid)
        if item:getActionId() == config.actionids[2] then
            -- find positions to spawn training creatures
            for i = 1, 4 do -- 4 possible directions
                -- make sure tile exists
                local check_tile = Tile(Position(current_x + direction[i][1], current_y + direction[i][2], config.boundaries.z))
                if check_tile then
                    -- if teleport exists on tile
                    local teleport_count = check_tile:getItemCountById(config.portalID)
                    if teleport_count > 0 then
                        -- we know which direction to spawn training creatures
                        local pos_1 = Position(current_x + direction[i][3], current_y + direction[i][4], config.boundaries.z)
                        local pos_2 = Position(current_x + direction[i][5], current_y + direction[i][6], config.boundaries.z)
                         -- add positions into table
                        positionData[#positionData + 1] = {position, pos_1, pos_2}
                        break
                    end
                end
            end
        end
    end
  
    -- calculate next tile
    if current_x == config.boundaries[2].x then
        current_x = config.boundaries[1].x
        current_y = current_y + 1
    else
        current_x = current_x + 1
    end
  
    -- check if next tile is within check area
    if config.boundaries[2].y + 1 ~= current_y then
        addEvent(collect_positionData, 1, current_x, current_y)
    end
end

local globalEvent = GlobalEvent()
globalEvent:type("startup")

function globalEvent.onStartup()
    addEvent(collect_positionData, 1000, config.boundaries[1].x, config.boundaries[1].y)
    return true
end

globalEvent:register()



local loginEvent = CreatureEvent("onLogin_trainingRoomTeleporter")
loginEvent:type("login")

function loginEvent.onLogin(player)
    local north_west = Position(config.boundaries[1].x, config.boundaries[1].y, config.boundaries.z)
    local south_east = Position(config.boundaries[2].x, config.boundaries[2].y, config.boundaries.z)
    if player:getPosition():isInRange(north_west, south_east) then
        local exit_position = config.exitPosition
        if exit_position == false then
            exit_position = player:getTown():getTemplePosition()
        end
        player:teleportTo(exit_position)
    end
    return true
end

loginEvent:register()
I will test it in 1h,
I hope I don't have a problem with it.
Anyway, thank you.
 
could you make two scripts for tfs 1.3 please. ?

if lever is used remove a wall. If it's used again add wall, but checking if a corpse , person or item is in there ( on the sqm where the wall will be created or added. if that is the case push the player, item, corpse, magic field 1 sqm back.

the second script works very similar but consists on;

if lever is used remove x roof or floor id. if a player or an item, corpse monster.. is standing on the sqm that will be removed when the lever is being used, they should fall down. if there is an magic field when the on the floor when the lever it used it should disappear. if the lever is used again add the roof / or floor id again


thanks in advance
what abut this... ? :(
 
Status
Not open for further replies.
Back
Top