Необходимо научить бота применять способность, которая применяется спустя какое-то время, как бы на опережение, чтобы попасть по врагу. Вроде все очень просто. Я знаю: куда движется цель, ее скорость и время применения способности. Все бы высчитывалось по простой формуле "скорость цели*угол движения цели*время применения способности", но проблема в путях(декорации, рельеф)...
Нет, цель же их обойдет и ее конечная позиция не будет совпадать с той которую я рассчитал по формуле. Подобное есть в доте с ботами. Жаль посмотреть нельзя(
Как насчет такого- каждые .04 секунды получать позицию цели, угол между ней и кастером и энумить декорации (можно и не энумить) и когда все данные будут соответствовать норме- кастовать
function FL7 takes real x1,real y1,real x2,real y2 returns real return SquareRoot(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))) endfunction
function QE7 takes real x,real y returns boolean if(x<GetRectMinX(bj_mapInitialPlayableArea)+75)then return false endif if(x>GetRectMaxX(bj_mapInitialPlayableArea)-75)then return false endif if(y<GetRectMinY(bj_mapInitialPlayableArea)+75)then return false endif if(y>GetRectMaxY(bj_mapInitialPlayableArea)-75)then return false endif return true endfunction
function FB7 takes real FC7 returns nothing local real F37 local real st=TimerGetElapsed(T) if st<=0 then set T=CreateTimer() call TimerStart(T,9000,false,null) endif if(FC7>0)then loop set F37=FC7-TimerGetElapsed(T)+st exitwhen F37<=0 if(F37>bj_POLLED_WAIT_SKIP_THRESHOLD)then call TriggerSleepAction(0.1*F37) else call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL) endif endloop endif endfunction
function QP7 takes unit E67,unit GA7,real QQ7,real QO7 returns location local real KM7=GetUnitX(GA7) local real KN7=GetUnitY(GA7) local real QR7=TimerGetElapsed(T) local real QS7=0 local real QT7=0 call FB7(0.1) set QR7=1./(TimerGetElapsed(T)-QR7) set QS7=(GetUnitX(GA7)-KM7)*QR7 set QT7=(GetUnitY(GA7)-KN7)*QR7 if not(QS7==0 and QT7==0)then set KM7=KM7+QS7*QQ7 set KN7=KN7+QT7*QQ7 endif if FL7(GetUnitX(E67),GetUnitY(E67),KM7,KN7)<=QO7 then call MoveLocation(ES7,KM7,KN7) if QE7(GetLocationX(ES7),GetLocationY(ES7))then return ES7 endif endif return null endfunction
Функции, используемые при наведении Sun strike Invoker'а, который отличается поразительной точностью добивания.
function DistanceBetweenPoints takes real x1,real y1,real x2,real y2 returns real return SquareRoot(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))) endfunction
function CanUsePoint takes real x, real y returns boolean if x < GetRectMinX(bj_mapInitialPlayableArea)+75 then return false endif if x > GetRectMaxX(bj_mapInitialPlayableArea)-75 then return false endif if y < GetRectMinY(bj_mapInitialPlayableArea)+75 then return false endif if y > GetRectMaxY(bj_mapInitialPlayableArea)-75 then return false endif
return true endfunction
function Wait takes real timeout returns nothing local real time local real elapsedttime = TimerGetElapsed(T)
if elapsedttime <= 0 then set T = CreateTimer() call TimerStart(T, 9000, false, null) endif
if timeout > 0 then loop //получить оставшееся время ожидания set time = timeout+elapsedttime - TimerGetElapsed(T) //выйти если ожидать больше нечего exitwhen time <= 0
//большой интервал if time > bj_POLLED_WAIT_SKIP_THRESHOLD then call TriggerSleepAction(.1*time) else //небольшой интервал call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL) endif endloop endif endfunction
function GetAbilityCastPoint takes unit u, unit ut, real timecast, real castdistance returns location local real x = GetUnitX(ut) local real y = GetUnitY(ut) local real time = TimerGetElapsed(T) local real speedx = 0 local real speedy = 0
//узнать куда движется цель call Wait(.1)
set time = 1./(TimerGetElapsed(T)-time) //сколько цель проходит за секунду времени по координате X set speedx=(GetUnitX(ut)-x)*time //сколько цель проходит за секунду времени по координате Y set speedy=(GetUnitY(ut)-y)*time
//цель двигалась if speedx != 0 or speedy != 0 then //рассчитать координаты точки применения set x = x+speedx*timecast set y = y+speedy*timecast endif
//расстояние от кастера до точки меньше или равное расстоянию каста if DistanceBetweenPoints(GetUnitX(u), GetUnitY(u), x, y) <= castdistance then //переместить точку каста call MoveLocation(loc, x, y) //если точка не выходит за границы карты if CanUsePoint(GetLocationX(loc), GetLocationY(loc)) then return loc endif endif