• 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,756
Solutions
578
Reaction score
5,305
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:
I'll look into it, but no promises. xD

Request as many as you like.
I won't guarantee that I can do them all though.

as per main post.. VV
Sorry.


Can you please explain what you want the script to do?
I'll look into it, but no promises. xD

Request as many as you like.
I won't guarantee that I can do them all though.

as per main post.. VV
Sorry.


Can you please explain what you want the script to do?
when you step in to the tp you go to one of the many rooms you mapped and it resp 2 training monks in the spots northwest-southwest of you and after you leave it then it remove monks.
Post automatically merged:

like the training system in all servers but it was never made for 1.3 <complete training system> myb add time to it. the other one work but no storage to know player left or joined then every one can spam in and out until it is all full
 

Attachments

  • received_303737327572357.png
    received_303737327572357.png
    332.2 KB · Views: 28 · VirusTotal
Last edited:
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()
Nice work bro! Really glad you migrated to 1.x, always admired your job.
I will test soon, but appears to be very solid...
About: {"speed", 1000} -- when testing, it only gave half of this value. Might just be my client though, take a look here i think is same "problem".
 
"Daily random boosted creatures"
Every day, there will be 2 random creatures that will yield u 50% + exp. With the possibility to show you a message on-screen everytime you login, example: Today boosted creatures: Warlock and Demon.

🤔
 
Damage type buffs (onuse)
For example drinking certain potion will increase the player holy damage by 5pts.
Frost,Fire damage, physical,desth etc.

So for example everytime he does damage with a holy spell it is gonna be +3.

Done. :)
Gif below shows it working for earth damage.

bandicam-2020-08-25-19-39-43-783.gif

Note: By default this will only work on players, unless you register the script inside of all monsters. (code from below)

data\events\scripts\monster.lua
inside the function function Monster:onSpawn(position, startup, artificial)
paste
Lua:
self:registerEvent("onHealthChange_damage_buff_potion")

data\scripts\onUse_damage_buff_potion.lua
Lua:
local damageTypes = {
    [COMBAT_PHYSICALDAMAGE] = {45001, 45002}, -- {damageStorage, timeStorage}
    [COMBAT_ENERGYDAMAGE]   = {45003, 45004},
    [COMBAT_EARTHDAMAGE]    = {45005, 45006},
    [COMBAT_FIREDAMAGE]     = {45007, 45008},
    [COMBAT_ICEDAMAGE]      = {45009, 45010},
    [COMBAT_HOLYDAMAGE]     = {45011, 45012},
    [COMBAT_DEATHDAMAGE]    = {45013, 45014}
}

local buff_potions = {
    --[itemid] = {damageType, buffAmount, buffTimeInSeconds, damageTypeText}
    [1111] = {COMBAT_PHYSICALDAMAGE, 30, 60, "physical"},
    [2222] = {COMBAT_ICEDAMAGE, 30, 60, "ice"},
    [3333] = {COMBAT_HOLYDAMAGE, 30, 60, "holy"}
}

local buffPotions = Action()

function buffPotions.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local index, cur_time = buff_potions[item.itemid], os.time()
    local buff_timer = cur_time + index[3]
    local playerPosition = player:getPosition()
   
    -- if a buff of equal or greater damage is currently active, don't let new buff activate.
    if player:getStorageValue(damageTypes[index[1]][2]) > cur_time then
        if player:getStorageValue(damageTypes[index[1]][1]) >= index[2] then
            playerPosition:sendMagicEffect(CONST_ME_POFF, player)
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "A buff of this damage type (" .. index[4] .. ") is still active.")
            return true
        end
    end

    player:setStorageValue(damageTypes[index[1]][1], index[2])
    player:setStorageValue(damageTypes[index[1]][2], buff_timer)
    playerPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "" .. (index[4]:gsub("^%l", string.upper)) .. " damage increased by " .. index[2] .. " for " .. index[3] .. " seconds.")
    item:remove(1)
    return true
end

for k, v in pairs(buff_potions) do
    buffPotions:id(k) -- adds all itemids from table
end
buffPotions:register()


local function damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, playerid)
    local player = Player(playerid)
    local currentTime = os.time()
    
    if primaryType ~= 0 and player:getStorageValue(damageTypes[primaryType][2]) > currentTime then
        local damageValue = player:getStorageValue(damageTypes[primaryType][1])
        local additionalDamage = damageValue > 0 and damageValue or 0
        primaryDamage = primaryDamage + additionalDamage
    end
    
    if secondaryType ~= 0 and player:getStorageValue(damageTypes[secondaryType][2]) > currentTime then
        local damageValue = player:getStorageValue(damageTypes[secondaryType][1])
        local additionalDamage = damageValue > 0 and damageValue or 0
        secondaryDamage = secondaryDamage + additionalDamage
    end
    
    return primaryDamage, secondaryDamage
