• 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.4.2

Xikini

I whore myself out for likes
Senator
Premium User
Joined
Nov 17, 2010
Messages
6,801
Solutions
582
Reaction score
5,363
Request whatever you want, within reason.

Please do not request for things that require source editing or database queries.

------------------------------------
If I've reacted to your post, it means I've read it. 👍😍🤣😲🙁😡🤔😉

------------------------------------
Completed Requests

A boss that randomly creates effects on tiles, that when stepped on, gives the player increased damage/mitigation to that boss.
Kill monster and gain X% extra loot chance or Y% extra experience for Z minutes
A pack of 6 useful simple scripts.
-> (1) Simple quest npc
-> (2,3,4,5) use levers in specific order / stand with 4 players / use 4 objects / place items -> to open wall
-> (6) use lever to add/remove/replace objects
Wave type spell, with multiple effects
-> Same spell, but with default combat system
House market system. (owner places price on blackboard and object on the ground, other players buy with a lever)
Respawn System (closest anchor (like darks souls bonfire) / tavern / temple)
Vocation Death Protection (protect the noobs!)
Spell that shows area it will damage, before it strikes.
RAID SYSTEM - rebuilt in Lua, with some more features.
Modal Window - Teleport Item with saving/deleting of positions
Show top 3 Online Players (outfit, name, level) (as monsters, in set positions)
onLook function showing kill count of player.
Modal Window - Use Item -> choose reward.
Talkaction - !backpacks - to buy backpacks (or single items) anywhere. uses bank & current money on players
Quest/Event? Turn a bunch of objects with a monster, spawn portal.
Spawn Monsters, after they've all been killed, give global increased experience/loot in specific area's
Evolving Weapons - Kill X amount of specific creatures, evolve weapon and gain extra damage to those creatures.
Random Portals spawn at XX:XX time(s). (can exit 'off' portals, if you have the storage.)
Monster that adjusts speed based on target
Monster that increases damage output based on # of players nearby
Experience recovery Item. Die -> Use Item -> gain % of lost experience
Character Snapshot - Keeps track of all skills & level, for resetting later.
Fire Dagger - Physical Damage Melee Weapon, with % added damage
Players in specific level ranges don't lose skills/loot/experience, when they die.
Multiclient Limit Check - with admin account not being counted towards limit
Capacity Increasing Items
Upgradeable Protection Amulet - 10% to all elements
-> upgrade amulet, but for all items.
onKill - give reward to all players who dealt damage
-> example: give reward based on damage contribution
Quest Book - Record your quest progress into a book.
Stat System, using modal windows
Holy Tible (POI) - Require Item to use teleport tiles
Item Upgrade System
Skill Stages
-> individual stages for each skill type
-> talkaction to check rates (by @Extrodus)
Random Reward Item - gives different rewards based on vocation
Bounty Hunter System
NPC & Player Walk System (Follow Nodes to destination)
Health/Mana gain permanent - limited use items

------------------------------------
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 necessary information it's impossible to help you.

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

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.

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 publicly, 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
---------

P.S.
I've been doing free scripting service's on/off for awhile.
And if you want to see the previous threads, go check them here.

 
Last edited by a moderator:
skillStages is below.

data/scripts/skillStages.lua
Lua:
local skillStages = {
    [{  1,   8}] = {multiplier = 5},
    [{  9,  20}] = {multiplier = 4},
    [{ 21,  50}] = {multiplier = 3},
    [{ 51, 100}] = {multiplier = 2},
    [{101}]      = {multiplier = 1}
}

local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries)
    local playerLevel = self:getLevel()
    for k, v in pairs(skillStages) do
        if playerLevel >= k[1] then
            if not k[2] or playerLevel <= k[2] then
                tries = tries * v.multiplier
                print(v.multiplier)
            end
        end
    end  
    return tries
end

ec:register()

Any chance we could set this to have one config for melee skills and another for magic? Thanks in advance!

ChatGPT Example:
local meleeSkillStages = {
[{1, 8}] = {multiplier = 5},
[{9, 20}] = {multiplier = 4},
[{21, 50}] = {multiplier = 3},
[{51, 100}]= {multiplier = 2},
[{101}] = {multiplier = 1}
}

