• 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
Joined
Nov 17, 2010
Messages
6,903
Solutions
589
Reaction score
5,531
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:
A script for a boss that randomly creates two different effects on tiles. When a player steps into these tiles/effects, one effect gives extra damage for a duration, and the other effect gives extra protection for a duration, both against that boss only.Then effect disappear so only 1 player can step into it.
effect example:

boss d.png
effect shows with a chance
 
I'm glad you're back. I'd like to ask a favor: create a script that, when the player uses the ring and dies, it removes the ring and is revived after about 5 seconds. Of course, upon dying and reviving, they would lose levels and skills normally, as it happens when dying in the usual way. If you could create a script for me, I would appreciate it. I'm using TFS 1.4.2, and it can be in revscripts. 😁
 
I'm glad you're back. I'd like to ask a favor: create a script that, when the player uses the ring and dies, it removes the ring and is revived after about 5 seconds. Of course, upon dying and reviving, they would lose levels and skills normally, as it happens when dying in the usual way. If you could create a script for me, I would appreciate it. I'm using TFS 1.4.2, and it can be in revscripts. 😁

If you really want to kill the player first then u prob need source edit or maybe it'll work with onpreparedeath

edit: nvm should work
 
Last edited:
As an old school mapper who knew little about scripting i always felt basic confugrable "quest scripts" were a thing that were hard to come by. You could extract them out of other quests and scripts but a nice modern up to date generic set of quest scripts would be a cool thng to see & would go along way with newer people imo. Either you do one or a small "pack" either is fine.

  • Place X items on X Squares & Remove X walls/Objects
  • Flick Levers Remove Walls/Objects
  • Use X items on X objects to open a door
  • X Players Click X objects within X time to remove X walls/objects
  • X Players stand in X position to remove X walls/objects
  • Activae X levers in X seqence to remove walls/objects
  • Give NPC X Item and get X storage
 
Wave spell that is based on three animations so starting/middle/ending for example what i mean is firstly it would execute starting effect once that effect ends it starts middle effect, after middle ends it starts ending effect so its like seamless one spell effect just combined from three sprites
 
A script for a boss that randomly creates two different effects on tiles. When a player steps into these tiles/effects, one effect gives extra damage for a duration, and the other effect gives extra protection for a duration, both against that boss only.Then effect disappear so only 1 player can step into it.
effect example:

View attachment 81593
effect shows with a chance

Hey, hope you enjoy it. :)
This ended up being more complex then I originally expected. xD

bossTileEffectBuffs.gif

data/events/events.xml -- make sure onSpawn is enabled
XML:
<event class="Monster" method="onSpawn" enabled="1" />
data/lib/core/core.lua
LUA:
dofile('data/lib/core/xikiniCustomFunctions.lua')
data/lib/core/xikiniCustomFunctions.lua
LUA:
--[[ quick reference of events

    CREATURE_EVENT_NONE
    CREATURE_EVENT_LOGIN
    CREATURE_EVENT_LOGOUT
    CREATURE_EVENT_THINK
    CREATURE_EVENT_PREPAREDEATH
    CREATURE_EVENT_DEATH
    CREATURE_EVENT_KILL
    CREATURE_EVENT_ADVANCE
    CREATURE_EVENT_MODALWINDOW
    CREATURE_EVENT_TEXTEDIT
    CREATURE_EVENT_HEALTHCHANGE
    CREATURE_EVENT_MANACHANGE
    CREATURE_EVENT_EXTENDED_OPCODE
]]--

function Player:hasEvent(type, name)
    for k, v in pairs(self:getEvents(type)) do
        if v == name then
            return true
        end
    end
    return false
end
data/scripts/bossTileEffectBuffs.lua
LUA:
local buffs = {
--    [actionId]
    [45007] = {
        tileSpawnShootEffect = CONST_ANI_FIRE,
        tileEffects = {
            CONST_ME_TUTORIALARROW, 
            CONST_ME_TUTORIALSQUARE,
            CONST_ME_HEARTS
        },
        buff = {
            tileDuration = 10, -- seconds (how long the tile remains 'active' before disappearing)
            effect = "damage mitigation",
            duration = 30, -- seconds
            percent = 80   -- 1-100%
        }
    },
    [45008] = {
        tileSpawnShootEffect = CONST_ANI_SUDDENDEATH,
        tileEffects = {
            CONST_ME_TUTORIALARROW, 
            CONST_ME_TUTORIALSQUARE,
            CONST_ME_MORTAREA
        },
        buff = {
            tileDuration = 10,
            effect = "damage increase",
            duration = 30,
            percent = 300  -- 100 = double damage
        }
    }
}