end

local healthChange = CreatureEvent("onHealthChange_damage_buff_potion")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if Player(attacker) then
        local attacker_id = attacker:getId()
        primaryDamage, secondaryDamage = damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, attacker_id)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()


local manaChange = CreatureEvent("onManaChange_damage_buff_potion")

function manaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if Player(attacker) then
        local attacker_id = attacker:getId()
        primaryDamage, secondaryDamage = damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, attacker_id)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

manaChange:register()


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

function loginEvent.onLogin(player)
    player:registerEvent("onHealthChange_damage_buff_potion")
    player:registerEvent("onManaChange_damage_buff_potion")
    return true
end

loginEvent:register()
 
Last edited:
How about events? I think most good events we have here are made for 0.4 and the ones made for 1.3 aren't good enough.
If you are alright working with events, I can list few here with videos/screenshots.
 
Heya bud, Can u make a script if you killed a monster in a specific area some gate open like a stone appear for 20 seconds then it gone
 
How about events? I think most good events we have here are made for 0.4 and the ones made for 1.3 aren't good enough.
If you are alright working with events, I can list few here with videos/screenshots.
As long as you provide text explaining how the event functions, I'll see what I can do. xP

Ok can you make the script to sell 1,2,3 or ... 'x' store coins (id:24774)?
I'll assume this is by an npc
Heya bud, Can u make a script if you killed a monster in a specific area some gate open like a stone appear for 20 seconds then it gone
Sure. Should be easy.

Is it ANY monster in that area, or specific monster?

-------
Updated Main post to-do list.
 
As long as you provide text explaining how the event functions, I'll see what I can do. xP


I'll assume this is by an npc

Sure. Should be easy.

Is it ANY monster in that area, or specific monster?

-------
Updated Main post to-do list.
A monster called "Combine Advisor"
 
Heya bud, Can u make a script if you killed a monster in a specific area some gate open like a stone appear for 20 seconds then it gone
and Done. :)
Note: don't trap your players. 😋

bandicam-2020-08-26-06-01-12-880.gif


Put this into any monster you want the script to activate for.
XML:
<script>
    <event name="onDeath_open_passageway" />
</script>

data\scripts\ onDeath_open_passageway.lua
Lua:
local config = {
    positionCheck = {north_west = Position(99, 99, 7), south_east = Position(101, 101, 7)},
    item = {Position(103, 100, 7), 1285}, -- {item_position, itemid}
    timer = 20, -- timer is how long until the 'stone' aka: item, is replaced.
    discoveryText = "A passageway has opened nearby!\nQuickly, get inside!"
}

local toggle = 0
local function changePassageway()
    local item = Tile(config.item[1]):getItemById(config.item[2])
    if item then
        item:remove()
        return true
    end
    config.item[1]:sendMagicEffect(CONST_ME_BIGPLANTS)
    Game.createItem(config.item[2], 1, config.item[1])
    toggle = 0
end

local creatureevent = CreatureEvent("onDeath_open_passageway")

function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
    if toggle == 1 then
        return true
    end
    local deathPosition = creature:getPosition()
    if not deathPosition:isInRange(config.positionCheck.north_west, config.positionCheck.south_east) then
        return true
    end
    toggle = 1
    config.item[1]:sendMagicEffect(CONST_ME_POFF)
    changePassageway()
    addEvent(changePassageway, config.timer * 1000)
    creature:say(config.discoveryText, TALKTYPE_MONSTER_SAY, false, nil, deathPosition)    
    return true
end

creatureevent:register()
 
and Done. :)
Note: don't trap your players. 😋

View attachment 49241


Put this into any monster you want the script to activate for.
XML:
<script>
    <event name="onDeath_open_passageway" />
</script>

data\scripts\ onDeath_open_passageway.lua
Lua:
local config = {
    positionCheck = {north_west = Position(99, 99, 7), south_east = Position(101, 101, 7)},
    item = {Position(103, 100, 7), 1285}, -- {item_position, itemid}
    timer = 20, -- timer is how long until the 'stone' aka: item, is replaced.
    discoveryText = "A passageway has opened nearby!\nQuickly, get inside!"
}

local toggle = 0
local function changePassageway()
    local item = Tile(config.item[1]):getItemById(config.item[2])
    if item then
        item:remove()
        return true
    end
    config.item[1]:sendMagicEffect(CONST_ME_BIGPLANTS)
    Game.createItem(config.item[2], 1, config.item[1])
    toggle = 0
end

local creatureevent = CreatureEvent("onDeath_open_passageway")