local magicSkillStages = {
[{1, 8}] = {multiplier = 3},
[{9, 20}] = {multiplier = 2},
[{21, 50}] = {multiplier = 1},
[{51, 100}]= {multiplier = 1},
[{101}] = {multiplier = 1}
}

local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries, skillType)
local playerLevel = self:getLevel()
local skillStages = skillType == "melee" and meleeSkillStages or magicSkillStages

for k, v in pairs(skillStages) do
if playerLevel >= k[1] then
if not k[2] or playerLevel <= k[2] then
tries = tries * v.multiplier
print(v.multiplier)
end
end
end
return tries
end

ec:register()
 
Can you create an upgrade system to develop items and weapons, including the wand
The system must be supported /magiclevelpoints/healthGain/manaGain/
Because I find problems in all available systems
 
I need a task system. It would be great if u did it because I really miss that system
Post automatically merged:

Sup @Xikini, a little question. Which replace should I use for
Lua:
doPlayerSendTextMessage(player, MESSAGE_EVENT_ADVANCE, "Has recibido " .. getItemNameString(rewardItem) .. " por eliminar a un jefe.")

To get the killed boss name on the message, at the end? Instead "por eliminar a un jefe", send "por eliminar "bossname"".
Testing: Lua - Xikini's Free Scripting Service TFS 1.4.2 (https://otland.net/threads/xikinis-free-scripting-service-tfs-1-4-2.287753/page-8#post-2744725)

Edit: Also wondering if there could be an addition of day parameter to the raid system. So it spawns only "Mondays", or "Tuesdays and Saturdays", etc. ;p

Thanks in advance!
 
Last edited:
change lib xikini custom functions.

from
Lua:
function parseFormulaAttributes(xmlContent)
    local formulas = {}

    local pattern = "<formula%s+meleeDamage=\"(.-)\"%s+distDamage=\"(.-)\"%s+defense=\"(.-)\"%s+armor=\"(.-)\"%s*/>"
 
    for meleeDamage, distDamage, defense, armor in xmlContent:gmatch(pattern) do
        table.insert(formulas, {
            meleeDamage = meleeDamage,
            distDamage = distDamage,
            defense = defense,
            armor = armor
        })
    end

    return formulas
end


local filePath = "data/XML/vocations.xml"
local xmlContent = readXmlFile(filePath)
GLOBAL_vocationMultipliers = parseFormulaAttributes(xmlContent)
to
Lua:
function parseVocationFormulas(xmlContent)
    local vocations = {}

    local pattern = "<vocation%s+id=\"(.-)\".-<formula%s+meleeDamage=\"(.-)\"%s+distDamage=\"(.-)\"%s+defense=\"(.-)\"%s+armor=\"(.-)\"%s*/>"
 
    for id, meleeDamage, distDamage, defense, armor in xmlContent:gmatch(pattern) do
        vocations[tonumber(id)] = {
            meleeDamage = meleeDamage,
            distDamage = distDamage,
            defense = defense,
            armor = armor
        }
    end

    return vocations
end


local filePath = "data/XML/vocations.xml"
local xmlContent = readXmlFile(filePath)
GLOBAL_vocationMultipliers = parseVocationFormulas(xmlContent)
New request can also do it for bow/crossbow
change lib xikini custom functions.

from
Lua:
function parseFormulaAttributes(xmlContent)
    local formulas = {}

    local pattern = "<formula%s+meleeDamage=\"(.-)\"%s+distDamage=\"(.-)\"%s+defense=\"(.-)\"%s+armor=\"(.-)\"%s*/>"
 
    for meleeDamage, distDamage, defense, armor in xmlContent:gmatch(pattern) do
        table.insert(formulas, {
            meleeDamage = meleeDamage,
            distDamage = distDamage,
            defense = defense,
            armor = armor
        })
    end

    return formulas
end


local filePath = "data/XML/vocations.xml"
local xmlContent = readXmlFile(filePath)
GLOBAL_vocationMultipliers = parseFormulaAttributes(xmlContent)
to
Lua:
function parseVocationFormulas(xmlContent)
    local vocations = {}

    local pattern = "<vocation%s+id=\"(.-)\".-<formula%s+meleeDamage=\"(.-)\"%s+distDamage=\"(.-)\"%s+defense=\"(.-)\"%s+armor=\"(.-)\"%s*/>"
 
    for id, meleeDamage, distDamage, defense, armor in xmlContent:gmatch(pattern) do
        vocations[tonumber(id)] = {
            meleeDamage = meleeDamage,
            distDamage = distDamage,
            defense = defense,
            armor = armor
        }
    end

    return vocations
