Есть способ для каждого юнита в группе получить координаты по X и Y, и потом взять минимум X и Y?

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

Функции дистанции
function GetDistancePoints takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
endfunction
function GetDistanceUnitPoint takes unit u, real x, real y returns real
local real dx = GetUnitX(u) - x
local real dy = GetUnitY(u) - y
return SquareRoot(dx * dx + dy * dy)
endfunction
function GetDistanceUnits takes unit u1, unit u2 returns real
local real dx = GetUnitX(u1) - GetUnitX(u2)
local real dy = GetUnitY(u1) - GetUnitY(u2)
return SquareRoot(dx * dx + dy * dy)
endfunction
Узнать ближайшего юнита к (x, y)
globals
    real X
    real Y
    unit ClosestUnit
    real Distance
endglobals

function FindClosestToXYCallback takes nothing returns nothing
    local real d = GetDistanceUnitPoint(GetEnumUnit(), X, Y)
    if d <= Distance then
        set Distance = d
        set ClosestUnit = GetEnumUnit()
    endif
endfunction

function FindClosestToXY takes group g, real x, real y returns unit
    set X = x
    set Y = y
    set ClosestUnit = null
    set Distance = 999999.
    call ForGroup(g, function FindClosestToXYCallback)
    return ClosestUnit
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
20
5 лет назад
0
можно, а в чем сложность? сделать две глобалки для X и Y, через перебор группы сравнивать координаты
0
11
5 лет назад
0
biridius:
можно, а в чем сложность? сделать две глобалки для X и Y, через перебор группы сравнивать координаты
Не понимаю, как обратиться к каждому юниту в группе. Какая команда
0
20
5 лет назад
Отредактирован biridius
0
call ForGroup(yourgroup, function yourfunction)
а там к самому юниту - GetEnumUnit()
0
11
5 лет назад
0
перебор группы
Это как? ForGroup()?
0
20
5 лет назад
Отредактирован biridius
0
в ГУИ картинках есть категория Отряд, там есть "Pick every unit in ..."
а на джассе ForGroup(g, function f) перебирает отряд g и запускает для каждого юнита по очереди функцию f
0
11
5 лет назад
0
biridius:
в ГУИ картинках есть категория Отряд, там есть "Pick every unit in ..."
Эта команда означает, что последующий код будет относиться к каждому юниту по отдельности? А не к отряду, так что ли?
0
20
5 лет назад
Отредактирован biridius
0
DopaMine, не, не последующий код.
Код для выбранных юнитов пишется в отдельной функции.
То что в гуях там все в одном триггере это для вида, на самом деле там создается редактором отдельная функция и поэтому при переборе групп на гуях не действуют локалки из вне перебора.
code
function ДляКаждогоЮнита takes nothing returns nothing
	set X = GetUnitX(GetEnumUnit())
endfunction

function ТвояПерваяФункцияЗапускающаяПеребор ...
	...
	ForGroup(ТвояГруппа, function ДляКаждогоЮнита)
	...
endfunction
0
11
5 лет назад
0
» code
Спасибо! А куда я могу сохранить данные из функции для каждого из юнитов, чтоб потом выбрать к примеру юнита с самым большим ХП? Если я к примеру сохраню в хэш каждого или ещё куда-то. Как мне потом получить эту базу данных?
0
20
5 лет назад
Отредактирован biridius
0
DopaMine, хеш не обязательно, такие вещи можно делать через глобальные переменные, например для координаты x делаем в редакторе переменных minx, в коде она будет называться udg_minx.
перед запуском перебора даем ей очень большое значение типа 99999.
затем внутри перебора сравниваем с X юнита:
local real x = GetUnitX(GetEnumUnit())
if x < udg_minx then
	udg_minx = x
	udg_minunit = GetEnumUnit()
else
endif
но тут вопрос в том зачем вообще искать наименьшую координату? мб тебе нужно найти ближайшего юнита к кастеру или тип того?
0
11
5 лет назад
0
можно делать через глобальные переменные
Не совсем понял: если у меня таких групп будет неизвестно сколько много по всей карте одновременно, то надо в хеш? Иначе дичь. Но логика ясна
biridius:
мб тебе нужно найти ближайшего юнита к кастеру или тип того?
Именно так!
То есть, типо надо скорее наименьший вектор найти из всех, что ведут к кастеру от каждого в группе.
0
28
5 лет назад
0
biridius, а else там зачем?
1
20
5 лет назад
Отредактирован biridius
1
DopaMine, эти глобалки будут использоваться только во время перебора. Варкрафт не выполняет сразу несколько функций одновременно если в них нету wait'ов, так что никаких пересечений не должно быть. Для перебора юнитов достаточно глобалок.
Как хранить данные в хеше для спеллов которые длятся какое-то время уже другой вопрос.
Чтобы найти ближайшего юнита, нужно еще сохранить в переменные целевую точку от которой считать расстояние.
PT153, хз можно убрать если ошибку выдает, не помню как там без jngp мб нужно мб нет
0
11
5 лет назад
0
if x < udg_minx then
Хорошо, чему тогда в начале равна глобльная ?:D
biridius:
Чтобы найти ближайшего юнита, нужно еще сохранить в переменные целевую точку от которой считать расстояние.
Да, точка сохранена уже.
Если что, я на джассе пишу, а не на триггерах)
3
28
5 лет назад
Отредактирован PT153
3
Функции дистанции
function GetDistancePoints takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
endfunction
function GetDistanceUnitPoint takes unit u, real x, real y returns real
local real dx = GetUnitX(u) - x
local real dy = GetUnitY(u) - y
return SquareRoot(dx * dx + dy * dy)
endfunction
function GetDistanceUnits takes unit u1, unit u2 returns real
local real dx = GetUnitX(u1) - GetUnitX(u2)
local real dy = GetUnitY(u1) - GetUnitY(u2)
return SquareRoot(dx * dx + dy * dy)
endfunction
Узнать ближайшего юнита к (x, y)
globals
    real X
    real Y
    unit ClosestUnit
    real Distance
