Можно ли как-нибудь периодически находить ближайший разрушаемый объект к точке 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(), если ли такое вообще? но адрес в памяти точно такой имеется...
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
28
для гуи нубов варианта получается нет?
В JNGP должно быть такое, но лучше на JASS.

Я вот такое имею в виду.
function FilterFunct takes nothing returns boolean
    local destructable d = GetFilterDestructable()
    local integer T = GetDestructableTypeId(d)
    if T == ... then
        // ...
    elseif T == ... then
        // ...
    endif
    set d = null
    return false
endfunction

function SomeFunct takes rect r returns nothing
    call EnumDestructablesInRect(r, Filter(function FilterFunct), null)
endfunction

А вообще, предлагаю сделать так. Тем более, выполняется такое условие.
Точка X неподвижна.
Для каждого нужного объекта вычисляем ближайший деструктабл во время инициализации.
Детектим смерть деструктабла с помощью события на смерть виджета и условия, что деструктабл триггера не нулл. Пересчитываем для каждого объекта ближайший деструктабл.
При создании нового деструктабла для каждого объекта сравниваем его текущий ближайший деструктабл с новым. Если новый ближе, заменяем. Если нет, то ничего не меняем.
23
Короче просидев вчера всю ночь и сегодня утро, так и не смог сделать ничего вразумительного. Попытался сделать по принципу поиска ближайшей дистанции: занес все точки и дудады в массив. Сравниваю дистанцию и нахожу минимальную. Вроде все работает, да не все. Дудадов очень много, цикл прерывается, не проходя через все.
Jack-of-shadow, я если честно не понял про твой пример. Точнее понял, но не понял, как реализовать. Допустим мы проходим по 200 дудадам, обрываем цикл, то как после его запустить и не проходить по уже пройденным декорациям?
26
Obelick:
Делать небольшой рект, и смещать его вокруг точки. Тогда за раз будет обрабатывается не большое количество декора. А за 2 секунды можно безболезненно обработать огромные площади.
33
Jack-of-shadow, 7 юнитов одновременно каждые 2 секунды пикают от 600 до 900 дуадов
Я до сих пор не могу поверить что в радиусе 500 от юнита может находится 600-900 дуадов
23
Bergi_Bear, расстояние между клетками 512 ед. Я пикаю соответственно в большем радиусе.
30
Строишь короче такой Quadtree, заносишь в него все объекты, и те, что ищешь, и те, от которых ищешь, после чего простой триангуляцией по дереву реализуешь поиск.

Есть основания полагать, что всякие события "входит в область" и поиски ближайших обжей работают через Quadtree как раз нативно.
28
Во время инициализации создаём все необходимые точки через 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
Я же верно понимаю, что деструктаблы не двигаются?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.