local bosses = {
    ["rat"] = { -- keep names all lowercase
        {
            actionIds = {45007, 45008}, -- actionIds from buffs table
            interval = 3, -- how often it attempts to spawn a buffTile (seconds)
            chance = 100,
            spawnDistance = 7, -- how far away from boss they can spawn
            requireLineOfSight = true, -- basically, can a buff spawn behind a wall?
            location = {
                from = Position(995, 995, 7), -- top left corner -- only registers event to bosses that spawn in this area
                to =   Position(1005, 1005, 7)    -- bottom right corner
            }
        },
--        { -- 2nd boss location with same name
--            actionIds = {11111, 22222},
--            interval = 5,
--            chance = 30,
--            spawnDistance = 7,
--            requireLineOfSight = true,
--            location = {
--                from = Position(1000, 1000, 7),
--                to =   Position(1001, 1001, 7)
--            }
--        }
    },
--    ["some other boss"] = {
--        {
--            actionIds = {11111, 22222},
--            interval = 5,
--            chance = 30,
--            spawnDistance = 7,
--            requireLineOfSight = true,
--            location = {
--                from = Position(1000, 1000, 7),
--                to =   Position(1001, 1001, 7)
--            }
--        }
--    }
}

-- END OF CONFIG --
-- Don't modify below --

local bossTracker = {
--    [bossId] = {index = i, thinkTimer = 0}
}

local activeBossBuffs = {
--    [bossId] = {
--        [playerId] = {
--            {receivedAt = os.mtime(), actionId = 11111}
--        }
--    }
}

local buffedTiles = {
--    [Position(1000, 1000, 7)] = {bossId = 1111, receivedAt = os.mtime()}
}

local function getRandomCircularOffset(maxDistance)
    local angle = math.random() * 2 * math.pi
    local radius = math.random() * maxDistance
    local offsetX = math.floor(radius * math.cos(angle) + 0.5)
    local offsetY = math.floor(radius * math.sin(angle) + 0.5)
    return offsetX, offsetY
end

local function resetTileActionId(position)
    local tile = Tile(position)
    if not tile then
        return
    end
    local ground = tile:getGround()
    if not ground then
        return
    end
    ground:removeAttribute(ITEM_ATTRIBUTE_ACTIONID)
end

local function tileChecker(position, actionId)
    local tileIndex = buffedTiles[position]
    if not tileIndex then
        resetTileActionId(position)
        return
    end
    
    local boss = Creature(tileIndex.bossId)
    if not boss then
        resetTileActionId(position)
        buffedTiles[position] = nil
        return
    end
    
    local index = buffs[actionId]
    if os.mtime() > tileIndex.receivedAt + (1000 * index.buff.tileDuration) then
        resetTileActionId(position)
        buffedTiles[position] = nil
        return true
    end
    
    for i = 1, #index.tileEffects do
        position:sendMagicEffect(index.tileEffects[i])
    end
    
    addEvent(tileChecker, 1000, position, actionId)
end

local function createBuffTile(bossId, bossIndex, actionId)
    local boss = Creature(bossId)
    if not boss then
        return
    end
    
    local bossPosition = boss:getPosition()
    for i = 1, 20 do
        local offsetX, offsetY = getRandomCircularOffset(bossIndex.spawnDistance)
        local x = bossPosition.x + offsetX
        local y = bossPosition.y + offsetY
        local targetPosition = Position(x, y, bossPosition.z)
        
        local tile = Tile(targetPosition)
        if tile and tile:isWalkable() then
            local ground = tile:getGround()
            if ground:getActionId() == 0 then
                local topVisibleCreature = tile:getTopVisibleCreature(boss)
                if not topVisibleCreature or not topVisibleCreature:isPlayer() then
                    if not bossIndex.requireLineOfSight or bossPosition:isSightClear(targetPosition) then
                        ground:setActionId(actionId)
                        bossPosition:sendDistanceEffect(targetPosition, buffs[actionId].tileSpawnShootEffect)
                        buffedTiles[targetPosition] = {bossId = boss:getId(), receivedAt = os.mtime()}
                        tileChecker(targetPosition, actionId)
                        return
                    end
                end
            end
        end
    end
end


local function calculateDamage(damage, damageType, percent, buffType)
    if damageType ~= 0 then
        if buffType == "damage mitigation" then
            return damage - (damage * (percent / 100))
        else
            return damage * ((percent + 100) / 100)
        end
    end
    return damage
end

