В общем, суть следующая: я сделал способность "Рывок": Герой бежит к указанному противнику, слегка отталкивая всех войнов по пути (включая своих). Остальное не важно. Сама проблема заключается в том, что в некоторых случаях отталкивание идет не в ту сторону, которую нужно (в зависимости от того, где расположен попадающийся объект, справа или слева, он отталкивается с разницей в 90 градусов от текущего поворота героя). Я уже перепробовал множество глупых способов, но максимум я смог сделать, чтобы лишь в большинстве случаев отталкивание шло правильно.

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

function GetDirection takes unit u, unit targ returns int
         local real alpha = GetUnitFacing(u)
         local real gamma = bj_RADTODEG * Atan2(GetUnitY(targ)-GetUnitY(u), GetUnitX(targ)-GetUnitX(u))
          if gamma < 0 then
            set gamma = 360. + gamma
          endif
          if (alpha < 180. and not(gamma > alpha and gamma < alpha + 180.)) or (alpha > 180. and gamma > alpha - 180. and gamma < alpha) then
            return 2
          else
            return 1
          endif
    endfunction
1 право, 2 лево, вроде бы
и обнулять реал это мощно... и хеш таблица не корректно используется...
2
13
10 лет назад
2
1
25
10 лет назад
1
Эм, а слабо отталкивать в сторону Угол между юнитами ( юнит кастер, юнит которого нужно оттолкнуть)? Или до этого додуматься столь сложно?
3
13
10 лет назад
3
Ancient, меня не устраивает этот вариант, мне нужно, чтобы цель отталкивалась на 90 градусов в зависимости от стороны, с которой располагается юнит, которого надо оттолкнуть.
0
28
10 лет назад
0
Pavell, кинь код под кат
лень открывать карту
3
13
10 лет назад
Отредактирован Pavell
3
Кусок кода, где идет попытка определения с какой стороны находится юнит
loop
            exitwhen CountUnitsInGroup(g) == 0
            set p = FirstOfGroup(g)
            if p!=u and p!=u1 and not IsUnitInGroup(p,udg_hit) then
                call GroupAddUnit(udg_hit,p)
                set t1 = CreateTimer()
                call SaveUnitHandle(udg_hash,GetHandleId(t1),0,p)
                call SaveReal(udg_hash,GetHandleId(t1),1,6)
                set a1 = Atan2(GetUnitX(u)-GetUnitX(p),GetUnitY(u)-GetUnitY(p))
                if a>0 and a1>0 then
                    if a>a1 then
                        call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                    else
                        call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                    endif
                else
                if a<0 and a1<0 then
                        if a<a1 then
                        call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                    else
                        call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                    endif
                else
                if a>a1 then
                    call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                else
                    call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                endif
                endif
                endif
                call SaveInteger(udg_hash,GetHandleId(t1),3,25)
                call UnitDamageTarget(u,p,25*GetUnitAbilityLevel(u,'A000'),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
                call TimerStart(t1,.02,true,function MoveUnits)
                set t1 = null
            endif
            call GroupRemoveUnit(g,p)
            set p = null
        endloop
Весь код
function MoveTarget takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = LoadUnitHandle(udg_hash,GetHandleId(t),0)
    local real d = LoadReal(udg_hash,GetHandleId(t),1)
    local real a = LoadReal(udg_hash,GetHandleId(t),2)
    local integer i = LoadInteger(udg_hash,GetHandleId(t),3)
    local real d1 = LoadReal(udg_hash,GetHandleId(t),4)
    call SetUnitX(u,GetUnitX(u)+d*Cos(a))
    call SetUnitY(u,GetUnitY(u)+d*Sin(a))
    call AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",GetUnitX(u),GetUnitY(u))
    call DestroyEffect(bj_lastCreatedEffect)
    call SaveReal(udg_hash,GetHandleId(t),1,d-(0.08*(d1/3-1)/5))
    call SaveInteger(udg_hash,GetHandleId(t),3,i-1)
    if(i==25)then
        call UnitAddAbility(u,'Aave')
        call UnitRemoveAbility(u,'Aave')
        call SetUnitFlyHeight(u,0,200)
    endif
    if(i==0)then
        call PauseUnit(u,false)
        call SetUnitPathing(u,true)
        call FlushChildHashtable(udg_hash, GetHandleId(t))
        call DestroyTimer(t)
    endif
    set t = null
    set u = null
    set a = 0
    set d = 0
    set i = 0
    set d1 = 0
endfunction

function MoveUnits takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = LoadUnitHandle(udg_hash,GetHandleId(t),0)
    local real d = LoadReal(udg_hash,GetHandleId(t),1)
    local real a = LoadReal(udg_hash,GetHandleId(t),2)
    local integer i = LoadInteger(udg_hash,GetHandleId(t),3)
    call SetUnitX(u,GetUnitX(u)+d*Cos(a))
    call SetUnitY(u,GetUnitY(u)+d*Sin(a))
    call AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",GetUnitX(u),GetUnitY(u))
    call DestroyEffect(bj_lastCreatedEffect)
    call SaveReal(udg_hash,GetHandleId(t),1,d-0.03)
    call SaveInteger(udg_hash,GetHandleId(t),3,i-1)
    if(i==0)then
        call GroupRemoveUnit(udg_hit,u)
        call PauseUnit(u,false)
        call SetUnitPathing(u,true)
        call FlushChildHashtable(udg_hash, GetHandleId(t))
        call DestroyTimer(t)
    endif
    set t = null
    set u = null
    set a = 0
    set d = 0
    set i = 0
endfunction

function GetMoveUnits takes nothing returns boolean
    return not(IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL)) and GetWidgetLife(GetFilterUnit()) > .405 and GetUnitAbilityLevel(GetFilterUnit(),'Aloc') == 0