end


local filePath = "data/XML/vocations.xml"
local xmlContent = readXmlFile(filePath)
GLOBAL_vocationMultipliers = parseVocationFormulas(xmlContent)
New request might be an edit, can you do this with a crossbow too?
 
Hi Xikini, I have an idea of a script for NPC, to make them feel more natural.

If certain hour comes, lets say 20:00, NPC will walk away walking certain path and finally stop on a given coordinates and will stay inactive for some time, for example until 08:00, and then walk back into its "day" coordinates and become active again. Would be dope if it would walk into the bed and disappear, making bed change its sprites into occupied version.

Another idea are inactive NPCs that would talk to each other from time to time.

Thank you in advance!
 
Hello!

I want a script! :)

It is a script for "drop based on vocation", so basically, when players participate in certain events, they get a special coin, with this coin they can buy chests in a specific store to drop crafting materials to create new outfits. The point is that I don't want these crafting materials from the chest to be dropped at the same proportion. Why? Because when a player gets more or less of the same crafting materials of all outfits (let's say there are 4, one for each vocation) they may take let's say 2 weeks to get enough materials to craft the first outfit, but then it will take only couple days to craft the other 3.

And if the drop from the chest depends on the vocation they used in the events where they got the coins, then they will get more crafting materials for a specific vocation outfit.


I was thinking that if a player uses Knight, for example, he will get 50% crafting materials for Druid, 25% for Sorc, 15% for Warrior, and 10% for Paladin.

This could be done with a system of "Internal different Coins". So let's say that these special coins to buy chests in the special store are called "Arak Coins". Externally (What players see) is always Arak Coins, but internally there are 4 different Arak Coins (1. Druid Arak Coins, 2. Knight Arak Coins, 3. Paladin Arack Coins, and 4. Sorcerer Arack Coins. When they play an event with the knight and receive 100 Arak Coins, they receive (based on the % above):

50 Druid Arak Coins
25 Sorcerer Arack Coins
15 Knight Arak Coins
10 Paladin Arack Coins

This way players when players buy a Chest from the "Special Shop", they are buying crafting materials for specific vocation outfits instead of equally random, and so depending on the vocations they are using in the events they will be more likely getting one specific vocation outfit or another, making the vocation rotation more appetizing and the outfit p2p in-game market more active.

Btw, your work is insanely amazing, I really appreciate it!!

:)
 
Last edited:
Did you not understand something?
No just forgot it existed.
Somehow didn't make it onto the list.
Post automatically merged:

Sup @Xikini, a little question. Which replace should I use for
Lua:
doPlayerSendTextMessage(player, MESSAGE_EVENT_ADVANCE, "Has recibido " .. getItemNameString(rewardItem) .. " por eliminar a un jefe.")

To get the killed boss name on the message, at the end? Instead "por eliminar a un jefe", send "por eliminar "bossname"".
Testing: Lua - Xikini's Free Scripting Service TFS 1.4.2 (https://otland.net/threads/xikinis-free-scripting-service-tfs-1-4-2.287753/page-8#post-2744725)

Edit: Also wondering if there could be an addition of day parameter to the raid system. So it spawns only "Mondays", or "Tuesdays and Saturdays", etc. ;p

Thanks in advance!
Lua:
doPlayerSendTextMessage(player, MESSAGE_EVENT_ADVANCE, "You received " .. getItemNameString(rewardItem) .. " for your contribution in killing " .. creature:getName() .. "!")
New request can also do it for bow/crossbow

New request might be an edit, can you do this with a crossbow too?
I made it for generic physical damage, I think.
I say just use it as-is. lol
Hi Xikini, I have an idea of a script for NPC, to make them feel more natural.

If certain hour comes, lets say 20:00, NPC will walk away walking certain path and finally stop on a given coordinates and will stay inactive for some time, for example until 08:00, and then walk back into its "day" coordinates and become active again. Would be dope if it would walk into the bed and disappear, making bed change its sprites into occupied version.

Another idea are inactive NPCs that would talk to each other from time to time.

Thank you in advance!
I had semi-plans to do this already. xD
Hello!