endglobals

function FindClosestToXYCallback takes nothing returns nothing
    local real d = GetDistanceUnitPoint(GetEnumUnit(), X, Y)
    if d <= Distance then
        set Distance = d
        set ClosestUnit = GetEnumUnit()
    endif
endfunction

function FindClosestToXY takes group g, real x, real y returns unit
    set X = x
    set Y = y
    set ClosestUnit = null
    set Distance = 999999.
    call ForGroup(g, function FindClosestToXYCallback)
    return ClosestUnit
endfunction
Принятый ответ
0
11
5 лет назад
0
Хорошо, чему тогда в начале равна глобльная ?:D
Ну вообще, я так понял, это будет как раз координата кастера. Только тогда надо модуль разницы сравнивать.
0
26
5 лет назад
0
перед запуском перебора даем ей очень большое значение типа 99999.
в - внимательность
1
20
5 лет назад
Отредактирован biridius
1
DopaMine, поэтому я и добавил что
перед запуском перебора даем ей очень большое значение типа 99999.
чтобы было с чем сравнивать
нифига тред полетел
Только тогда надо модуль разницы сравнивать.
не, этого не достаточно. см код PT153 для функций расстояния
0
11
5 лет назад
0
globals
real X
real Y
unit ClosestUnit
real Distance
endglobals
Щас буду разбираться)
PT153:
» Функции дистанции
» Узнать ближайшего юнита к (x, y)
Офигеть, как компактно можно написать) прям как я и представлял, но как-то просто слишком выходит)) Круто! Спасибо!
3
17
5 лет назад
Отредактирован GetLocalPlayer
3
перед запуском перебора даем ей очень большое значение типа 99999.
set Distance = 999999.
Pow(2, 128)
PT153:
Функции дистанции
function GetDistancePoints takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
endfunction
function GetDistanceUnitPoint takes unit u, real x, real y returns real
local real dx = GetUnitX(u) - x
local real dy = GetUnitY(u) - y
return SquareRoot(dx * dx + dy * dy)
endfunction
function GetDistanceUnits takes unit u1, unit u2 returns real
local real dx = GetUnitX(u1) - GetUnitX(u2)
local real dy = GetUnitY(u1) - GetUnitY(u2)
return SquareRoot(dx * dx + dy * dy)
endfunction
Узнать ближайшего юнита к (x, y)
globals
    real X
    real Y
    unit ClosestUnit
    real Distance
endglobals

function FindClosestToXYCallback takes nothing returns nothing
    local real d = GetDistanceUnitPoint(GetEnumUnit(), X, Y)
    if d <= Distance then
        set Distance = d
        set ClosestUnit = GetEnumUnit()
    endif
endfunction

function FindClosestToXY takes group g, real x, real y returns unit
    set X = x
    set Y = y
    set ClosestUnit = null
    set Distance = 999999.
    call ForGroup(g, function FindClosestToXYCallback)
    return ClosestUnit
endfunction
Заметка для оптимизации: экономичнее не извлекать квадратный корень, а сравнивать с квадратом дистанции.
1
28
5 лет назад
1
Pow(2, 128)
Я бы вообще поставил максимальный float, но было лень гуглить.
Заметка для оптимизации: экономичнее не извлекать квадратный корень, а сравнивать с квадратом дистанции.
Верно, так даже точнее будет.
0
11
5 лет назад
0
DopaMine, хеш не обязательно, такие вещи можно делать через глобальные переменные
У меня появился таймер для того, чтоб нанести урон отобранному юниту через 0.2 секунды после того, как он был выбран. Теперь глобальные не подойдут, так как скилл муи и в глобальную будут за время ожидания(0.2) перезаписываться значения других юнитов, кастеров. Как быть?( ведь и в хендл не сохранишь, так как к примеру в отсеивателе ненужных юнитов для группы - GetFilterUnit() нет того, к чему привязать хэндл юнита-кастера(которого надо включить в список тех, кого не надо бить)
0
20
5 лет назад
0
Перебор юнитов в группе делается мгновенно, используйте глобалки, никакого конфликта не будет.
Параметры в глобалку заносите из основной функции после ожидания, а вот в самой основной функции загружать из хеша.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.