SirNikolas, а чем плоха R2I ? Тем что она не округляет, а отбрасывает дробную часть?
Я в контакте и на warcraft3ft.info. Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
omfg... Дак почему бы не использовать недостаток R2I?
Code
//На вход любые значения function RR2I takes real r returns integer local real x local integer z = 1 if r == 0 then return 0 elseif r < 0 then set r = -r set z = -1 endif set x = R2I(r) set r = r - x if r > 0.4 then return x + z endif return x endfunction
//На вход передаем положительные значения (можно и убрать условие, но нужно помнить, во избежание получения кривых значений писать не RR2I(-x), а -RR2I(x)) function RR2I takes real r returns integer local real x if r == 0 then return 0 elseif r < 0 set r = -r endif set x = R2I(r) set r = r - x if r > 0.4 then return x + 1 endif return x endfunction
Я в контакте и на warcraft3ft.info. Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
Функция от FkoFF с положительными работает "наотличненько". Достаточно передать в неё достаточно большое значение (скажем, 30 тысяч). Будет превышен лимит операций.
Функция от CHLSN выдаёт синтаксическую ошибку:
Code
return x // ==>> return R2I(x)
И даже если исправить это, то функция работает частично, но возвращает совершенно левые значения, если r > 0.4. Вы пытаетесь сделать трюк: сложить целое и дробное и вернуть целое. Компилятор, как ни странно, пропускает это, но игра выдает интересные значения.
Code
if r > 0.4 then return x + z endif // ==>> if r > 0.4 then return R2I(x) + z endif
Это я к тому, что вы трюкачите на ровном месте. Наиболее верная функция для округления:
Code
function R2Ix takes real r returns integer if (r < 0.0) then return R2I(r - 0.5001) endif return R2I(r + 0.5001) endfunction
Думаю стоит различать разницу между трюком и багом.
Quote (swdn)
Компилятор, как ни странно, пропускает это + Функция от CHLSN выдаёт синтаксическую ошибку
Компилятор проверяет только последний return
Я в контакте и на warcraft3ft.info. Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
И даже если исправить это, то функция работает частично, но возвращает совершенно левые значения, если r > 0.4. Вы пытаетесь сделать трюк: сложить целое и дробное и вернуть целое. Компилятор, как ни странно, пропускает это, но игра выдает интересные значения.
я не спорю, функция прямо скажем паршивая и дырявая, когда утром посмотрел - переписал в нормальный вариант с поддержкой отрицательных чисел и прочего факирства (главное - убрал циклы)
function MoveU takes unit u, real dist, real angle returns nothing call SetUnitPosition(u,GetWidgetX(u)+dist*Cos(angle*bj_DEGTORAD),GetWidgetY(u)+dist*Sin(angle*bj_DEGTORAD)) call SetUnitFacing(u,angle) set u=null endfunction
function MoveUex takes unit u, real dist, real angle returns nothing call SetUnitX(u,GetWidgetX(u)+dist*Cos(angle*bj_DEGTORAD)) call SetUnitY(u,GetWidgetY(u)+dist*Sin(angle*bj_DEGTORAD)) set u=null endfunction
MoveUex сдвигает юнита u на dist ед. расстояния в сторону angle не прерывая действий юнита MoveU сдвигает юнита u на dist ед. расстояния в сторону angle, прерывая текущие действия и поворачивая юнита в сторону angle
Code
function StunLoop takes nothing returns nothing local timer t = GetExpiredTimer() local integer th = GetHandleId(t) local unit u = LoadUnitHandle(udg_Data, th, 1) local integer ui=GetHandleId(u)
function StunUnit takes unit u, unit v, real time, real bonusdmg returns nothing local timer t = CreateTimer() local integer vi=GetHandleId(v) if u!=null and bonusdmg != null and bonusdmg > 0 then call UnitDamageTarget(u,v,bonusdmg, true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS) endif
if LoadReal(udg_Data,vi), 15) > 0 then if LoadReal(udg_Data, vi, 15)<time then call SaveReal(udg_Data, vi,15, time) endif else call PauseUnit(v, true) call SaveUnitHandle(udg_Data, GetHandleId(t), 1, v) call SaveReal(udg_Data, vi,15, time) call SaveEffectHandle(udg_Data,vi, 16, AddSpecialEffectTarget("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", v, "overhead")) call TimerStart(t, 0.02, true, function StunLoop) endif
set t = null set u=null set v=null endfunction
Функция заставляет юнита u оглушить юнита v на time секунд и нанести дополнительно bonusdmg ед. урона. Если юнит, находясь в оглушении получит оглушение более короткое чем оставшееся на юните - функция не запишет новое значение в переменную time, так же при передаче аргументов в функцию можно заменить первый аргумент на null а последний на 0 для того что бы просто оглушить юнита.
Code
function UnitGetItemById takes unit whichUnit, integer itemId returns item local integer l=1 local item it=null
loop exitwhen l>6 if GetItemTypeId(UnitItemInSlot(whichUnit,l))==itemId then set it=UnitItemInSlot(whichUnit,l) endif set l=l+1 endloop
return it
endfunction
Функция возвращает item по типу itemid находящийся на руках у unit u
Code
function GATcb takes nothing returns nothing local timer t=GetExpiredTimer() local integer ti=GetHandleId(t) local unit u=LoadUnitHandle(udg_Data,ti,0) local integer ui=GetHandleId(u) local integer abilcode=LoadInteger(udg_Data,ti,1) local real time=LoadReal(udg_Data,ui,abilcode)
if time>0 then set time=time-0.1 call SaveReal(udg_Data,ui,abilcode,time) else call UnitRemoveAbility(u,abilcode) call SaveReal(udg_Data,ui,abilcode,0) call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) set t=null endif
endfunction
function GiveAbilityTimed takes unit u, integer abilcode, integer lvl, real duration returns nothing local timer t local integer ui =GetHandleId(u) local integer ti if LoadReal(udg_Data,ui,abilcode) == null or LoadReal(udg_Data,ui,abilcode)<=0 then set t=CreateTimer() set ti=GetHandleId(t) call UnitAddAbility(u,abilcode) call SetUnitAbilityLevel(u,abilcode,lvl) call SaveInteger(udg_Data,ti,1,abilcode) call SaveUnitHandle(udg_Data,ti,0,u) call SaveReal(udg_Data,GetHandleId(u),abilcode,duration) call TimerStart(t,0.1,true,function GATcb) set t=null else call SaveReal(udg_Data,ui,abilcode,duration) if GetUnitAbilityLevel(u,abilcode) != lvl then call SetUnitAbilityLevel(u,abilcode,lvl) endif endif endfunction
Функция добавляет юниту х способность abilcode уровня lvl на duration секунд. При повторном вызове перезаписывает значения если есть разница в уровне и новая длительность больше старой длительности.
Code
function IALcb takes nothing returns nothing local timer t=GetExpiredTimer() call DecUnitAbilityLevel(LoadUnitHandle(udg_Data,GetHandleId(t),0),LoadInteger(udg_Data,GetHandleId(t),1)) call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) set t=null endfunction
function IncAblLvlTimed takes unit u, integer abilcode, real duration returns nothing local timer t=CreateTimer() call UnitAddAbility(u,abilcode) call IncUnitAbilityLevel(u,abilcode) call SaveInteger(udg_Data,GetHandleId(t),1,abilcode) call SaveUnitHandle(udg_Data,GetHandleId(t),0,u) call TimerStart(t,duration,true,function IALcb) set t=null endfunction
Увеличивает уровень способности abilcode юнита u на duration секунд. Функция нужна для способностей на подобии старой пассивки тролля в доте. Осторожно - способность не проверяет максимальный уровень способности.
function DummyCast takes unit u, unit targ, integer SpellId,integer lvl, string order returns nothing local unit du = CreateUnit(GetOwningPlayer(u),'h000',GetUnitX(u),GetUnitY(u),bj_RADTODEG * Atan2(GetWidgetY(targ) - GetWidgetY(u), GetWidgetX(targ) - GetWidgetX(u))) call UnitAddAbility(u,SpellId) call SetUnitAbilityLevel(u,SpellId,lvl) call IssueTargetOrder(du,order,targ) call UnitApplyTimedLife(du,'BTLF',0.5) set du = null set u=null set targ=null endfunction
function DummyCastCords takes unit u, real x, real y, integer SpellId,integer lvl, string order returns nothing local unit du = CreateUnit(GetOwningPlayer(u),'h000',x,y,0) call UnitAddAbility(u,SpellId) call SetUnitAbilityLevel(u,SpellId,lvl) call IssuePointOrder(du,order,x,y) call UnitApplyTimedLife(du,'BTLF',0.5) set du = null set u=null endfunction[/code] Функции берут unit u (владелец), создают для него дамми и заставляют применить SpellId уровня lvl строкой order (в первом случае) на юнита targ, во втором случае на точки x,y.
Code
function GetInvItemCount takes unit whichUnit, integer itemId returns integer local integer index local integer i=0
set index = 1 loop
if GetItemTypeId(UnitItemInSlot(whichUnit, index)) == itemId then set i =i+ 1 endif
set index = index + 1 exitwhen index > bj_MAX_INVENTORY endloop return i endfunction
Функция возвращает текущее количество предметов типа itemId у юнита whichUnit, требуется для корректной работы предметных пассивных\активных способностей.
Code
function CooldownSlotLoop takes nothing returns nothing local timer t=GetExpiredTimer() local unit u=LoadUnitHandle(udg_Data,GetHandleId(t),0) local integer checkslot =LoadInteger(udg_Data,GetHandleId(t),1) local real timeleft=LoadReal(udg_Data,GetHandleId(u),checkslot)
if timeleft <= 0 then call FlushChildHashtable(udg_Data,GetHandleId(t)) call DestroyTimer(t) call SaveReal(udg_Data,GetHandleId(u),checkslot,0) else call SaveReal(udg_Data,GetHandleId(u),checkslot,timeleft-0.1) endif
set t=null set u=null endfunction
function CooldownSlot takes unit u, integer checkslot, real duration returns nothing local timer t local integer ti=GetHandleId(u) local boolean b=LoadReal(udg_Data,ti,checkslot)!=null and LoadReal(udg_Data,ti,checkslot)>0
if b==false then set t=CreateTimer() call SaveUnitHandle(udg_Data,GetHandleId(t),0,u) call SaveInteger(udg_Data,GetHandleId(t),1,checkslot) call TimerStart(t,0.1,true,function CooldownSlotLoop) set t=null endif
endfunction
function CheckCDSlot takes unit u, integer checkslot returns boolean return LoadReal(udg_Data,GetHandleId(u),checkslot) == null or LoadReal(udg_Data,GetHandleId(u),checkslot)==0 endfunction
набор функций для проверки отката пассивных навыков да и любых других навыков. В нужном месте добавьте откат call CooldownSlot(unit,spellrawcode,duration) и проверяйте откатывающийся слот if CheckCDSlot(u,spellrawcode) then