I want a script! :)

It is a script for "drop based on vocation", so basically, when players participate in certain events, they get a special coin, with this coin they can buy chests in a specific store to drop crafting materials to create new outfits. The point is that I don't want these crafting materials from the chest to be dropped at the same proportion. Why? Because when a player gets more or less of the same crafting materials of all outfites (let's say there are 4, one for each vocation) they may take let's say 2 weeks to get enough materials to craft the first outfit, but then it will take only couple days to craft the other 3.

And if the drop from the chest depends on the vocation they used in the events where they got the coins, then they will get more crafting materials of an specific vocation outfit.


I was thinking that if a player uses knight, for example, he will get 50% crafting materials for Druid, 25% for Sorc, 15% for Warrior, and 10% for Paladin.

This way players will always receive an outfit that they probably don't want and will sell it in the ingame market to but the one they are looking for, and this way the ingame market has more activity.

:)
So tldr, a random reward item that gives different rewards depending on the vocation?
 
I saw you reacted to my post when i was editing it with the function internal proposal, so I'm just making sure you don't miss it :p

ty!
Hello!

I want a script! :)

It is a script for "drop based on vocation", so basically, when players participate in certain events, they get a special coin, with this coin they can buy chests in a specific store to drop crafting materials to create new outfits. The point is that I don't want these crafting materials from the chest to be dropped at the same proportion. Why? Because when a player gets more or less of the same crafting materials of all outfits (let's say there are 4, one for each vocation) they may take let's say 2 weeks to get enough materials to craft the first outfit, but then it will take only couple days to craft the other 3.

And if the drop from the chest depends on the vocation they used in the events where they got the coins, then they will get more crafting materials for a specific vocation outfit.


I was thinking that if a player uses Knight, for example, he will get 50% crafting materials for Druid, 25% for Sorc, 15% for Warrior, and 10% for Paladin.

This could be done with a system of "Internal different Coins". So let's say that these special coins to buy chests in the special store are called "Arak Coins". Externally (What players see) is always Arak Coins, but internally there are 4 different Arak Coins (1. Druid Arak Coins, 2. Knight Arak Coins, 3. Paladin Arack Coins, and 4. Sorcerer Arack Coins. When they play an event with the knight and receive 100 Arak Coins, they receive (based on the % above):

50 Druid Arak Coins
25 Sorcerer Arack Coins
15 Knight Arak Coins
10 Paladin Arack Coins

This way players when players buy a Chest from the "Special Shop", they are buying crafting materials for specific vocation outfits instead of equally random, and so depending on the vocations they are using in the events they will be more likely getting one specific vocation outfit or another, making the vocation rotation more appetizing and the outfit p2p in-game market more active.

Btw, your work is insanely amazing, I really appreciate it!!

:)
I saw you reacted to my post when i was editing it with the function internal proposal, so I'm just making sure you don't miss it :p

ty!
 
Single Tasks at a time
can you make
player kills npc task with money and exp and item rewards. can only start 1 player kill task at time.
like this
task to kill 400 players with money and exp and item rewards
when finished choose next task with 600 to kill 600 players with money and exp and item rewards
task kills are counted in channel with orange msg so player can know how many left and when finished
thank you
this one here i meant player killing tasks, pk tasks not monsters killing. you added with the monsters task requests so just clearing this part.
 
3399ca3c214d195fc892161ec7d4d073.png

The Final Bounty Hunter System to Rule Them All
I've been looking around and there have been some systems made in the past but either they were 0.3/0.4 or were not up to par.​

