Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Наработка
Работает по принципу: Даем юниту максимальную дальность атаки, а при атаке проверяем,, если дальность больше требуемой, то заставляем двигаться до нашей точки пока расстояние не будет соответствовать дальности атаки.
Для использования качаем и копируем себе в карту триггер "AttackRange" или создаем триггер с названием "AttackRange" и копируем в него весь код.
Вызов функции: call SetUnitRange( юнит, дальность атаки)
Код
library ATTACKRANGE initializer Ini_AttackRange

globals
    unit array ar_attack
    unit array ar_attacked
    integer ar_max = 0
    boolean array ar_bool 
    timer T = CreateTimer()
    hashtable h = InitHashtable()
endglobals

function CheckDistance takes nothing returns nothing
local integer i = 0
local real x 
local real y 
local real x1
local real y1 
local integer id 
local real a 
    
    loop

        set i = i + 1
        exitwhen i > ar_max
        
        set x = GetUnitX(ar_attack[i])
        set y = GetUnitY(ar_attack[i])
        set x1 = GetUnitX(ar_attacked[i])
        set y1 = GetUnitY(ar_attacked[i])
        set a = Atan2(y1 - y, x1 - x)
        set id = GetHandleId(ar_attack[i])
        
        if SquareRoot((x1-x) * (x1-x) + (y1-y) * (y1-y)) <= LoadReal(h,id,2) or GetWidgetLife(ar_attack[i]) <= 0. then 
            call IssueTargetOrder(ar_attack[i],"attack",ar_attacked[i])
            set ar_attack[i] = ar_attack[ar_max]
            set ar_attacked[i] = ar_attacked[ar_max]
            set ar_max = ar_max - 1
        elseif ar_bool[i] then
            call IssueTargetOrder(ar_attack[i],"move",ar_attacked[i] )
            set ar_bool[i] = false
        endif
        
    endloop

endfunction

function Trig_AttackRange_Actions takes nothing returns nothing
local unit attack = GetAttacker()
local unit attacked = GetTriggerUnit()
local integer id = GetHandleId(attack)
local real x = GetUnitX(attack)
local real y = GetUnitY(attack)
local real x1 = GetUnitX(attacked)
local real y1 = GetUnitY(attacked)
local integer i = 0
    
    if SquareRoot((x1-x) * (x1-x) + (y1-y) * (y1-y)) > LoadReal(h,id,2) then
        set ar_max = ar_max + 1
        set ar_attack[ar_max] = attack
        set ar_attacked[ar_max] = attacked
        set ar_bool[ar_max] = true
    endif
    
set attack = null
set attacked = null
endfunction

function Ini_AttackRange takes nothing returns nothing
    set gg_trg_AttackRange = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_AttackRange,EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction(gg_trg_AttackRange,function Trig_AttackRange_Actions)
    call TimerStart(T,.02,true,function CheckDistance)
endfunction
    
function SetUnitRange takes unit u, real range returns nothing
    call SaveReal(h,GetHandleId(u),2,range)
    call SetUnitAcquireRange(u,range + 200.)
endfunction

endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...