Можно ли как-нибудь периодически находить ближайший разрушаемый объект к точке X без постоянного перебора (лагает, объектов много) и без участия заранее созданных точек: точку Y мне необходимо создавать только тогда, когда ближайший объект уже найден.

Принятый ответ

Не давно показывал эту функцию
поиск декораций
function CheckDes takes nothing returns nothing
local destructable d=GetEnumDestructable()
if GetDestructableLife(d)>0 and cdb==false  and d!=null then
set cdb=TRUE
endif
set d=null
endfunction

function PCD takes real x,real y, unit u returns boolean//PointConteintDes
local rect r
local real d=50
set r=Rect( x - d*2, y - d*2, x + d*2, y +d*2 )
set cdb=false
call EnumDestructablesInRect(r,null,function CheckDes)
call RemoveRect(r)
set r=null
return cdb
endfunction
Я точно это проверял на карте в 1000 объектов у 4 источников одновременно, больше не было думаю условия одинаковые.. Но нужно будет переделать под ваши нужды в CheckDes мы по очереди перебираем все разрушаемые в нужно регионе, изначально функция создана для нахождения какой либо разрушаемого, но тут достаточно добавить пару глобалок на, темболее возле героя же будет не 500-1000 разрушаемых а например до 10, если это деревья
Obelick, если ещё какие либо ньюансы для нахождения этого близжайшего декора, мне легче показать как я себе представляю реализацию такой задачи, чем объяснить, но нужно больше исходных данных, особоенно волнуют вопросы
сколько может быть разрушаемых в радиусе 512 и какой интервал
quq_CCCP, а если не мемхаком, просто послать рубить деревья, а потом как то извлечь дерево записанное в приказе, хз на сколько это возможно GetDestructableOrder(), если ли такое вообще? но адрес в памяти точно такой имеется...
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
30
5 лет назад
Отредактирован Clamp
0
Строишь короче такой Quadtree, заносишь в него все объекты, и те, что ищешь, и те, от которых ищешь, после чего простой триангуляцией по дереву реализуешь поиск.

Есть основания полагать, что всякие события "входит в область" и поиски ближайших обжей работают через Quadtree как раз нативно.
0
28
5 лет назад
Отредактирован PT153
0
Во время инициализации создаём все необходимые точки через Object.create(), затем после создания всех деструктаблов вызываем Object.findClosestDestForAll(). При создании нового деструктабла нужно вызвать Object.updateDestForAll(), а при смерти - Object.findClosestDestForAll(). Как ловить смерть я уже говорил.
Детектим смерть деструктабла с помощью события на смерть виджета и условия, что деструктабл триггера не нулл.
Код
function GetDistanceDestPoint takes destructable d, real x, real y returns real
    local real dx = GetDestructableX(d) - x
    local real dy = GetDestructableY(d) - y
    return SquareRoot(dx * dx + dy * dy)
endfunction

struct Object
    readonly static real StartDistance
    readonly static rect World
    private static boolexpr filter
    
    static thistype array entities
    readonly static integer top = -1
    
    real x
    real y
    readonly destructable d
    private real distance = StartDistance
    private integer index
    
    static method create takes real x, real y returns thistype
        local thistype this = allocate()
        set this.x = x
        set this.y = y
        set top = top + 1
        set entities[top] = this
        set index = top
        return this
    endmethod
    
    method onDestroy takes nothing returns nothing
        local integer i = index
        if i < top then
            set entities[i] = entities[top]
            set entities[i].index = i
        endif
        set top = top - 1
        set d = null
    endmethod
    
    method updateDest takes destructable d returns nothing
        local real dist = GetDistanceDestPoint(d, x, y)
        if dist > distance then
            set this.d = d
            set distance = dist
        endif
    endmethod
    
    static method updateDestForAll takes destructable d returns nothing
        local integer a = 0
        loop
            exitwhen a > top
            call entities[a].updateDest(d)
            set a = a + 1
        endloop
    endmethod
    
    private static method FilterFunc takes nothing returns boolean
        //local destructable t = GetFilterDestructable()
        //if GetDestructableTypeId(t) == 'ATtr' then
        //    call TransmittedObject.updateDest(t)
        //endif
        //set t = null
        call TransmittedObject.updateDest(GetFilterDestructable())
        return false
    endmethod
    
    private static thistype TransmittedObject
    
    method findClosestDest takes nothing returns nothing
        set TransmittedObject = this
        call EnumDestructablesInRect(World, filter, null)
    endmethod
    
    static method findClosestDestForAll takes nothing returns nothing
        local integer a = 0
        loop
            exitwhen a > top
            call entities[a].findClosestDest()
            set a = a + 1
        endloop
    endmethod
    
    private static method OnInit takes nothing returns nothing
        local rect r = GetWorldBounds()
        local real dx = GetRectMaxX(r) - GetRectMinX(r)
        local real dy = GetRectMaxY(r) - GetRectMinY(r)
        set StartDistance = SquareRoot(dx * dx + dy * dy) * 2.
        set World = r
        set r = null
        set filter = Filter(function thistype.FilterFunc)
    endmethod
endstruct
Я же верно понимаю, что деструктаблы не двигаются?
Чтобы оставить комментарий, пожалуйста, войдите на сайт.