For this system, I had the following in mind as a basic skeleton:
  • Player A goes to a specific NPC and asks to place a bounty on Player B at XXX amount of gold.​
  • Player B is listed on a bounty list, which can be checked by looking on a Blackboard (or any writable/hangable). (I couldn't care less about displaying it on the website)​
  • Player C kills Player B and receives the gold.​

To make it advanced and better than all the others:
  • Ability for Player B to buy off his bounty.​
  • If two players participate in a kill, the gold is shared, except if one of the attackers dies, then only the one that survived gets all the gold (or giving the hunted a chance to get away).​
  • If a Player receives a Red Skull, the system automatically puts a bounty of XXX gold on a player.​
  • Players are able to increase existing bounties.​
  • Make players with a certain storage immune to be targeted by regular players, although if a player has a certain storage value, they can put a bounty on that player.​
This way I can categorize races (vocations), and whatnot.

Important notes:
- Everything done must be through an NPC, rather not use a talkaction to put a bounty on someone.

The Lord Of The Rings GIF by Maudit
Scared Cringe GIF by O&O, Inc
lord of the rings queue GIF


Don't hate me xD
 
Last edited:
Hi @Xikini , Could you help me create a revscripts of actions that "x" item adds "x" amount of life and "y" item adds "y" amount of mana. I also need to have a limiter on how many stones I could use.
Can you create an upgrade system to develop items and weapons, including the wand
The system must be supported /magiclevelpoints/healthGain/manaGain/
Because I find problems in all available systems

bandicam2024-02-1809-54-16-601-ezgif.com-video-to-gif-converter.gif


data/scripts/eventcallbacks/player/default_onLook.lua

add to very top
Lua:
local conditions = {
    "life increase",
    "mana increase",
    "speed",
    "magic",
    "melee",
    "fist",
    "club",
    "sword",
    "axe",
    "distance",
    "shield",
    "fishing",
    "critical hit chance",
    "critical hit damage",
    "life leech chance",
    "life leech amount",
    "mana leech chance",
    "mana leech amount",
    "life increase percent",
    "mana increase percent",
    "magic percent",
    "melee percent",
    "fist percent",
    "club percent",
    "sword percent",
    "axe percent",
    "distance percent",
    "shield percent",
    "fishing percent",
    "life regen",
    "mana regen",
    "soul regen"
}
add under local description = "You see " .. thing:getDescription(distance)
Lua:
    if thing:isItem() then
        for i = 1, #conditions do
            local currentStatAmount = thing:getCustomAttribute(conditions[i])
            currentStatAmount = currentStatAmount and currentStatAmount or 0
            if currentStatAmount > 0 then
                description = description .. "\n" .. conditions[i] .. ": " .. currentStatAmount
            end
        end
    end
data/scripts/itemUpgradeSystem.lua
Lua:
local conditionSubId = 45083 -- must be a unique subId not used for other buffs in your server
local config = {
    ["statMain"] = {
        -- flat_bonus_stats
        {statType = "life increase"},
        {statType = "mana increase"},
        {statType = "magic"},
        {statType = "fist"},
        {statType = "melee"},
        {statType = "distance"},
        {statType = "shield"},
        {statType = "fishing"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 1000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 1000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = {
        {statType = "soul regen", ticks = 1000}
    },
  
    maxUpgradesPerItem = 5,
    upgradeItems = {
        [8302] = {statType = "reset item"},
        [8303] = {statType = "life increase", value = 100},
    },
    specialDisallowedItems = {} -- any items that shouldn't be upgradeable, add them here
}

-- Choose Flat or Percentage stats. Cannot use both.

-- Flat Stats
--[[
    ["statMain"] = {
        -- flat_bonus_stats
        {statType = "life increase"},
        {statType = "mana increase"},
        {statType = "magic"},
        {statType = "fist"},
        {statType = "melee"},
        {statType = "distance"},
        {statType = "shield"},
        {statType = "fishing"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 5000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 5000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = { -- you can remove entire categories
        {statType = "soul regen", ticks = 5000} -- or individual stats, if you don't want to use them
    },
]]--


-- Percent Stats
--[[
    ["statMain"] = {
        -- percent_bonus_stats
        {statType = "life increase percent"},
        {statType = "mana increase percent"},
        {statType = "magic percent"},
        {statType = "fist percent"},
        {statType = "melee percent"},
        {statType = "distance percent"},
        {statType = "shield percent"},
        {statType = "fishing percent"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 5000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 5000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = {
        {statType = "soul regen", ticks = 5000}
    },
]]--


-- END OF CONFIG

local choiceDictionary = {}

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 updateStatBonus(playerId)
    local player = Player(playerId)
    if not player then
        return
    end
  
    -- remove all previous buffs
    for i = 1, 4 do
        if player:getCondition(main_attributes[i], conditionSubId) then
            player:removeCondition(main_attributes[i], conditionSubId)
        end
    end
  
    local equippedItems = {}
    for slot = 1, 10 do
        local slotItem = player:getSlotItem(slot)
        if slotItem then
            equippedItems[#equippedItems + 1] = slotItem
        end
    end
  
    -- add all buffs
    for i = 1, 4 do
        local statCategory = main_stats[i]
        if config[statCategory] then
            local condition = Condition(main_attributes[i], conditionSubId)
            condition:setParameter(CONDITION_PARAM_TICKS, -1)
            for _, stat in ipairs(config[statCategory]) do
                local statValue = 0
                for i = 1, #equippedItems do
                    local itemValue = equippedItems[i]:getCustomAttribute(stat.statType)
                    statValue = itemValue and itemValue + statValue or statValue
                end
                if statValue > 0 then
                    for conditionParam = 1, #conditions[stat.statType] do
                        condition:setParameter(conditions[stat.statType][conditionParam], statValue)
                    end
                    player:addCondition(condition)
                end
            end
        end
    end
    return true
end


local slotTypes = {
    48, -- weapon or shield
    49, -- helmet
    50, -- amulet
    52, -- backpack
    56, -- armor
    112, -- legs
    176, -- boots
    304, -- ring
    560, -- ammo
    2096 -- two handed
}

local function isItemUpgradeable(item)
    if not item:isItem() then
        return false
    end
    local itemType = ItemType(item:getId())
    if not table.contains(slotTypes, itemType:getSlotPosition()) then
        return false
    end
    if itemType:isStackable() then
        return false
    end
    if table.contains(config.specialDisallowedItems, item:getId()) then
        return false
    end
    return true
end



local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not isItemUpgradeable(target) then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Not a valid item to apply upgrades too.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF, player)
        return true
    end
  
    local itemIndex = config.upgradeItems[item:getId()]
    local itemUpgradeCount = target:getCustomAttribute("Upgrade Counter")
    itemUpgradeCount = itemUpgradeCount and itemUpgradeCount or 0
  
    if itemIndex.statType == "reset item" then
        if itemUpgradeCount == 0 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has no upgrades to reset.")
            target:getPosition():sendMagicEffect(CONST_ME_POFF, player)
            return true
        end
        for k, v in pairs(conditions) do
            target:removeCustomAttribute(k)
        end
        target:removeCustomAttribute("Upgrade Counter")
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE, player)
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "All upgrades have been removed from this item.")
        item:remove(1)
        if toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 then
            addEvent(updateStatBonus, 0, player:getId())
        end
        return true
    end
  
    if itemUpgradeCount >= config.maxUpgradesPerItem then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has reached max upgrades.")
        target:getPosition():sendMagicEffect(CONST_ME_POFF, player)
        return true
    end
  
    local currentStatAmount = target:getCustomAttribute(itemIndex.statType)
    currentStatAmount = currentStatAmount and currentStatAmount or 0
    target:setCustomAttribute(itemIndex.statType, currentStatAmount + itemIndex.value)
    target:setCustomAttribute("Upgrade Counter", itemUpgradeCount + 1)
  
    target:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN, player)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has been upgraded.")
    item:remove(1)
  
    if toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 then
        addEvent(updateStatBonus, 0, player:getId())
    end
    return true
end

for itemId, _ in pairs(config.upgradeItems) do
    action:id(itemId)
end
action:register()


local creatureevent = CreatureEvent("onLogin_updateItemStatBonus")

function creatureevent.onLogin(player)
    updateStatBonus(player:getId())
    return true
end

creatureevent:register()


local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if not (toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 or fromPosition.x == CONTAINER_POSITION and fromPosition.y <= 10) then
        return RETURNVALUE_NOERROR
    end
    addEvent(updateStatBonus, 0, self:getId())
    return RETURNVALUE_NOERROR
end

ec:register()
Post automatically merged:

Any chance we could set this to have one config for melee skills and another for magic? Thanks in advance!

ChatGPT Example:
local meleeSkillStages = {
[{1, 8}] = {multiplier = 5},
[{9, 20}] = {multiplier = 4},
[{21, 50}] = {multiplier = 3},
[{51, 100}]= {multiplier = 2},
[{101}] = {multiplier = 1}
}

local magicSkillStages = {
[{1, 8}] = {multiplier = 3},
[{9, 20}] = {multiplier = 2},
[{21, 50}] = {multiplier = 1},
[{51, 100}]= {multiplier = 1},
[{101}] = {multiplier = 1}
}

local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries, skillType)
local playerLevel = self:getLevel()
local skillStages = skillType == "melee" and meleeSkillStages or magicSkillStages

for k, v in pairs(skillStages) do
if playerLevel >= k[1] then
if not k[2] or playerLevel <= k[2] then
tries = tries * v.multiplier
print(v.multiplier)
end
end
end
return tries
end

ec:register()
Lua:
local skillStages = {
    [SKILL_FIST] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_CLUB] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_SWORD] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_AXE] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_DISTANCE] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_SHIELD] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_FISHING] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    },
    [SKILL_MAGLEVEL] = {
        [{  1,   8}] = {multiplier = 5},
        [{  9,  20}] = {multiplier = 4},
        [{ 21,  50}] = {multiplier = 3},
        [{ 51, 100}] = {multiplier = 2},
        [{101}]      = {multiplier = 1}
    }
}


