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

TFS 0.X Tfs 0.4 Doubt with use "str"

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,188
Solutions
34
Reaction score
200
Hi guy how are u?
This script i use in one quest, all players in X area, kill a boss and all players who are in this X area get teleport do temple.

Code:
    if count == 0 then -- when monster dies
        for x = fromPos.x, toPos.x do
            for y = fromPos.y,toPos.y do
            `    local m = getTopCreature({x=x, y=y, z=fromPos.z}).uid
                    if m~= 0 and isPlayer(m) then
                        doTeleportThing(m,{x=25100, y=15100, z=7})
                        doPlayerSendTextMessage(m,22,"You finished the quest!")
                    end
            end
        end
    end
If the players Josh, Makui and Hujoh kill the BOSS, i need to implement in the script this msg:
I need to introduce a broadcast saying "The players: Josh, Makui and Hujoh has compelted the quest"
I tried to use str buy i dont get sucess
 
Solution
With 0.4 / 0.3.6 / 0.3.7 -> I swear there isn't a default broadcast function scripted into sources. It's really hit or miss. So I just made it 'broadcast' to all online players individually.

put this in the monster somewhere (I do it right under defenses)
XML:
<script>
    <event name="aaaaaaaaaa"/>
</script>

data/creaturescripts/creaturescripts.xml
XML:
<event type="death" name="aaaaaaaaaa" event="script" value="aaaaaaaaaa.lua"/>

data/creaturescripts/scripts/aaaaaaaaaa.lua
Lua:
local config = {
    north_west_corner = {x = 900, y = 900, z = 7},
    south_east_corner = {x = 1100, y = 1100, z = 7},
}

function onDeath(cid, corpse, deathList)
    local players, text = getPlayersOnline(), ""
    for _, pid in ipairs(players) do...
With 0.4 / 0.3.6 / 0.3.7 -> I swear there isn't a default broadcast function scripted into sources. It's really hit or miss. So I just made it 'broadcast' to all online players individually.

put this in the monster somewhere (I do it right under defenses)
XML:
<script>
    <event name="aaaaaaaaaa"/>
</script>

data/creaturescripts/creaturescripts.xml
XML:
<event type="death" name="aaaaaaaaaa" event="script" value="aaaaaaaaaa.lua"/>

data/creaturescripts/scripts/aaaaaaaaaa.lua
Lua:
local config = {
    north_west_corner = {x = 900, y = 900, z = 7},
    south_east_corner = {x = 1100, y = 1100, z = 7},
}

function onDeath(cid, corpse, deathList)
    local players, text = getPlayersOnline(), ""
    for _, pid in ipairs(players) do
        local player_pos = getCreaturePosition(pid)
        if player_pos.z <= config.north_west_corner.z and player_pos.z >= config.south_east_corner.z then
            if player_pos.y >= config.north_west_corner.y and player_pos.y <= config.south_east_corner.y then
                if player_pos.x >= config.north_west_corner.x and player_pos.x <= config.south_east_corner.x then
                    if text ~= "" then
                        text = text .. ", "
                    end
                    text = text .. getCreatureName(pid)
                    doTeleportThing(pid, getTownTemplePosition(getPlayerTown(pid)))
                end
            end
        end
    end
    text = text .. " has completed the quest!"
    for _, pid in ipairs(players) do
        doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_ORANGE, text)
    end
    return true
end
 
Solution
With 0.4 / 0.3.6 / 0.3.7 -> I swear there isn't a default broadcast function scripted into sources. It's really hit or miss. So I just made it 'broadcast' to all online players individually.

put this in the monster somewhere (I do it right under defenses)
XML:
<script>
    <event name="aaaaaaaaaa"/>
</script>

data/creaturescripts/creaturescripts.xml
XML:
<event type="death" name="aaaaaaaaaa" event="script" value="aaaaaaaaaa.lua"/>

data/creaturescripts/scripts/aaaaaaaaaa.lua
Lua:
local config = {
    north_west_corner = {x = 900, y = 900, z = 7},
    south_east_corner = {x = 1100, y = 1100, z = 7},
}

function onDeath(cid, corpse, deathList)
    local players, text = getPlayersOnline(), ""
    for _, pid in ipairs(players) do
        local player_pos = getCreaturePosition(pid)
        if player_pos.z <= config.north_west_corner.z and player_pos.z >= config.south_east_corner.z then
            if player_pos.y >= config.north_west_corner.y and player_pos.y <= config.south_east_corner.y then
                if player_pos.x >= config.north_west_corner.x and player_pos.x <= config.south_east_corner.x then
                    if text ~= "" then
                        text = text .. ", "
                    end
                    text = text .. getCreatureName(pid)
                    doTeleportThing(pid, getTownTemplePosition(getPlayerTown(pid)))
                end
            end
        end
    end
    text = text .. " has completed the quest!"
    for _, pid in ipairs(players) do
        doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_ORANGE, text)
    end
    return true
end
use getSpectators, god damn it
 
use getSpectators
getSpectators

pro's
- fast for small-medium area sizes

con's
- hard for new scripters to use correctly without a wall of text explaining how to use the function
- depending on how many squares need to be checked, can be really slow
- if the area to check is not explicitly contained to 1 floor, the script would need to be modified to include this functionality
-- (getSpectators can check 1 floor or ALL floors, not multiple floors.)
--- see first con in this section regarding the above con.

-------
script above
- most likely a new scripter
- no idea how big the area is
- will always be roughly the same speed during operation. (unless OP has like 500+ players..?)

my verdict and decision, based on previous experience
- don't use semi-complicated functions that can cause issues OP likely doesn't know how to solve or troubleshoot.

god damn it
feel free to post your own solution, and let OP decide which is better. :p
 
getSpectators

pro's
- fast for small-medium area sizes

con's
- hard for new scripters to use correctly without a wall of text explaining how to use the function
- depending on how many squares need to be checked, can be really slow
- if the area to check is not explicitly contained to 1 floor, the script would need to be modified to include this functionality
-- (getSpectators can check 1 floor or ALL floors, not multiple floors.)
--- see first con in this section regarding the above con.

-------
script above
- most likely a new scripter
- no idea how big the area is
- will always be roughly the same speed during operation. (unless OP has like 500+ players..?)

my verdict and decision, based on previous experience
- don't use semi-complicated functions that can cause issues OP likely doesn't know how to solve or troubleshoot.


feel free to post your own solution, and let OP decide which is better. :p
solution
Code:
function getPlayersInArea(tl, br, multifloor, excludeGamemasters)
    local players = {}
    local rangeX = math.ceil(((br.x - tl.x) / 2))
    local rangeY = math.ceil(((br.y - tl.y) / 2))
    local spectators = getSpectators({x = (tl.x + rangeX), y = (tl.y + rangeY), z = tl.z}, rangeX, rangeY, (multifloor and true or false))

    if spectators then
        for _, creature in pairs(spectators) do
            if isPlayer(creature) then
                local pos = getCreaturePosition(creature)
                if ((pos.x >= tl.x) and (pos.x <= br.x)) then
                    if ((pos.y >= tl.y) and (pos.y <= br.y)) then
                        if (not excludeGamemasters) then
                            table.insert(players, creature)
                        else
                            if (getPlayerAccess(creature) < 3) then
                                table.insert(players, creature)
                            end
                        end
                    end
                end
            end
        end
    end

    return players
end



local area = {
    tl = {x = 900, y = 900, z = 7},
    br = {x = 1100, y = 1100, z = 7}
}

function onDeath(cid, corpse, deathList)
    local players = getPlayersInArea(area.tl, area.br)

    if (#players > 0) then
        local names = {}
        for _, player in pairs(players) do
            doTeleportThing(player, getPlayerMasterPos(player))
            doPlayerSendTextMessage(player, MESSAGE_EVENT_ADVANCE, "You have finished the quest!")
            table.insert(names, getCreatureName(player))
        end

        doBroadcastMessage(("%s %s completed the quest."):format(table.concat(names, ", "), ((#players > 1) and "have" or "has")))
    end
    return true
end



also you don't know what you're talking about if you think getSpectators is slow - it's literally made and optimized for this exact task
here's a benchmark using the function i used in the solution, it scanned 511664 tiles
Code:
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 11
02:10 0.021999999997206
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 12
02:10 0.0050000000046566
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 12
02:10 0.016000000061467


and another one in a smaller, but more populated area, scanning 135124 tiles
Code:
02:15 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:15 not xikini: 259
02:15 0.015999999945052
02:15 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:15 not xikini: 259
02:15 0.015999999945052
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.010000000009313
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.01500000001397
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.021000000066124
 
solution
Code:
function getPlayersInArea(tl, br, multifloor, excludeGamemasters)
    local players = {}
    local rangeX = math.ceil(((br.x - tl.x) / 2))
    local rangeY = math.ceil(((br.y - tl.y) / 2))
    local spectators = getSpectators({x = (tl.x + rangeX), y = (tl.y + rangeY), z = tl.z}, rangeX, rangeY, (multifloor and true or false))

    if spectators then
        for _, creature in pairs(spectators) do
            if isPlayer(creature) then
                local pos = getCreaturePosition(creature)
                if ((pos.x >= tl.x) and (pos.x <= br.x)) then
                    if ((pos.y >= tl.y) and (pos.y <= br.y)) then
                        if (not excludeGamemasters) then
                            table.insert(players, creature)
                        else
                            if (getPlayerAccess(creature) < 3) then
                                table.insert(players, creature)
                            end
                        end
                    end
                end
            end
        end
    end

    return players
end



local area = {
    tl = {x = 900, y = 900, z = 7},
    br = {x = 1100, y = 1100, z = 7}
}

function onDeath(cid, corpse, deathList)
    local players = getPlayersInArea(area.tl, area.br)

    if (#players > 0) then
        local names = {}
        for _, player in pairs(players) do
            doTeleportThing(player, getPlayerMasterPos(player))
            doPlayerSendTextMessage(player, MESSAGE_EVENT_ADVANCE, "You have finished the quest!")
            table.insert(names, getCreatureName(player))
        end

        doBroadcastMessage(("%s %s completed the quest."):format(table.concat(names, ", "), ((#players > 1) and "have" or "has")))
    end
    return true
end



also you don't know what you're talking about if you think getSpectators is slow - it's literally made and optimized for this exact task
here's a benchmark using the function i used in the solution, it scanned 511664 tiles
Code:
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 11
02:10 0.021999999997206
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 12
02:10 0.0050000000046566
02:10 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31827, y = 32018, z = 7}, {x = 32959, y = 32470, z = 7})) return os.clock() - start
02:10 not xikini: 12
02:10 0.016000000061467


and another one in a smaller, but more populated area, scanning 135124 tiles
Code:
02:15 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:15 not xikini: 259
02:15 0.015999999945052
02:15 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:15 not xikini: 259
02:15 0.015999999945052
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.010000000009313
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.01500000001397
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0
02:16 local start = os.clock() doCreatureSay(cid, #getPlayersInArea({x = 31815, y = 29219, z = 6}, {x = 32222, y = 29551, z = 6})) return os.clock() - start
02:16 not xikini: 259
02:16 0.021000000066124
Doesn't solve the multi-floor issue, but cool.
 
Back
Top