local function damageCalculator(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType)
    local bossId = creature:isMonster() and creature:getId() or attacker:isMonster() and attacker:getId() or 0
    local index = activeBossBuffs[bossId]
    if index then
        local playerId = creature:isPlayer() and creature:getId() or attacker:isPlayer() and attacker:getId() or 0
        index = index[playerId]
        if index then
            local currentTime = os.mtime()
            local percent = 0
            local buffType = creature:isPlayer() and "damage mitigation" or "damage increase"
            -- loop through all buffs and find highest percent
            for i = #index, 1, -1 do
                local buff = buffs[index[i].actionId].buff
                if (buff.duration * 1000) + index[i].receivedAt > currentTime then
                    if buffType == buff.effect then
                        percent = percent < buff.percent and buff.percent or percent
                    end
                else
                    table.remove(index, i) -- remove inactive buffs
                end
            end
            if percent > 0 then
                primaryDamage = calculateDamage(primaryDamage, primaryType, percent, buffType)
                secondaryDamage = calculateDamage(secondaryDamage, secondaryType, percent, buffType)
            end
        end
    end
    return primaryDamage, secondaryDamage
end


local healthChange = CreatureEvent("onHealthChange_bossTileEffectBuffs")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    primaryDamage, secondaryDamage = damageCalculator(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType)
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()


local manaChange = CreatureEvent("onManaChange_bossTileEffectBuffs")

function manaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    primaryDamage, secondaryDamage = damageCalculator(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType)
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

manaChange:register()

local creatureevent = CreatureEvent("onDeath_bossTileEffectBuffs")

function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
    -- check if all bosses are dead
    local playerIds = {}
    for bossId, players in pairs(activeBossBuffs) do
        local creature = Creature(bossId)
        if creature then
            return true
        end
        for playerId, _ in pairs(players) do
            playerIds[playerId] = 0
        end
    end
    
    -- all bosses confirmed dead
    
    -- remove registered events from players
    for playerId, _ in pairs(playerIds) do
        local player = Player(playerId)
        if player then
            player:unregisterEvent("onHealthChange_bossTileEffectBuffs")
            player:unregisterEvent("onManaChange_bossTileEffectBuffs")
        end
    end
    
    -- remove any remaining active tiles
    for position, _ in pairs(buffedTiles) do
        local tile = Tile(position)
        if tile then
            local ground = tile:getGround()
            ground:removeAttribute(ITEM_ATTRIBUTE_ACTIONID)
        end
    end
    
    -- and reset all tables
    bossTracker = {}
    activeBossBuffs = {}
    buffedTiles = {}
    return true
end

creatureevent:register()


local creatureevent = CreatureEvent("onThink_bossTileEffectBuffs")

