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

ответ
если есть х/у дерева и требуемой точки, то почему бы просто не сравнивать расстояния между ними?

33
Сколько объектов и сколько истоников возле которых нужно делать проверку?
23
Bergi_Bear, объектов очень много, больше тысячи. Источников 8. Пробовал перебором, даже в небольшом радуисе (512), но все равно спайкает каждый раз.
Как я пытался сделать сам:
Точка X неподвижна. Вокруг каждой X я создавал заранее область (находить объект по всей карте - не нужно, только в заданной области/радиусе). Заносил все дудады в переменную, для каждой из областей, и создавал под каждым из них точку. Проходя циклом, находя дистанцию между X и точками из массива, узнавал минимальную. Но я не знаю, как взять ссылку на саму точку с этой минимальной дистанцией. Этот вариант громоздкий, но если вы сможете подсказать, как найти ссылку на точку, то это тоже поможет решить проблему, но очень костыльно.
32
Ну только если это деревья... Создать работника и отправить рубить лес, он безошибочно найдет ближейшее дерево.
Хз мб с помощью мемхака удастся выудить эту функцию пойска, т.к действия описанные в движке работают быстрее чем на jass.
4
а если перебирать несколько раз, но начиная с совсем мелких радиусов, там по 50, 100.
33
Не давно показывал эту функцию
поиск декораций
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(), если ли такое вообще? но адрес в памяти точно такой имеется...
Принятый ответ
23
В 512 думаю около 10, интервал 2 секунды. Но фишка в том, что в этом радиусе может и не быть подходящих объектов. Так как ты уже играл в Железную эпоху, то я пытаюсь сделать ИИ для этой карты, возможно тебе легче будет это представить в таком случае. Компьютер должен последовательно захватывать ближайшие клетки вокруг своего главного здания и не выходить за пределы своей территории.
26
Obelick:
Лагать не должно, если правильно отсеивать.
У меня в карте более 30 к разрушаемых пропсов, заспавненных во время игры (около 30 декораций на радиус 500 ед.) Через енум и стрелы летят и проверка на зрение работает и все норм.
То что предложил Bergi_Bear самое оно, только ректы можно глобальные подготовить разных размеров заранее.

Obelick:
В 512 думаю около 10, интервал 2 секунды. Но фишка в том, что в этом радиусе может и не быть подходящих объектов.
Что то мне подсказывает что именно при "ненахождении" объектов возникают проблемы. Возможно вы что то упустили в этом месте.
33
Obelick, ну такое точно не должно лагать, если даже у Джека всё норм, покажи нам свой код наверное какой-то лишний перегруз
32
Bergi_Bear, да, об этом в статьях есть, отправь работника рубить лес и посмотри цель текущего приказа...
23
Jack-of-shadow, как отсеивать в пике дудады, если условных пиков нет? Можно только выбрать все на карте/в радиусе и уже далее ставить условия
20
Я когда-то давно так делал:
x = 50
Цикл
	Ищем декорации в радиусе x от изначальной точки
	Если нашли, то выбрать любой декор, который нашли выше и сохранить его.
	Иначе х = х + 50 и повторить цикл.
Ну, тут нужно добавить, что могут быть погрешности в пределах 50 точек, но мне это было не принципиально.
Также будет зацикливание, если дудов на карте вообще нет или они все мертвы, но это исправляется условием.
23
KaneThaumaturge, у меня лагает, когда пикаешь дудады. Ботов может быть много и каждый пикает от 500+ каждые 2 секунды. Спайк небольшой, но заметен.
22
создаю дамми и вручаю юнит несколько дерево и даю приказ продолжить работу и он приказ ловит и узнаем декорация. havet
26
Obelick:
Все таки сколько одновременно юнитов выбираеют декор?
Возможно лагает какраз от того, что у тебя много юнитов делают enum одновременно в одном тике.
В таком случае неважно какая периодичность - лагать будет одинаково. Можно решить примерно
так

Очень утрированный пример:

таймер 0.01
выборка для unit[index]
index++
if index > 200 { index = 1}
на 200 юнитов хватит и будет периодичность 2 секунды.

Потом какие нибудь важные декорации которые ты ищешь можно найти один раз при загрузке карты, тем более что она у тебя генерируемая. Например создать отсортированные массивы определенного типа по которым можно делать более быстрый перебор, чем по всем декорациям на карте.
23
Jack-of-shadow, 7 юнитов одновременно каждые 2 секунды пикают от 600 до 900 дуадов
26
Пример выше должен помочь, если перебирать не 900 декораций сразу, а например по 90 каждые 0.1. Если равномерно распределить, то по примерно по 5 декораций выбираться будет за кадр.

Я правильно понимаю тебе нужно отсортировать декорации по дальности от базы?
23
Jack-of-shadow, да, верно. Чтобы компьютер захватывал сначала ближайшие клетки, а уже потом отдалялся от своей базы.
28
как отсеивать в пике дудады, если условных пиков нет?
В фильтре пишешь условие, внутри которого и делаешь все необходимые действия, а codeAction скипаешь.
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 ед. Я пикаю соответственно в большем радиусе.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.