local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries)
    if not skillStages[skill] then
        return tries
    end
    local playerLevel = skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getSkillLevel(skill)
    for k, v in pairs(skillStages[skill]) do
        if playerLevel >= k[1] then
            if not k[2] or playerLevel <= k[2] then
                tries = tries * v.multiplier
            end
        end
    end  
    return tries
end

ec:register()
Post automatically merged:

Edit: Also wondering if there could be an addition of day parameter to the raid system. So it spawns only "Mondays", or "Tuesdays and Saturdays", etc. ;p

Thanks in advance!
Added.

Go to the post and find the uploaded script, as per usual. lol
 
Last edited:
But can they use magic and runes? It should be that they cannot use spells, runes, potions, etc., but they can speak normal messages. However, they cannot use magic, runes, potions, etc. Do you understand?
I managed to figure out how to block spells, runes, and even potions... I feel so blind! Tested and functional, everything works! Thank you for your TIME. :)
 
Hello!

I want a script! :)

It is a script for "drop based on vocation", so basically, when players participate in certain events, they get a special coin, with this coin they can buy chests in a specific store to drop crafting materials to create new outfits. The point is that I don't want these crafting materials from the chest to be dropped at the same proportion. Why? Because when a player gets more or less of the same crafting materials of all outfits (let's say there are 4, one for each vocation) they may take let's say 2 weeks to get enough materials to craft the first outfit, but then it will take only couple days to craft the other 3.