function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
    if toggle == 1 then
        return true
    end
    local deathPosition = creature:getPosition()
    if not deathPosition:isInRange(config.positionCheck.north_west, config.positionCheck.south_east) then
        return true
    end
    toggle = 1
    config.item[1]:sendMagicEffect(CONST_ME_POFF)
    changePassageway()
    addEvent(changePassageway, config.timer * 1000)
    creature:say(config.discoveryText, TALKTYPE_MONSTER_SAY, false, nil, deathPosition)  
    return true
end

creatureevent:register()
Works like charm, This actually awesome bud Love your great art! keep going appreciate your work.
 
Last edited:
Done. :)
Gif below shows it working for earth damage.

View attachment 49220

Note: By default this will only work on players, unless you register the script inside of all monsters. (code from below)

data\events\scripts\monster.lua
inside the function function Monster:onSpawn(position, startup, artificial)
paste
Lua:
self:registerEvent("onHealthChange_damage_buff_potion")

data\scripts\onUse_damage_buff_potion.lua
Lua:
local damageTypes = {
    [COMBAT_PHYSICALDAMAGE] = {45001, 45002}, -- {damageStorage, timeStorage}
    [COMBAT_ENERGYDAMAGE]   = {45003, 45004},
    [COMBAT_EARTHDAMAGE]    = {45005, 45006},
    [COMBAT_FIREDAMAGE]     = {45007, 45008},
    [COMBAT_ICEDAMAGE]      = {45009, 45010},
    [COMBAT_HOLYDAMAGE]     = {45011, 45012},
    [COMBAT_DEATHDAMAGE]    = {45013, 45014}
}

local buff_potions = {
    --[itemid] = {damageType, buffAmount, buffTimeInSeconds, damageTypeText}
    [1111] = {COMBAT_PHYSICALDAMAGE, 30, 60, "physical"},
    [2222] = {COMBAT_ICEDAMAGE, 30, 60, "ice"},
    [3333] = {COMBAT_HOLYDAMAGE, 30, 60, "holy"}
}

local buffPotions = Action()

function buffPotions.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local index, cur_time = buff_potions[item.itemid], os.time()
    local buff_timer = cur_time + index[3]
    local playerPosition = player:getPosition()
  
    -- if a buff of equal or greater damage is currently active, don't let new buff activate.
    if player:getStorageValue(damageTypes[index[1]][2]) > cur_time then
        if player:getStorageValue(damageTypes[index[1]][1]) >= index[2] then
            playerPosition:sendMagicEffect(CONST_ME_POFF, player)
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "A buff of this damage type (" .. index[4] .. ") is still active.")
            return true
        end
    end

    player:setStorageValue(damageTypes[index[1]][1], index[2])
    player:setStorageValue(damageTypes[index[1]][2], buff_timer)
    playerPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "" .. (index[4]:gsub("^%l", string.upper)) .. " damage increased by " .. index[2] .. " for " .. index[3] .. " seconds.")
    item:remove(1)
    return true
end

for k, v in pairs(buff_potions) do
    buffPotions:id(k) -- adds all itemids from table
end
buffPotions:register()


local function damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, playerid)
    local player = Player(playerid)
  
    if damageTypes[primaryType] then
        local damageValue = player:getStorageValue(damageTypes[primaryType][1])
        local additionalDamage = damageValue > 0 and damageValue or 0
        primaryDamage = primaryDamage + additionalDamage
    end
  
    if damageTypes[secondaryType] then
        local damageValue = player:getStorageValue(damageTypes[secondaryType][1])
        local additionalDamage = damageValue > 0 and damageValue or 0
        secondaryDamage = secondaryDamage + additionalDamage
    end
  
    return primaryDamage, secondaryDamage
end

local healthChange = CreatureEvent("onHealthChange_damage_buff_potion")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not Player(attacker) then
        return true
    end
    local attacker_id = attacker:getId()
    primaryDamage, secondaryDamage = damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, attacker_id)
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()


local manaChange = CreatureEvent("onManaChange_damage_buff_potion")

function manaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not Player(attacker) then
        return true
    end
    local attacker_id = attacker:getId()
    primaryDamage, secondaryDamage = damageCalculator(primaryDamage, primaryType, secondaryDamage, secondaryType, attacker_id)
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

manaChange:register()


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

function loginEvent.onLogin(player)
    player:registerEvent("onHealthChange_damage_buff_potion")
    player:registerEvent("onManaChange_damage_buff_potion")
    return true
end

loginEvent:register()
I don't have the scripts folder, shud I do it as an action and register the event inside login.lua?
 
I don't have the scripts folder, shud I do it as an action and register the event inside login.lua?
If you're not using TFS 1.3, then yes, you'd need to separate it into all of the separate events.

onUse, onHealthChange, onManaChange, onLogin
 
If you're not using TFS 1.3, then yes, you'd need to separate it into all of the separate events.

onUse, onHealthChange, onManaChange, onLogin
im am using 1.3 but I don't have some of the latest pushs.
I manage to do it just one problem dude

right here:
Lua:
local buffPotions = Action()