function creatureevent.onThink(creature, interval)
    local bossId = creature:getId()
    
    -- have to add this here, because onSpawn doesn't let you get the creatures Id, because it hasn't been created yet.. fully.  idk lol
    if not bossTracker[bossId] then
        local index = bosses[creature:getName():lower()]
        if index then
            local position = creature:getPosition()
            for i = 1, #index do
                if position:isInRange(index[i].location.from, index[i].location.to) then
                    bossTracker[creature:getId()] = {index = i, thinkTimer = 0}
                    break
                end
            end
        end
    end
    
    local bossIndex = bosses[creature:getName():lower()][bossTracker[bossId].index]
    
    bossTracker[bossId].thinkTimer = bossTracker[bossId].thinkTimer + interval
    if bossTracker[bossId].thinkTimer >= bossIndex.interval * 1000 then
        bossTracker[bossId].thinkTimer = bossTracker[bossId].thinkTimer - (bossIndex.interval * 1000)
        if math.random(100) <= bossIndex.chance then
            local actionId = bossIndex.actionIds[math.random(#bossIndex.actionIds)]
            createBuffTile(bossId, bossIndex, actionId)
        end
    end
    return true
end

creatureevent:register()


local moveevent = MoveEvent()

function moveevent.onStepIn(creature, item, position, fromPosition)
    if not isPlayer(creature:getId()) then
        return true
    end
    
    local tileActionId = item:getActionId()
    local index = buffs[tileActionId]
    item:removeAttribute(ITEM_ATTRIBUTE_ACTIONID)
    
    if not index then
        print("Error: ActionId not in table. (" .. tileActionId .. ")") -- shouldn't be possible.. but :shrug
        return true
    end
    
    -- work-around to ensure position tables are the same.
    for k, v in pairs(buffedTiles) do
        if position.x == k.x and position.y == k.y and position.z == k.z then
            position = k
        end
    end
    
    if not buffedTiles[position] then
        return true
    end
    
    local boss = Creature(buffedTiles[position].bossId)
    if not boss then
        buffedTiles[position] = nil
        return true
    end
    
    local currentTime = os.mtime()
    if currentTime > buffedTiles[position].receivedAt + (1000 * index.buff.tileDuration) then
        buffedTiles[position] = nil
        return true
    end
    
    local bossId = buffedTiles[position].bossId
    if not activeBossBuffs[bossId] then
        activeBossBuffs[bossId] = {}
    end
    
    local playerId = creature:getId()
    if not activeBossBuffs[bossId][playerId] then
        if not creature:hasEvent(CREATURE_EVENT_HEALTHCHANGE, "onHealthChange_bossTileEffectBuffs") then
            creature:registerEvent("onHealthChange_bossTileEffectBuffs")
        end
        if not creature:hasEvent(CREATURE_EVENT_MANACHANGE, "onManaChange_bossTileEffectBuffs") then
            creature:registerEvent("onManaChange_bossTileEffectBuffs")
        end
        activeBossBuffs[bossId][playerId] = {}
    end
    
    table.insert(activeBossBuffs[bossId][playerId], {receivedAt = currentTime, actionId = tileActionId})
    buffedTiles[position] = nil
    creature:say(buffs[tileActionId].buff.effect .. "\n" .. buffs[tileActionId].buff.duration .. " seconds", TALKTYPE_MONSTER_SAY)
    return true
end

for actionId, _ in pairs(buffs) do
    moveevent:aid(actionId)
end
moveevent:register()


local eventCallback = EventCallback

function eventCallback.onSpawn(creature, position, startup, artificial)
    local index = bosses[creature:getName():lower()]
    if index then
        for i = 1, #index do
            if position:isInRange(index[i].location.from, index[i].location.to) then
                creature:registerEvent("onDeath_bossTileEffectBuffs")
                creature:registerEvent("onHealthChange_bossTileEffectBuffs")
                creature:registerEvent("onThink_bossTileEffectBuffs")
                return true
            end
        end
    end
    return true
end

eventCallback:register(-666)
 
Last edited:
Markets
Something that has been in my mind for a long, long time..
Counters that act like "market stands" if that makes any sense.

So essentially you could have a few spots in a city assigned for players to be able to sell their items "afk"
without the need for a house or some non-immersive market in Depotbox.

4d945776478ed558604f59ff78c760da.jpg


I want to let players open a sort of market
- The seller places an item on the Counter, perhaps using an Auction Hammer on it and an "amount" window will be displayed where the seller states the sell price.
OR could create a container inside the Counter and then the seller uses a hammer on the Counter.
- The item will be put for sale for a certain amount of time let's say two hours (this can be put on the Auction Hammer?),
perhaps the price and ending time could be displayed on top of the item or on onLook.

  • If the owner of the item moves the item, the item will be removed from the "market" (perhaps with a confirmation message)
  • If a buyer moves the item, the item will be "sold" and it will take money from the player. (perhaps with a confirmation message)
  • If item is bought the gold is send to sellers bank account.
  • If the seller logs out the item will be taken off the market and send to depot.

Is this even possible with just storage and no database queries? 🤔
0d0ed91e2707be77acc48a3cce3a0f58.png

------

EDIT: Perhaps it would be more immersive if you can perhaps ask a NPC that runs the market for you 🤔
So behind the market stall there is an NPC that will do the actions for you?
 
Last edited:
I'm glad you're back. I'd like to ask a favor: create a script that, when the player uses the ring and dies, it removes the ring and is revived after about 5 seconds. Of course, upon dying and reviving, they would lose levels and skills normally, as it happens when dying in the usual way. If you could create a script for me, I would appreciate it. I'm using TFS 1.4.2, and it can be in revscripts. 😁
Okay, so I've thought about this a lot, and it's basically a nightmare lol

Player having an equipped ring and dies -> simulate death

Lose experience -> find and replicate formula to lose experience.. checking blessings and items.. doable maybe
Lose skills -> same as above
Update Death list? -> unsure if you want that.. but would need to give other players experience possibly? cuz of pvp stuff
Dropping items -> unsure if you want that, probably easy to simulate.. but there would be no body

Then the big crux..
Removing buffs / creature events.. and then reapplying them? -> so many potential conflicts..
We basically need to simulate onLogout and onLogin

--
And then we move onto the really big problem. xD
Making the person stand there, as if they are basically offline and can't do anything.

We need to prevent..
-> the person from attacking
-> the person from follow locking
-> trading
-> items.. moving them around, using them, 'use with', item interaction at distance (source force walking us to attempt to interact)
-> walking and movement
-> talking
-> maybe other stuff?

--
Sorry to say, I really think this is impossible.
 
Okay, so I've thought about this a lot, and it's basically a nightmare lol

Player having an equipped ring and dies -> simulate death

Lose experience -> find and replicate formula to lose experience.. checking blessings and items.. doable maybe
Lose skills -> same as above
Update Death list? -> unsure if you want that.. but would need to give other players experience possibly? cuz of pvp stuff
Dropping items -> unsure if you want that, probably easy to simulate.. but there would be no body

Then the big crux..
Removing buffs / creature events.. and then reapplying them? -> so many potential conflicts..
We basically need to simulate onLogout and onLogin

--
And then we move onto the really big problem. xD
Making the person stand there, as if they are basically offline and can't do anything.

We need to prevent..
-> the person from attacking
-> the person from follow locking
-> trading
-> items.. moving them around, using them, 'use with', item interaction at distance (source force walking us to attempt to interact)
-> walking and movement
-> talking
-> maybe other stuff?

--
Sorry to say, I really think this is impossible.
Without the 5 second thing, you could just create a local table, kill the player and store their guid as the key and the death position
and onLogin check for the guid in the table and teleport to the death position, and ofc, if still exists, remove the ring.

But yeah, the whole effect of it happening would most likely require client changes, or a lot more thought.
 
Respawn at the nearest Respawn Statue/Tavern/Town

Sorry for asking the impossible again, probably going against your rules but it's also something that has been on my mind for quite a long time since traversing on my server will be somewhat hard on my huge-sized map and players getting back to their bodies is a problem I need to overcome.

Upon dying, players now respawn at their home town, but what if they are miles and miles away, it is very discouraging for players to travel such a long distance even if they could teleport their way back to the location through carriages and boats.

To the point:

- My original concept was to let players respawn at the closest Tavern upon dying not their home-town.
OR
- Upon dying players respawn next to an Object with actionid/uniqueid.
This way you can have this Respawn Object at any hunting ground and upon dying, the player spawns very near the place they died at.
Kind of like the Statues in Elden Ring or Bonfires in Dark Souls.

the lord of the rings elise GIF
 
Okay, so I've thought about this a lot, and it's basically a nightmare lol

Player having an equipped ring and dies -> simulate death

Lose experience -> find and replicate formula to lose experience.. checking blessings and items.. doable maybe
Lose skills -> same as above
Update Death list? -> unsure if you want that.. but would need to give other players experience possibly? cuz of pvp stuff
Dropping items -> unsure if you want that, probably easy to simulate.. but there would be no body

Then the big crux..
Removing buffs / creature events.. and then reapplying them? -> so many potential conflicts..
We basically need to simulate onLogout and onLogin

--
And then we move onto the really big problem. xD
Making the person stand there, as if they are basically offline and can't do anything.

We need to prevent..
-> the person from attacking
-> the person from follow locking
-> trading
-> items.. moving them around, using them, 'use with', item interaction at distance (source force walking us to attempt to interact)
-> walking and movement
-> talking
-> maybe other stuff?

--
Sorry to say, I really think this is impossible.
I appreciate your understanding; thank you for your dedicated efforts.

I acquired a foundational script from the PVP arena and subsequently made modifications. Now, both creatures and players have the capability to eliminate me; the demise is simulated, and I undergo revival after a brief 5-second interval. Following a span of several days, I discerned that there is no loss of levels or skills. Despite exerting efforts for over two weeks, there has been no tangible progress—quite amusing, really. In due course, I am confident that I will attain success; a genuine script is in development.

Furthermore, the Revive system is already in existence, originating from the antiquated Evolution engine crafted by Xiadozu. They incorporated specific codes into the source. I intend to thoroughly investigate this matter and endeavor to integrate it into TFS 1.4.2. I extend my apologies and express gratitude for your ongoing commitment. Undoubtedly, you possess an exceptional level of expertise, standing out as a luminary within the Otland community. I am profoundly thankful for all your contributions.

kindly review the GIF to observe the outcome of the script; it is a somewhat improvised rendition. 🙂
 
Last edited:
Good evening my dear, it's great to see collaborations like this!
I've been thinking about the following for a few days, my server is customized and I have 3 evolutions for each vocation, I would like: players with vocation 13 to 16, when they kill players with vocation 1 to 5, players with vocation 1 to 5 return to the temple position 1000 1000 7, without suffering any damage, as if it were a bit of a teleportation, and the killing player (vocation 13 to 16) does not receive any frag, or skull... it seems like a complex, would it be possible? Thank you very much in advance!
 
Alright, Let's try to respond to everyone here so we're all on the same page. :)

I can't edit posts because I don't have premium account on OtLand lol.

can you do a script killing a monster gives random 10% extra loot chance or 10% extra exp for 30 minutes and broadcast message
Doable. Added onto the ToDo list.

As an old school mapper who knew little about scripting i always felt basic confugrable "quest scripts" were a thing that were hard to come by. You could extract them out of other quests and scripts but a nice modern up to date generic set of quest scripts would be a cool thng to see & would go along way with newer people imo. Either you do one or a small "pack" either is fine.

  • Place X items on X Squares & Remove X walls/Objects
  • Flick Levers Remove Walls/Objects
  • Use X items on X objects to open a door
  • X Players Click X objects within X time to remove X walls/objects
  • X Players stand in X position to remove X walls/objects
  • Activae X levers in X seqence to remove walls/objects
  • Give NPC X Item and get X storage
All Doable.
I'll make them as a pack of single-use scripts, so people can just copy-paste the files, as they need more of them.
Added onto the ToDo list.

Wave spell that is based on three animations so starting/middle/ending for example what i mean is firstly it would execute starting effect once that effect ends it starts middle effect, after middle ends it starts ending effect so its like seamless one spell effect just combined from three sprites
This is mostly a timing issue with an addEvent.
There's no way to get the animation length via Lua function calls, so it's just trial and error until it looks seamless.
Added onto the ToDo list.

Markets
Something that has been in my mind for a long, long time..
Counters that act like "market stands" if that makes any sense.

So essentially you could have a few spots in a city assigned for players to be able to sell their items "afk"
without the need for a house or some non-immersive market in Depotbox.

4d945776478ed558604f59ff78c760da.jpg


I want to let players open a sort of market
- The seller places an item on the Counter, perhaps using an Auction Hammer on it and an "amount" window will be displayed where the seller states the sell price.
OR could create a container inside the Counter and then the seller uses a hammer on the Counter.
- The item will be put for sale for a certain amount of time let's say two hours (this can be put on the Auction Hammer?),
perhaps the price and ending time could be displayed on top of the item or on onLook.

  • If the owner of the item moves the item, the item will be removed from the "market" (perhaps with a confirmation message)
  • If a buyer moves the item, the item will be "sold" and it will take money from the player. (perhaps with a confirmation message)
  • If item is bought the gold is send to sellers bank account.
  • If the seller logs out the item will be taken off the market and send to depot.

Is this even possible with just storage and no database queries? 🤔
0d0ed91e2707be77acc48a3cce3a0f58.png

------

EDIT: Perhaps it would be more immersive if you can perhaps ask a NPC that runs the market for you 🤔
So behind the market stall there is an NPC that will do the actions for you?
Talked in private.
The idea being a lever + blackboard setup inside of a house, that would allow for house owner to set the price on the blackboard, and be able to sell the 'top most visible item'.
Untitled.png
Added onto the ToDo list.

Without the 5 second thing, you could just create a local table, kill the player and store their guid as the key and the death position
and onLogin check for the guid in the table and teleport to the death position, and ofc, if still exists, remove the ring.

But yeah, the whole effect of it happening would most likely require client changes, or a lot more thought.
Yeah, making a 'teleport to where I died' script is possible. xD
But was not the original request.

I appreciate your understanding; thank you for your dedicated efforts.

I acquired a foundational script from the PVP arena and subsequently made modifications. Now, both creatures and players have the capability to eliminate me; the demise is simulated, and I undergo revival after a brief 5-second interval. Following a span of several days, I discerned that there is no loss of levels or skills. Despite exerting efforts for over two weeks, there has been no tangible progress—quite amusing, really. In due course, I am confident that I will attain success; a genuine script is in development.

Furthermore, the Revive system is already in existence, originating from the antiquated Evolution engine crafted by Xiadozu. They incorporated specific codes into the source. I intend to thoroughly investigate this matter and endeavor to integrate it into TFS 1.4.2. I extend my apologies and express gratitude for your ongoing commitment. Undoubtedly, you possess an exceptional level of expertise, standing out as a luminary within the Otland community. I am profoundly thankful for all your contributions.

kindly review the GIF to observe the outcome of the script; it is a somewhat improvised rendition. 🙂
I have a feeling that this either requires source edits, or doesn't solve for any of the problems I listed earlier.
Sorry bud.

Respawn at the nearest Respawn Statue/Tavern/Town

Sorry for asking the impossible again, probably going against your rules but it's also something that has been on my mind for quite a long time since traversing on my server will be somewhat hard on my huge-sized map and players getting back to their bodies is a problem I need to overcome.

Upon dying, players now respawn at their home town, but what if they are miles and miles away, it is very discouraging for players to travel such a long distance even if they could teleport their way back to the location through carriages and boats.

To the point:

- My original concept was to let players respawn at the closest Tavern upon dying not their home-town.
OR
- Upon dying players respawn next to an Object with actionid/uniqueid.
This way you can have this Respawn Object at any hunting ground and upon dying, the player spawns very near the place they died at.
Kind of like the Statues in Elden Ring or Bonfires in Dark Souls.

the lord of the rings elise GIF
again, spoke in private to confirm details.

Will be making a tavern and respawn anchor system.
When you die, if you are inside of a respawn achor area, you'll respawn to that anchor.
If not in any respawn anchor area's, then respawn at closest tavern.
In the unlikely scenario that 2 taverns are equally close, it will respawn you at the first tavern found in the list of taverns.

Good evening my dear, it's great to see collaborations like this!
I've been thinking about the following for a few days, my server is customized and I have 3 evolutions for each vocation, I would like: players with vocation 13 to 16, when they kill players with vocation 1 to 5, players with vocation 1 to 5 return to the temple position 1000 1000 7, without suffering any damage, as if it were a bit of a teleportation, and the killing player (vocation 13 to 16) does not receive any frag, or skull... it seems like a complex, would it be possible? Thank you very much in advance!
Very doable. I will just prevent the death entirely, heal the player and teleport them to their home temple.
I assume this works for each evolution?

Tier 1, can kill anyone.
Tier 2, can kill tier 2 and tier 3. If kills tier 1, tier 1 goes to temple.
Tier 3, can only kill tier 3. If kills tier 1 or 2, they go to temple?

--
Thanks for all the replies guys.
I'll do my best. :)
 
Hello!
Need a script something like miniworld changes but....

The idea is that there will be several teleports in different places on the map.
If a player will have a party with a minimum of 1 person and it will be in the player's range then the player will be able to enter the teleport the same way the person who is in the party.
If he loses this party or the person will not be in range to the party expshare for, for example, 10 minutes then it throws both people out of the party to a certain position.
In addition, the teleport can always work if the player has the given storage.

Well, and one more point... Teleports are activated randomly, for example, a maximum of 3 different for one day, after 24 hours access for players is closed and opens another random 3 portals.

+ Some information which places are currently active.
 
I would like to request assistance with another matter. I have attempted to create a script but was unable to finalize it due to my limited expertise, particularly in modal window implementation. I kindly ask for your assistance in reviewing and rectifying any deficiencies in the script. Allow me to provide an explanation of how this system operates. The Teleport-Pos feature enables the saving of up to three coordinates, which can then be accessed from different locations. Upon clicking the Teleport-Pos item, a modal window for Teleport Coordinates will appear, facilitating the saving of multiple positions. Unlike standard teleportation methods, this feature ensures reliability and does not compromise the integrity of the coordinates. Additionally, manual removal of coordinates is possible should the need arise for replacement. Upon successfully saving a coordinate, a confirmation message will indicate 'positions saved'. To utilize the saved positions, simply select the desired one and click 'go'. This functionality streamlines the process of navigating to previously saved locations. I would greatly appreciate any assistance you can provide in this matter.


Upon using the item, a modal window appears, but it does not save the coordinates. There may be something missing, I'm not sure
LUA:
local BUTTON_SAVE = 100
local BUTTON_TELEPORT = 101
local BUTTON_CANCEL = 102

local TELEPORT_STORAGE = 54646
local KEY_PREFIX = "TeleportPos_"
local MAX_POSITIONS = 3

function createTeleportModal(player)
    local modal = ModalWindow(100, "Teleport-Pos", "Choose a position to teleport:")
    modal:addButton(BUTTON_SAVE, "Save")
    modal:addButton(BUTTON_TELEPORT, "Teleport")
    modal:addButton(BUTTON_CANCEL, "Cancel")

    for i = 1, MAX_POSITIONS do
        local coordinates = getSavedCoordinates(player, i)
        if coordinates then
            modal:addChoice(i, "Position " .. i .. ": (" .. coordinates.x .. ", " .. coordinates.y .. ", " .. coordinates.z .. ")")
        end
    end

    modal:setDefaultEnterButton(BUTTON_TELEPORT)
    modal:setDefaultEscapeButton(BUTTON_CANCEL)

    modal:sendToPlayer(player)
end

local tpModal = CreatureEvent("Teleport-Pos")

function tpModal.onModalWindow(player, modalWindowId, buttonId, choiceId)
    if modalWindowId == 100 then
        if buttonId == BUTTON_SAVE then
            local x, y, z = player:getPosition().x, player:getPosition().y, player:getPosition().z
            if saveCoordinates(player, choiceId, {x = x, y = y, z = z}) then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Position saved successfully!")
            else
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Failed to save the position.")
            end
        elseif buttonId == BUTTON_TELEPORT then
            local coordinates = getSavedCoordinates(player, choiceId)
            if coordinates then
                tpBack(player, nil, nil, nil, nil)
            else
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Position not found.")
            end
        elseif buttonId == BUTTON_CANCEL then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Action canceled.")
        end
    end
end

tpModal:register()

local tp = Action()


function tp.onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)
    createTeleportModal(player)
    return true
