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

Simple Trap System

Scarlet Ayleid

Advanced OT User
Senator
Joined
Jul 7, 2007
Messages
4,049
Reaction score
238
Hey

I present to you all a simple trap system:
[video=youtube_share;Tnh9JVwj5Hg]

I initially placed 4 traps with 10 seconds delay, then I disabled that delay(so I wouldn't have to change windows all the time) and placed the others to show them working, whenever I stood still was because I was messing around with the controls to make it easy and simple to show everything as fast as possible.
The traps activate either by stepping on them or if they reach the time limit defined in the config
Note: The damage didn't show because since I had a God I was unable to damage normal players, but it does do damage, it also works on monsters and summons!

Code:
local config = {
    itemRequired = 2579, --0 to not require an item
    recoverItem = 2578, --0 to disable
    trapLimit = 3, --0 to disable
    checkInterval = 100, --How often it checks if someone is on the tile, lower values increase accuracy(incase a player  but may increase lag
    timeToActivate = (10 * 1000), --How long until they automatically activate (0 to disable, only activates when stepped, NOT RECOMMENDED because it might generate lag since they will only disappear when someone steps on them!)
timeToDestroyItem = (60 * 1000), -- How long until the item is removed from game if it's not picked up
    types = {
        [1] = function(cid, pos) --Fire Trap
                        doCombatAreaHealth(cid, COMBAT_FIREDAMAGE, pos, nil, 100, 200, CONST_ME_FIREAREA)
                        return true
                    end,
        [2] = function(cid, pos) --Energy Trap
                        doCombatAreaHealth(cid, COMBAT_ENERGYDAMAGE, pos, nil, 100, 200, CONST_ME_ENERGYHIT)
                        return true
                    end,
        [3] = function(cid, pos) --Ice Trap
                        doCombatAreaHealth(cid, COMBAT_ICEDAMAGE, pos, nil, 100, 200, CONST_ME_ICEATTACK)
                        return true
                    end,
        [4] = function(cid, pos) --Earth Trap
                        doCombatAreaHealth(cid, COMBAT_EARTHDAMAGE, pos, nil, 100, 200, CONST_ME_CARNIPHILA)
                        return true
                    end,
        [5] = function(cid, pos) --Fake Demon Trap
                        for i = 1, 8, 1 do
                            local mob = doCreateMonster("Rat", pos)
                            doSetMonsterOutfit(mob, "Demon")
                        end
                        return true
                    end,
        [6] = function(cid, pos) --Blabber Trap
                        local creature = getTopCreature(pos).uid
                        local talks = {
                            "OTLand rocks!", "Scarlet Ayleid sucks!!1!11", "fri itens plzz",
                            "br?", "pl?", "no ks", "hauhauhahuahahua", "help plzz", "pk pk pk pk pk pk",
                            "pandas own", "Rep me++"
                        }
                        doSendMagicEffect(pos, CONST_ME_CRAPS)
                        for i = 1, 20, 1 do
                            addEvent(doCreatureSay, i * 1000, creature, talks[math.random(1, 6)], TALKTYPE_MONSTER)
                        end
                        return true
                    end
    }
}


local players = {
    --[cid] = 0
}

local function removeTrap(pos)
    local item = getTileItemById(pos, config.recoverItem)
    if(item) then
        doRemoveItem(item.uid)
    end
    return true
end

local function activateTrap(cid, pos, trapType)
    if(not isPlayer(cid)) then
        return false
    end
    players[cid] = players[cid] - 1
    config.types[trapType](cid, pos)
    if(config.recoverItem > 0) then
        doCreateItem(config.recoverItem, 1, pos)
        if(config.timeToDestroyItem > 0) then
            addEvent(removeTrap, config.timeToDestroyItem, pos)
        end
    end
    return true
end


local function trapCheck(cid, pos, trapType, timer)
    local creature = getTopCreature(pos).uid
    if(((config.timeToActivate > 0) and (timer >= config.timeToActivate)) or (creature > 0 and (cid ~= creature))) then
        return activateTrap(cid, pos, trapType)
    end
    addEvent(trapCheck, config.checkInterval, cid, pos, trapType, timer + config.checkInterval)
    return true
end


function placeMine(cid, trapType)
    if(config.trapLimit > 0 and players[cid] and players[cid] >= config.trapLimit) then
        sendCancelMessage(cid, "You can only place " .. config.trapLimit .. " traps at once.")
        return false
    end
    local pos = getCreaturePosition(cid)
    if(config.itemRequired == 0 or doPlayerRemoveItem(cid, config.itemRequired, 1)) then
        addEvent(trapCheck, config.checkInterval, cid, pos, trapType, config.checkInterval)
        doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Trap has been placed!")
        doSendMagicEffect(pos, CONST_ME_BLOCKHIT, cid)
        if(players[cid]) then
            players[cid] = players[cid] + 1
        else
            players[cid] = 1
        end
    else
        local itemInfo = getItemInfo(config.itemRequired)
        sendCancelMessage(cid, "You need " .. itemInfo.article .. " " .. itemInfo.name .. " to be able to place a trap.")
    end
    return true
end
How to use this:

Write the code above in a Lua file and put it in the data/libs folder
Make your own traps on the configs, they can be whatever you want, from simple damages like the Fire/Energy/Ice/Earth traps, to other fun and more complex functions, very simple to configure, the rest of the configs are obvious I think
To make use of the system you need to use the function placeMine(cid, trapType) where cid is the player that placed the trap and trapType is the number of the trap you want to use, so if you want to make a spell to place a fire trap, its as simple as:
Code:
function onCastSpell(cid, var)
    return placeMine(cid, 1)
end

I think that's it, like I said simple =)

Thoughts? Comments? Suggestions?
 
Last edited:
Well, it's a nice thought, though I wouldn't use it. Reason why I wouldn't use them is mostly because of the possibility that people will place these traps everywhere. (Unless it's limited time)
 
They go off after a time set on the configs(10 seconds by default) automatically if no one steps on them
regarding putting the traps everywhere, this is a system for other people to use in their scripts, not an actual spell or talkaction, so I think that those kinds of verifications need to be checked at those places and not in this system
 
So, when do you expect people to use these traps? It would be great if you could only use maximum 2 or 3 traps, then you can higher the time limit aswell. Then this script would come in handy for me ^^
 
you can use it whenever you want, look at the spell example I gave at the end of the post, can't be any simpler then that
I think I can come up with a way to implement some sort of limitation to the number of traps a person can use, shouldn't be that hard :p
I'll do it tomorrow, going to bed now
 
Hahaha, I liked it!

Best part of the script:
Code:
"OTLand rocks!", "Scarlet Ayleid = best mod eva!!1!11", "fri itens plzz", "br?", "pl?", "no ks", "hauhauhahuahahua", "help plzz", "pk pk pk pk pk pk", "pandas suck", "Rep me++"
xDDDDD

Nice job, keep showing us your spells! ^^

Btw: 10/12 related videos = Minecraft :blink: xD
 
that probably happened because of the Trap keyword and it must connect them with Minecraft traps xD

yeah, the Blabber Trap is really just for fun xD
it was just to show how wide this system can go :p

Glad you liked it xD

I'll change the script later to support limited traps
 
So, when do you expect people to use these traps? It would be great if you could only use maximum 2 or 3 traps, then you can higher the time limit aswell. Then this script would come in handy for me ^^
Just updated it, didn't tried it, but I think it's a simple enough change that it doesn't require testing to know its working
if you use it and run into any problems, let me know :D
 
can u post a version where only x vocation can use
 
that isn't part of the system responsability, where you use it is where you have to check that
 
How about, would it possible for you to add an option for a used trap to disappear after x seconds if not picked back up? These traps would start to flood the map after awhile, yet I love the idea of having them. If I was any good at scripting, I would figure out a way to do it myself.

Think you could help me out here?


--Also, what 'lib' folder am I supposed to put traps.lua in, the one in data? I did that but it doesn't work. It just opens and closes the trap. >.<
 
Last edited:
Edited first post to support that, but haven't tested it, let me know if it works

you put it in the libs folder inside data
then you have to make another script to use the system, like the example I gave on the bottom of the first post
 
I guess we could make thing that will make possible to detect the mine.
Like its in rpgs-> There is some try that will give you a chance to see it. ^^
 
i guess its possible, but the way they are managed(recursive events) make it quite hard since there is no place for you to check if they exist or not, i guess you can make some tables with coords, like:

this is a quick edit, i think it might work, but it might not xD

Changes to the lib:
Lua:
...
mineCoords = {{{}}}

local function placeMine(cid, trapType)
     ...
     mineCoords[pos.x][pos.y][pos.z] = addEvent(...)
     doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Trap has been placed!")
     ...
end
...
local function activateTrap(cid, pos, trapType)
    ...
    mineCoords[pos.x][pos.y][pos.z] = nil
    return true
end

How to detect:
Lua:
local config = {
    range = 4
}

function detectTraps(cid)
    local pos = getCreaturePosition(cid)
    for x = pos.x - range, range * 2, 1 do
        for y = pos.y - range, range * 2, 1 do
            if(mineCoords[x][y][pos.z]) then
                --Detected mine, do whatever
            end
        end
    end
    return true
end

This seems like the most straightforward way, hope it helps you :)
 
That's what I always wanted from it, simple, clean, intuitive and powerful, just like any system should be :p
 
Back
Top