• 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 1.X+ 1.3 how to access tiles in combat area

JayMeazy

Member
Joined
Sep 7, 2020
Messages
92
Solutions
2
Reaction score
23
hello, I'm trying to access the tiles in a combat area, like AREA_CIRCLE3X3, to see if monsters and players are there. I created a function spell:area(), and then put the area in spells.xml, here's my function:
Code:
local combat2 = Combat()
function getTilesInArea()
    -- param1 - pos/creature
    -- param2 - pattern
    combat2:setArea(AREA_SQUARE7X7)

    local tiles = {}
    local positions = combat2:getPositions() -- get positions of creatures from combat area
    for _, position in ipairs(positions) do
        local tile = Tile(position) -- create a tile for this position
        tiles[#tiles+1] = tile
    end
    return tiles
end
which gives me the error:
luaCombatSetArea(). This function can only be used while loading the script.
which is because it's inside the function I guess, and while for this particular function I can set the combat2:setArea(AREA_SQUARE7X7) outside of the function, but this one I can't:
Code:
local combat = Combat()

function getCreaturesInArea2(param2, param3)
    -- param2 - pattern
    -- param3 - type of return
    -- 1 - everyone, 2 - monsters, 3 - players
    local specs = 0
    local monsters = 0
    local players = 0
    combat:setArea(param2)

    
    local positions = combat:getPositions() -- get positions of creatures from combat area
    for _, position in ipairs(positions) do
        local tile = Tile(position) -- create a tile for this position
        for _, creature in ipairs(tile:getCreatures()) do
            if creature ~= player then
                specs = specs + 1
                if creature:isMonster() then
                    monsters = monsters + 1
                elseif creature:isPlayer() then
                    players = players + 1
                end
            end
                
        end
    end
    if param3 == 1 then
        return specs
    elseif param3 == 2 then
        return monsters
    else
        return players
    end
end
any ideas? I have no idea how to get Game.getSpectators to work with a combat area, I'm thinking about just making it a c++ function, where it handles the combat area.
 

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,244
Solutions
71
Reaction score
555
Location
Hell
Looking for this?

Lua:
function onTargetTile(creature, position)
    -- do something with current combat tile
end

combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile")
 
OP
OP
JayMeazy

JayMeazy

Member
Joined
Sep 7, 2020
Messages
92
Solutions
2
Reaction score
23
Looking for this?

Lua:
function onTargetTile(creature, position)
    -- do something with current combat tile
end

combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile")
I still need to set the area inside the function for my second function, and when I do that it gives me errors. I think I have an idea for parsing the area, just doing an iterator across both dimensions of the table, and see how far the 1's are from the 3, and then iterate through those positions
Code:
AREA_CIRCLE3X3 = {
{0, 0, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 3, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 0, 0}
}

Code:
local timer2 = 0
function getCreaturesInArea(pos, area, param3, player)
    local playerPos = {}
    local effectedPos = {}
    for i = 1, #area do
        for v = 1, #area[i] do
            if area[i][v] == 3 then
                playerPos = {v, i}
            elseif area[i][v] == 1 then
                effectedPos[#effectedPos+1] = {v, i}
            end
        end
    end
    local monsters = 0
    local players = 0
    local specs = 0
    local ranges = {}
    if #effectedPos >= 1 then
        for i = 1, #effectedPos do
            local tmpX = effectedPos[i][1] - playerPos[1]
            local tmpY = effectedPos[i][2] - playerPos[2]
            ranges[#ranges+1] = {tmpX, tmpY}
        end
        for i = 1, #ranges do
            local xDiff = pos.x + ranges[i][1]
            local yDiff = pos.y + ranges[i][2]
            local tile = Tile(Position({x = xDiff, y = yDiff, pos.z}))
            if os.time() >= timer2 then
            player:say("" .. xDiff .. "", TALKTYPE_MONSTER_SAY, true, nil, Position(xDiff, yDiff, pos.z))
            end
            if tile and not tile:hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) and tile:getPosition():isSightClear(pos) then
                for _, creature in ipairs(tile:getCreatures()) do
                    if creature ~= player then
                    specs = specs + 1
                        if creature:isMonster() then
                            creature:say("ME", TALKTYPE_MONSTER_SAY)
                            monsters = monsters + 1
                        elseif creature:isPlayer() then
                            creature:say("ME", TALKTYPE_MONSTER_SAY)
                            players = players + 1
                        end
                    end            
                end
            end
        end
        timer2 = os.time()+1
    end
    if param3 == 1 then
        return specs
    elseif param3 == 2 then
        return monsters
    else
        return players
    end
end

it's not working but it's what i've come up with so far, for exevo gran mas flam it's saying there's 60 effected tiles, seems like it could be right, but my math's are wrong because all 60 tiles are being iterated to the 3 tiles above me, and i don't think it's recognizing creatures yet
 
Last edited:
Top