And if the drop from the chest depends on the vocation they used in the events where they got the coins, then they will get more crafting materials for a specific vocation outfit.


I was thinking that if a player uses Knight, for example, he will get 50% crafting materials for Druid, 25% for Sorc, 15% for Warrior, and 10% for Paladin.

This could be done with a system of "Internal different Coins". So let's say that these special coins to buy chests in the special store are called "Arak Coins". Externally (What players see) is always Arak Coins, but internally there are 4 different Arak Coins (1. Druid Arak Coins, 2. Knight Arak Coins, 3. Paladin Arack Coins, and 4. Sorcerer Arack Coins. When they play an event with the knight and receive 100 Arak Coins, they receive (based on the % above):

50 Druid Arak Coins
25 Sorcerer Arack Coins
15 Knight Arak Coins
10 Paladin Arack Coins

This way players when players buy a Chest from the "Special Shop", they are buying crafting materials for specific vocation outfits instead of equally random, and so depending on the vocations they are using in the events they will be more likely getting one specific vocation outfit or another, making the vocation rotation more appetizing and the outfit p2p in-game market more active.

Btw, your work is insanely amazing, I really appreciate it!!

:)

Based on your description, this is the best I could come up with.

The people who use the chest, get reward chances based on their vocation.

Lua:
local rewardChestId = 1746
local rewards = {
    vocations = {
        [{1, 5}] = { -- sorc & master sorc
            chanceType = "sorcerer",
            ["sorcerer"] = {itemChanceModifier = 1},
            ["druid"] = {itemChanceModifier = 2}, -- 2x harder to get druid items, if your class is sorcerer
            ["paladin"] = {itemChanceModifier = 3},
            ["knight"] = {itemChanceModifier = 3}
        },
        [{2, 6}] = { -- druid & elder druid
            chanceType = "druid",
            ["sorcerer"] = {itemChanceModifier = 2},
            ["druid"] = {itemChanceModifier = 1},
            ["paladin"] = {itemChanceModifier = 3},
            ["knight"] = {itemChanceModifier = 3}
        },
        [{3, 7}] = { -- paladin & royal paladin
            chanceType = "paladin",
            ["sorcerer"] = {itemChanceModifier = 3},
            ["druid"] = {itemChanceModifier = 3},
            ["paladin"] = {itemChanceModifier = 1},
            ["knight"] = {itemChanceModifier = 2}
        },
        [{4, 8}] = { -- knight & elite knight
            chanceType = "knight",
            ["sorcerer"] = {itemChanceModifier = 3},
            ["druid"] = {itemChanceModifier = 3},
            ["paladin"] = {itemChanceModifier = 2},
            ["knight"] = {itemChanceModifier = 1}
        }
    },
    rewardAmount = {min = 100, max = 100}, -- item rewards you receive for each chest
    itemList = {
        {itemId = 2160, amount = {min = 1, max = 1}, chance = 10000, chanceType = "sorcerer"}, -- chance 10000 = 100% | 100 = 1% | 1 = 0.01%
        {itemId = 2152, amount = {min = 1, max = 1}, chance = 10000, chanceType = "druid"},
        {itemId = 2148, amount = {min = 1, max = 1}, chance = 10000, chanceType = "paladin"},
        {itemId = 8302, amount = {min = 1, max = 1}, chance = 10000, chanceType = "knight"}
    }
}

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local vocation = player:getVocation():getId()
    local chanceTypes
    for k, v in pairs(rewards.vocations) do
        if table.contains(k, vocation) then
            chanceTypes = {
                ["sorcerer"] = v["sorcerer"].itemChanceModifier,
                ["druid"] = v["druid"].itemChanceModifier,
                ["paladin"] = v["paladin"].itemChanceModifier,
                ["knight"] = v["knight"].itemChanceModifier
            }
            vocation = v.chanceType
            break
        end
    end
    local rewardAmount = math.random(rewards.rewardAmount.min, rewards.rewardAmount.max)
    local _rewards = {}
    while #_rewards < rewardAmount do
        for k, v in pairs(rewards.itemList) do
            local chance = 10000 * chanceTypes[v.chanceType]
            if math.random(chance) <= v.chance then
                _rewards[#_rewards + 1] = {itemId = v.itemId, amount = math.random(v.amount.min, v.amount.max)}
            end
        end
    end
    for i = 1, rewardAmount do
        local rand = math.random(#_rewards)
        player:addItem(_rewards[rand].itemId, _rewards[rand].amount, true)
        table.remove(_rewards[rand])
    end
    item:remove(1)
    return true
end

action:id(rewardChestId)
action:register()
 
Can you create an upgrade system to develop items and weapons, including the wand
The system must be supported /magiclevelpoints/healthGain/manaGain/
Thank you but the script is not working as my requested
1 It does not increase the hits of any weapon

Your original request only asked for 3 things.
"magiclevelpoints/healthGain/manaGain"

aka
Lua:
{statType = "magic"}
{statType = "life regen", ticks = 1000}
{statType = "mana regen", ticks = 1000}

I've added those 3 things + like 30 more.

2 Does not upgrade skill/clup/sword/axe/distance/magic level
It only increases the hp of items

If you set up more items it will do more then just hp..
jfc..
Lua:
    upgradeItems = {
        [8302] = {statType = "reset item"},
        [8303] = {statType = "life increase", value = 100}, -- wow life increase. now copy the line and do more items with different stats?
    },

Because I find problems in all available systems

I think we found the problem.
You don't understand how to setup a script.

View attachment bandicam 2024-02-18 13-53-57-341.mp4
 
Last edited:
If you set up more items it will do more then just hp..
jfc..
There is one problem When I try to develop a weapon
Lua:
        [7760] = {statType = "critical hit chance", value = 100},
        [7761] = {statType = "critical hit damage",  value = 100},
if critical hit chance +5 Does not increase weapon strikes
also if critical hit damage +5 Does not increase weapon strikes
But if it is critical hit chance +1 and critical hit damage +2/3/4 Increases weapon hits
 
Thank you but the script is not working as my requested
1 It does not increase the hits of any weapon
2 Does not upgrade skill/clup/sword/axe/distance/magic level
It only increases the hp of items
I took the script he posted and tested it perfectly, then changed another attribute and it's still working well. You just need to understand how to configure it correctly, haha.
 
Back
Top