end


function saveCoordinates(player, index, coordinates)
    if index > 0 and index <= MAX_POSITIONS then
        player:setStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_x", coordinates.x)
        player:setStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_y", coordinates.y)
        player:setStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_z", coordinates.z)
        return true
    end
    return false
end


function getSavedCoordinates(player, index)
    if index > 0 and index <= MAX_POSITIONS then
        local x = player:getStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_x")
        local y = player:getStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_y")
        local z = player:getStorageValue(TELEPORT_STORAGE, KEY_PREFIX .. index .. "_z")
        if x ~= nil and y ~= nil and z ~= nil then
            return {x = x, y = y, z = z}
        end
    end
    return nil
end

tp:id(39557)
tp:register()
 
can you do a script killing a monster gives random 10% extra loot chance or 10% extra exp for 30 minutes and broadcast message

BonusLootorExperience.gif

register it to the monster inside of the monster file
XML:
    <script>
        <event name="onDeath_BonusLootorExperience" />
    </script>

in data\scripts\eventcallbacks\monster\default_onDropLoot.lua
replace the entire code with this
LUA:
local ec = EventCallback

ec.onDropLoot = function(self, corpse)
    if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
        return
    end

    local player = Player(corpse:getCorpseOwner())
    local mType = self:getType()
    if not player or player:getStamina() > 840 then
        local boostedLootMultiplier = player and player:getStorageValue(GLOBAL_BonusLootorExperience.loot) > os.time() and 1 + (GLOBAL_BonusLootorExperience.lootBoost / 100) or 1
        local monsterLoot = mType:getLoot()
        for i = 1, #monsterLoot do
            if monsterLoot[i].chance then
                monsterLoot[i].chance = math.min(monsterLoot[i].chance * boostedLootMultiplier, MAX_LOOTCHANCE)
            end
            local item = corpse:createLootItem(monsterLoot[i])
            if not item then
                print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
            end
        end

        if player then
            local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
            local party = player:getParty()
            if party then
                party:broadcastPartyLoot(text)
            else
                player:sendTextMessage(MESSAGE_LOOT, text)
            end
        end
    else
        local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
        local party = player:getParty()
        if party then
            party:broadcastPartyLoot(text)
        else
            player:sendTextMessage(MESSAGE_LOOT, text)
        end
    end
