как найти самого близкого юнита

Добавлен
Мне нужно чтобы юнит при входе в зону направлялся к ближайшему зданию. Вот что я пытался но не вышло.
function Trig_SomeFunc_Conditions takes nothing returns boolean
    return ( GetUnitTypeId(GetTriggerUnit()) == 'SomeUnit' )
endfunction

function Trig_SomeFunc_H takes nothing returns nothing
    local unit f = GetEnumUnit()
    local unit u = null
    if ( R2I(DistanceBetweenPoints(GetUnitLoc(GetTriggerUnit()), GetUnitLoc(f))) <= R2I(DistanceBetweenPoints(GetUnitLoc(GetTriggerUnit()), GetUnitLoc(u))) ) then
        set u = f
    endif
    call IssuePointOrderLoc(GetTriggerUnit(), "move", GetUnitLoc(u))
endfunction

function Trig_SomeFunc_Actions takes nothing returns nothing
    call ForGroupBJ( GetUnitsOfPlayerAndTypeId(GetOwningPlayer(GetTriggerUnit()), 'SomeBuilding'), function Trig_SomeFunc_H )
endfunction
//===============================================
function InitTrig_SomeFunc takes nothing returns nothing
    set gg_trg_SomeFunc = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_SomeFunc, gg_rct_SomeLocation )
    call TriggerAddCondition( gg_trg_SomeFunc, Condition( function Trig_SomeFunc_Conditions ) )
    call TriggerAddAction( gg_trg_SomeFunc, function Trig_SomeFunc_Actions )
endfunction

Я не буду писать на джассе, просто скажу идею:
Создаешь глобальную целочисленную, присвоив ей какое-нибудь крупное значение (10000 например)
Создаешь глобального юнита (если я не ошибаюсь, то здание является юнитом)
Ты выбираешь триггером все здания в округе
Для каждого выбранного здания ты считаешь дистанцию и записываешь в локальную переменную.
Если значение локальной переменной меньше глобальной ( в первый раз оно однозначно будет меньше), то мы:
Записываем значение локалки в глобалку
Выбранное здание записываем в глобального юнита.
Иначе ничего не делаем.
Таким образом триггер моментально переберет все здания в округе, оценит их положение и ближайшее здание запишет в глобального юнита.
Затем ты просто посылаешь вошедшего юнита к этой глобалке.
В конце нужно глобальной целочисленной обратно вернуть большое значение.
Если тебе не нравятся глобалки, то ты можешь использовать хэш, не буду долбать себе мозги.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
20
В переменной с плавающей запятой R содержится дистанция от ближайшего юнита U3 до нашего U.
В локальной группе G все юниты-здания(ну или какие-либо еще, удовлетворяющие вашим условиям)
Тогда для каждого юнита из группы G:
Если юнит ближе предыдущего, он становится ближайшим.
Итого имеем нечто вроде:
Ближайший юнит находится сравнением расстояний, кэп. Дабы не возникал- вот тебе код(примерный).
globals
unit U
unit U2
unit U3
real R
real X
real Y
real X2
real Y2
endglobals

function BuildingFilter takes nothing returns boolean
set U2=GetFilteredUnit()
return IsUnitType(U2,UNIT_TYPE_BUILDING) and U!=U2
endfunction

function ActionOfTrigger2 takes nothing returns nothing
set U2=GetEnumUnit()
set X2=X-GetUnitX(U2)
set Y2=Y-GetUnitY(U2)
set X2=SquareRoot(X2*X2+Y2*Y2)
if X2<R then
set U3=U2
set R=X2
endif
endfunction

function ActionOfTrigger takes nothing returns nothing
local group G=CreateGroup()//Глобалка не подходит ибо довольно долго будут осуществляться операции с ней. С другой стороны почему бы и нет? Но это уже твоя забота.
set U=Юнит-константа
set X=GetUnitX(U)
set Y=GetUnitY(U)
call GroupEnumUnitsInRect(G,РЕГИОН ВЫБОРА,Condition(function Filter))//По логике: выделение по региону быстрее
set U3=FirstOfGroup(G)
set X2=X-GetUnitX(U3)
set Y2=Y-GetUnitY(U3)
set R=SquareRoot(X2*X2+Y2*Y2)
call GroupRemoveUnit(G,U3)
call ForGroup(G,function ActionOfTrigger2)
//Итого U3- ближайший юнит
endfunction
17
я так понимаю из кода что set X2=SquareRoot(X2*X2+Y2*Y2) это ты в квадрате берешь всех юнитов?
20
Чем ждать ответа попробуй вникнуть в код?
X2=SquareRoot(X2*X2+Y2*Y2) присваивает переменной X2 значение расстояния между юнитом U и текущим юнитом, обрабатываемым ForGroup.
Бегло пробежался по коду- ошибок у себя не вижу. Могу потратить еще время, мне не шибко то жалко, но говори конкретнее что не ясно? Могу оформить с использованием #define, будет понятнее. Но, на мой взгляд, тут и так все норм.
21
Принятый ответ
Я не буду писать на джассе, просто скажу идею:
Создаешь глобальную целочисленную, присвоив ей какое-нибудь крупное значение (10000 например)
Создаешь глобального юнита (если я не ошибаюсь, то здание является юнитом)
Ты выбираешь триггером все здания в округе
Для каждого выбранного здания ты считаешь дистанцию и записываешь в локальную переменную.
Если значение локальной переменной меньше глобальной ( в первый раз оно однозначно будет меньше), то мы:
Записываем значение локалки в глобалку
Выбранное здание записываем в глобального юнита.
Иначе ничего не делаем.
Таким образом триггер моментально переберет все здания в округе, оценит их положение и ближайшее здание запишет в глобального юнита.
Затем ты просто посылаешь вошедшего юнита к этой глобалке.
В конце нужно глобальной целочисленной обратно вернуть большое значение.
Если тебе не нравятся глобалки, то ты можешь использовать хэш, не буду долбать себе мозги.
28
зачем хэш зачем глобалка можно всё в локалку
и зачем здание создавать
короче держи
интересно sergant1000 читает ответы на этот вопрос или он забил?
Загруженные файлы
21
возможно, глобалки и хэш не нужен, просто структура кода пока не держится в голове)
28
я скинул пример там глобалка только для примера используется
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.