function buffPotions.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local index, cur_time = buff_potions[item.itemid], os.time()
    local buff_timer = cur_time + index[3]
    local playerPosition = player:getPosition()
  
    -- if a buff of equal or greater damage is currently active, don't let new buff activate.
    if player:getStorageValue(damageTypes[index[1]][2]) > cur_time then
        if player:getStorageValue(damageTypes[index[1]][1]) >= index[2] then
            playerPosition:sendMagicEffect(CONST_ME_POFF, player)
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "A buff of this damage type (" .. index[4] .. ") is still active.")
            return true
        end
    end

    player:setStorageValue(damageTypes[index[1]][1], index[2])
    player:setStorageValue(damageTypes[index[1]][2], buff_timer)
    playerPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "" .. (index[4]:gsub("^%l", string.upper)) .. " damage increased by " .. index[2] .. " for " .. index[3] .. " seconds.")
    item:remove(1)
    return true
end

for k, v in pairs(buff_potions) do
    buffPotions:id(k) -- adds all itemids from table
end
buffPotions:register()

is there another way to do the action.onuse function?
unknown.png

my server is not recognizing Action()
 
im am using 1.3 but I don't have some of the latest pushs.
I manage to do it just one problem dude

right here:
Lua:
local buffPotions = Action()

function buffPotions.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local index, cur_time = buff_potions[item.itemid], os.time()
    local buff_timer = cur_time + index[3]
    local playerPosition = player:getPosition()
 
    -- if a buff of equal or greater damage is currently active, don't let new buff activate.
    if player:getStorageValue(damageTypes[index[1]][2]) > cur_time then
        if player:getStorageValue(damageTypes[index[1]][1]) >= index[2] then
            playerPosition:sendMagicEffect(CONST_ME_POFF, player)
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "A buff of this damage type (" .. index[4] .. ") is still active.")
            return true
        end
    end

    player:setStorageValue(damageTypes[index[1]][1], index[2])
    player:setStorageValue(damageTypes[index[1]][2], buff_timer)
    playerPosition:sendMagicEffect(CONST_ME_MAGIC_RED)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "" .. (index[4]:gsub("^%l", string.upper)) .. " damage increased by " .. index[2] .. " for " .. index[3] .. " seconds.")
    item:remove(1)
    return true
end

for k, v in pairs(buff_potions) do
    buffPotions:id(k) -- adds all itemids from table
end
buffPotions:register()

is there another way to do the action.onuse function?
unknown.png

my server is not recognizing Action()
yes u do not have revscripts you need to use it like a normal action event
 
I'll look into it, but no promises. xD

Request as many as you like.
I won't guarantee that I can do them all though.

as per main post.. VV
Sorry.


Can you please explain what you want the script to do?
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
 
Additional unique drop system: (not sure if can be done in pure lua but most likely yes, if no just scrap that idea ;p)

  • After killing monster it will roll additional item with possibility to not roll additional item from this system.
  • Possibility to add different sets of items in tiers for each monster
  • First rolling Tier of the item from 1 to x where 1 is the rarest
  • 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 )
  • After all of this send message to player that he just got additional tier x drop
  • This additional item can be inside the corpse or give to the player container its whatever u would prefer
 
Last edited:
Lua:
function onStepIn(cid, item, position, fromPosition)
for i = 17000, 18015 do
local pos = getThingPos(i)
if not isPlayer(getTopCreature(pos).uid) then
doTeleportThing(cid, pos)
doCreatureSay(cid, 'Training time!.', TALKTYPE_ORANGE_1, false, cid)
doSendMagicEffect(position, CONST_ME_TELEPORT)
doSendMagicEffect(pos, CONST_ME_TELEPORT)
return true
end
end
doTeleportThing(cid, fromPosition, true)
doCreatureSay(cid, 'All training slots are taken', TALKTYPE_ORANGE_1, false, cid)
doSendMagicEffect(fromPosition, CONST_ME_TELEPORT)
end


Code:
function onStepIn(cid, item, pos)
 Player = getPlayerPosition(cid)
    NorthWest = {x=Player.x-1, y=Player.y-1, z=Player.z}
    NorthEast = {x=Player.x+1, y=Player.y-1, z=Player.z}
    doSummonCreature("Target", NorthWest)
    doSummonCreature("Target", NorthEast)
    end

function onStepOut(cid, item, frompos, pos)
local remove = {
[1] = {x=frompos.x-1, y=frompos.y-1, z=frompos.z, stackpos=255},
[2] = {x=frompos.x+1, y=frompos.y-1, z=frompos.z, stackpos=255}
}
for i = 1, #remove do
    doRemoveCreature(getThingfromPos(remove[i]).uid)
end

return 1
end

i used this in 0.4 but no good one for 1.3
 
Status
Not open for further replies.
Back
Top