endfunction

function MoveHero takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer t1 = null
    local unit u = LoadUnitHandle(udg_hash,GetHandleId(t),0)
    local unit u1 = LoadUnitHandle(udg_hash,GetHandleId(t),1)
    local real d = LoadReal(udg_hash,GetHandleId(t),2)
    local real dx = GetUnitX(u1) - GetUnitX(u)
    local real dy = GetUnitY(u1) - GetUnitY(u)
    local real a = Atan2(dy,dx)
    local group g = CreateGroup()
    local unit p = null
    local real a1 = 0
    local real a2 = 0
    if GetWidgetLife(u) > .405 then
        call SetUnitX(u,GetUnitX(u)+d*Cos(a))
        call SetUnitY(u,GetUnitY(u)+d*Sin(a))
        call SetUnitFacing(u,a*180/3.14)
        call AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",GetUnitX(u),GetUnitY(u))
        call DestroyEffect(bj_lastCreatedEffect)
        call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 128, Condition(function GetMoveUnits))
        loop
            exitwhen CountUnitsInGroup(g) == 0
            set p = FirstOfGroup(g)
            if p!=u and p!=u1 and not IsUnitInGroup(p,udg_hit) then
                call GroupAddUnit(udg_hit,p)
                set t1 = CreateTimer()
                call SaveUnitHandle(udg_hash,GetHandleId(t1),0,p)
                call SaveReal(udg_hash,GetHandleId(t1),1,6)
                set a1 = Atan2(GetUnitX(u)-GetUnitX(p),GetUnitY(u)-GetUnitY(p))
                if a>0 and a1>0 then
                    if a>a1 then
                        call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                    else
                        call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                    endif
                else
                if a<0 and a1<0 then
                        if a<a1 then
                        call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                    else
                        call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                    endif
                else
                if a>a1 then
                    call SaveReal(udg_hash,GetHandleId(t1),2,a-1.57)
                else
                    call SaveReal(udg_hash,GetHandleId(t1),2,a+1.57)
                endif
                endif
                endif
                call SaveInteger(udg_hash,GetHandleId(t1),3,25)
                call UnitDamageTarget(u,p,25*GetUnitAbilityLevel(u,'A000'),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
                call TimerStart(t1,.02,true,function MoveUnits)
                set t1 = null
            endif
            call GroupRemoveUnit(g,p)
            set p = null
        endloop
        call SaveReal(udg_hash,GetHandleId(t),2,d+0.04)
        if(SquareRoot(dx*dx+dy*dy)<=125)then
            call AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",GetUnitX(u1),GetUnitY(u1))
            call DestroyEffect(bj_lastCreatedEffect)
            call UnitDamageTarget(u,u1,100*GetUnitAbilityLevel(u,'A000'),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            call PauseUnit(u,false)
            call SetUnitPathing(u,true)
            call FlushChildHashtable(udg_hash, GetHandleId(t))
            call DestroyTimer(t)
            set t = CreateTimer()
            call PauseUnit(u1,true)
            call SetUnitPathing(u1,false)
            call UnitAddAbility(u1,'Aave')
            call UnitRemoveAbility(u1,'Aave')
            call SetUnitFlyHeight(u1,100,200)
            call SaveUnitHandle(udg_hash,GetHandleId(t),0,u1)
            call SaveReal(udg_hash,GetHandleId(t),1,d/3-1)
            call SaveReal(udg_hash,GetHandleId(t),2,a)
            call SaveInteger(udg_hash,GetHandleId(t),3,50)
            call SaveReal(udg_hash,GetHandleId(t),4,d)
            call TimerStart(t,.02,true,function MoveTarget)
        endif
    else
        call PauseUnit(u,false)
        call SetUnitPathing(u,true)
        call FlushChildHashtable(udg_hash, GetHandleId(t))
        call DestroyTimer(t)
    endif
    call DestroyGroup(g)
    set t = null
    set u = null
    set u1 = null
    set a = 0
    set d = 0
    set dx = 0
    set dy = 0
    set g = null
    set p = null
    set t1 = null
endfunction

function Trig_Dash_Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A000' 
endfunction

function Trig_Dash_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit u1 = GetSpellTargetUnit()
    local timer t = CreateTimer()
    local real a = 180/3.14*Atan2(GetUnitY(u1)-GetUnitY(u),GetUnitX(u1)-GetUnitX(u))
    local real dx = GetUnitX(u1) - GetUnitX(u)
    local real dy = GetUnitY(u1) - GetUnitY(u)
    call PauseUnit(u,true)
    call SetUnitPathing(u,false)
    call SetUnitFacing(u,a)
    call SaveUnitHandle(udg_hash,GetHandleId(t),0,u)
    call SaveUnitHandle(udg_hash,GetHandleId(t),1,u1)
    call SaveReal(udg_hash,GetHandleId(t),2,(640000/SquareRoot(dx*dx+dy*dy)/50)-1)
    call TimerStart(t,.02,true,function MoveHero)
    set t = null
    set u = null
    set u1 = null
    set a = 0
endfunction

//===========================================================================
function InitTrig_Dash takes nothing returns nothing
    set gg_trg_Dash = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Dash, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Dash, Condition( function Trig_Dash_Conditions ) )
    call TriggerAddAction( gg_trg_Dash, function Trig_Dash_Actions )
endfunction
0
28
10 лет назад
0
хэш
период 0,02
в общем омг
я напишу сегодня как я бы делал это
потом глянешь
что и где у тебя не правильно
1
26
10 лет назад
Отредактирован Hate
1
function GetDirection takes unit u, unit targ returns int
         local real alpha = GetUnitFacing(u)
         local real gamma = bj_RADTODEG * Atan2(GetUnitY(targ)-GetUnitY(u), GetUnitX(targ)-GetUnitX(u))
          if gamma < 0 then
            set gamma = 360. + gamma
          endif
          if (alpha < 180. and not(gamma > alpha and gamma < alpha + 180.)) or (alpha > 180. and gamma > alpha - 180. and gamma < alpha) then
            return 2
          else
            return 1
          endif
    endfunction
1 право, 2 лево, вроде бы
и обнулять реал это мощно... и хеш таблица не корректно используется...
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.