end

ec:register()
and make another file in data/scripts somewhere and name it BonusLootorExperience.lua
paste this code
LUA:
GLOBAL_BonusLootorExperience = {
    experience = 45009,
    experienceBoost = 10, -- percent
    experienceTimer = 30, -- minutes
    loot = 45010,
    lootBoost = 10, -- percent
    lootTimer = 30 -- minutes
}


local ec = EventCallback

ec.onGainExperience = function(self, source, exp, rawExp)
    if not source:isMonster() then
        return exp
    end
    if self:getStorageValue(GLOBAL_BonusLootorExperience.experience) > os.time() then
        local percent = 1 + (GLOBAL_BonusLootorExperience.experienceBoost / 100)
        exp = exp * percent
    end
    return exp
end

ec:register()


local creatureevent = CreatureEvent("onDeath_BonusLootorExperience")

function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
    if not isPlayer(killer) then
        return true
    end
    local rand = math.random(2)
    local storageKey = rand == 2 and GLOBAL_BonusLootorExperience.experience or GLOBAL_BonusLootorExperience.loot
    local storageTimer = rand == 2 and GLOBAL_BonusLootorExperience.experienceTimer or GLOBAL_BonusLootorExperience.lootTimer
    killer:setStorageValue(storageKey, os.time() + (60 * storageTimer))
    Game.broadcastMessage(killer:getName() .. " has killed " .. creature:getName() .." and received increased " .. (rand == 2 and "experience" or "loot") .. " for " .. storageTimer .. " minutes!")
    return true
end

creatureevent:register()
 
Back
Top