Имеется код для одной способности включающая в себя, как активный режим, так и пассивный.
Задача состоит в оптимизации кода, преимущественно для активного режима, где герой перемещается (SetUnitPosition) с мелкой периодичностью.
Использую JNGP.
Задача состоит в оптимизации кода, преимущественно для активного режима, где герой перемещается (SetUnitPosition) с мелкой периодичностью.
Использую JNGP.
Функции, что используются часто (в нестандартном коде карты)
globals
group FilterGroup=null
player FilterPlayer=null
boolean FilterVisible=false
boolean RegisterDamage=true
endglobals
function UnitDamageTargetEx takes unit u, unit t, real d, boolean a, boolean r, attacktype at, damagetype dt, weapontype wt returns nothing
set RegisterDamage=false
call UnitDamageTarget(u,t,d,a,r,at,dt,wt)
set RegisterDamage=true
endfunction
function GroupFilter takes nothing returns boolean
local boolean b=((not IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD)) and GetUnitAbilityLevel(GetFilterUnit(),'Aloc')==0)
if FilterGroup!=null then
set b=(b and not IsUnitInGroup(GetFilterUnit(),FilterGroup))
endif
if FilterPlayer!=null then
set b=(b and IsUnitEnemy(GetFilterUnit(),FilterPlayer))
if FilterVisible then
set b=(b and IsUnitVisible(GetFilterUnit(),FilterPlayer) and not IsUnitFogged(GetFilterUnit(),FilterPlayer))
endif
endif
return b
endfunction
function TextTag takes string s, real sz, unit u, real ho, integer r, integer g, integer b, real xv, real yv, real f, real l returns nothing
local texttag tt=CreateTextTag()
call SetTextTagText(tt,s,sz)
call SetTextTagPos(tt,GetUnitX(u),GetUnitY(u),ho)
call SetTextTagColor(tt,r,g,b,255)
call SetTextTagVelocity(tt,xv,yv)
call SetTextTagVisibility(tt,true)
call SetTextTagFadepoint(tt,f)
call SetTextTagLifespan(tt,l)
call SetTextTagPermanent(tt,false)
call SetTextTagSuspended(tt,false)
set tt=null
set u=null
set s=null
endfunction
Сам триггер способности...
globals
constant integer Custom_SkillW_Ability='A001'
constant integer Custom_SkillW_Ability_B='A006'
constant integer Custom_SkillW_Buff_B='B000'
constant integer Custom_SkillW_Ability_C='A00O'
constant integer Custom_SkillW_Ability_D='A008
constant integer Custom_SkillW_Ability_E='A007'
constant integer Custom_SkillW_HeroID_A='N000'
constant integer Custom_SkillW_HeroID_B='N001'
constant real Custom_SkillW_A_Bonus_Base=.7
constant real Custom_SkillW_A_Bonus_PerLvl=.3
constant real Custom_SkillW_C_Chance_Evade_Base=10.
constant real Custom_SkillW_C_Chance_Evade_PerLvl=.0
constant real Custom_SkillW_C_Chance_Evade_Stat_Base=.01
constant real Custom_SkillW_C_Chance_Evade_Stat_PerLvl=.01
constant real Custom_SkillW_C_Chance_Crit_Base=10.
constant real Custom_SkillW_C_Chance_Crit_PerLvl=.0
constant real Custom_SkillW_C_Chance_Crit_Stat_Base=.01
constant real Custom_SkillW_C_Chance_Crit_Stat_PerLvl=.01
constant real Custom_SkillW_C_Multi_Crit_Min_Base=1.5
constant real Custom_SkillW_C_Multi_Crit_Min_PerLvl=.0
constant real Custom_SkillW_C_Multi_Crit_Max_Base=3.
constant real Custom_SkillW_C_Multi_Crit_Max_PerLvl=.0
integer Custom_SkillW_C_StringMaxer
string array Custom_SkillW_C_Strings
constant real Custom_SkillW_E_Interval=.0125
constant real Custom_SkillW_E_Time_A=3.
constant real Custom_SkillW_E_Time_B=.5
constant real Custom_SkillW_E_AoE_A=600.+25.
constant real Custom_SkillW_E_AoE_B=.0
constant real Custom_SkillW_E_Bonus_Dmg_Base=.0
constant real Custom_SkillW_E_Bonus_Dmg_PerLvl=.0
constant real Custom_SkillW_E_Bonus_Stat_Dmg_Base=1.
constant real Custom_SkillW_E_Bonus_Stat_Dmg_PerLvl=.0
trigger SkillW_A=CreateTrigger()
trigger SkillW_B=CreateTrigger()
trigger SkillW_C=CreateTrigger()
trigger SkillW_D=CreateTrigger()
trigger SkillW_E=CreateTrigger()
integer SkillW_A__MAX=0
unit array SkillW_A__Unit
real array SkillW_A__Bonus
integer SkillW_D__MAX=0
unit array SkillW_D__Source
unit array SkillW_D__Target
effect array SkillW_D__Effect
trigger array SkillW_D__Trigger
timer SkillW_E__Timer=CreateTimer()
integer SkillW_E__MAX=0
unit array SkillW_E__Unit
unit array SkillW_E__Target
real array SkillW_E__Time
real array SkillW_E__Area
trigger array SkillW_E__Trigger
real array SkillW_E__Bonus
endglobals
//===========================================================================
function SkillW_A_Func_GetUnitIndex takes unit u returns integer
local integer index=0
loop
exitwhen index==SkillW_A__MAX
if u==SkillW_A__Unit[index] then
return index
endif
set index=index+1
endloop
set u=null
return -1
endfunction
function SkillW_A_Func_Adder takes unit u, integer index returns nothing
local real level=I2R(GetUnitAbilityLevel(u,Custom_SkillW_Ability))
local real r=I2R(GetHeroLevel(u))*(Custom_SkillW_A_Bonus_Base+Custom_SkillW_A_Bonus_PerLvl*(level-1))
call SetHeroAgi(u,GetHeroAgi(u,false)-R2I(SkillW_A__Bonus[index]),true)
call SetHeroAgi(u,GetHeroAgi(u,false)+R2I(r),true)
if GetLocalPlayer()==GetOwningPlayer(u) then
call TextTag("+"+R2SW(r-SkillW_A__Bonus[index],1,1),.023,u,250.,0,255,0,-0.04,.0,2,3)
endif
set SkillW_A__Bonus[index]=r
set u=null
endfunction
function SkillW_A_Func_Condition takes nothing returns boolean
local integer index=SkillW_A_Func_GetUnitIndex(GetTriggerUnit())
if GetLearnedSkill()==Custom_SkillW_Ability and ( not IsUnitIllusion(GetTriggerUnit()) ) then
if index==-1 then
set index=SkillW_A__MAX
set SkillW_A__Unit[SkillW_A__MAX]=GetTriggerUnit()
set SkillW_A__Bonus[SkillW_A__MAX]=.0
call TriggerRegisterUnitEvent(SkillW_B, GetTriggerUnit(), EVENT_UNIT_HERO_LEVEL)
call TriggerRegisterUnitEvent(SkillW_C, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
call TriggerRegisterUnitEvent(SkillW_E, GetTriggerUnit(), EVENT_UNIT_SPELL_EFFECT)
set SkillW_A__MAX=SkillW_A__MAX+1
endif
call SkillW_A_Func_Adder(GetTriggerUnit(),index)
return true
endif
return false
endfunction
//===========================================================================
function SkillW_B_Func_Condition takes nothing returns boolean
local integer index=SkillW_A_Func_GetUnitIndex(GetTriggerUnit())
if GetUnitAbilityLevel(GetTriggerUnit(),Custom_SkillW_Ability)!=0 then
call SkillW_A_Func_Adder(GetTriggerUnit(),index)
return true
endif
return false
endfunction
//===========================================================================
function SkillW_C_Func_Condition takes nothing returns boolean
local real level=I2R(GetUnitAbilityLevel(GetTriggerUnit(),Custom_SkillW_Ability))
local real stat=I2R(GetHeroAgi(GetTriggerUnit(),true))
local real r=(Custom_SkillW_C_Chance_Evade_Base+Custom_SkillW_C_Chance_Evade_PerLvl*(level-1))+stat*(Custom_SkillW_C_Chance_Evade_Stat_Base+Custom_SkillW_C_Chance_Evade_Stat_PerLvl*(level-1))
if GetUnitAbilityLevel(GetTriggerUnit(),Custom_SkillW_Ability)!=0 and GetRandomReal(0.,100.)<=r and GetEventDamage()>1. and GetEventDamageSource()!=GetTriggerUnit() then
call TextTag(Custom_SkillW_C_Strings[GetRandomInt(0,Custom_SkillW_C_StringMaxer)],0.022,GetTriggerUnit(),100.,255,0,0,.0,.06,1,2)
call SetWidgetLife(GetTriggerUnit(),GetWidgetLife(GetTriggerUnit())+GetEventDamage())
return true
endif
return false
endfunction
//===========================================================================
function SkillW_D_Func_GetTriggerIndex takes trigger t returns integer
local integer index=0
loop
exitwhen index==SkillW_D__MAX
if t==SkillW_D__Trigger[index] then
set t=null
return index
endif
set index=index+1
endloop
set t=null
return -1
endfunction
function SkillW_D_Func_GetSourceIndex takes unit u returns integer
local integer index=0
loop
exitwhen index==SkillW_D__MAX
if u==SkillW_D__Source[index] then
set u=null
return index
endif
set index=index+1
endloop
set u=null
return -1
endfunction
function SkillW_D_Func_Second takes nothing returns boolean
local trigger tr=GetTriggeringTrigger()
local unit u=GetEventDamageSource()
local unit t=GetTriggerUnit()
local real level=I2R(GetUnitAbilityLevel(u,Custom_SkillW_Ability))
local real min=Custom_SkillW_C_Multi_Crit_Min_Base+Custom_SkillW_C_Multi_Crit_Min_PerLvl*(level-1)
local real max=Custom_SkillW_C_Multi_Crit_Max_Base+Custom_SkillW_C_Multi_Crit_Max_PerLvl*(level-1)
local real dmg=GetEventDamage()*GetRandomReal(min,max)
local integer index=SkillW_D_Func_GetTriggerIndex(tr)
local boolean b=false
if GetTriggerEventId()==EVENT_UNIT_DAMAGED then
if GetEventDamage()>1. and u==SkillW_D__Source[index] and t==SkillW_D__Target[index] and RegisterDamage then
set b=true
call DisableTrigger(tr)
call QueueUnitAnimation( u, "stand, ready" )
call TextTag(I2S(R2I(dmg))+"!",.023,u,0.,255,0,0,.0,.04,2,3)
call UnitDamageTargetEx(u,t,dmg-GetEventDamage(),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
call DestroyEffect(AddSpecialEffectTarget( GetAbilityEffectById(Custom_SkillW_Ability,EFFECT_TYPE_MISSILE,1), t, "chest"))
endif
else
set b=true
call DisableTrigger(tr)
endif
if b then
call DestroyTrigger(tr)
call DestroyEffect(SkillW_D__Effect[index])
set SkillW_D__MAX=SkillW_D__MAX-1
set SkillW_D__Source[index]=SkillW_D__Source[SkillW_D__MAX]
set SkillW_D__Target[index]=SkillW_D__Target[SkillW_D__MAX]
set SkillW_D__Effect[index]=SkillW_D__Effect[SkillW_D__MAX]
set SkillW_D__Trigger[index]=SkillW_D__Trigger[SkillW_D__MAX]
set SkillW_D__Source[SkillW_D__MAX]=null
set SkillW_D__Target[SkillW_D__MAX]=null
set SkillW_D__Effect[SkillW_D__MAX]=null
set SkillW_D__Trigger[SkillW_D__MAX]=null
endif
set t=null
set u=null
set tr=null
return false
endfunction
function SkillW_D_Func_Condition takes nothing returns boolean
local unit u=GetAttacker()
local unit t=GetTriggerUnit()
local integer index=SkillW_D_Func_GetSourceIndex(u)
local real level=I2R(GetUnitAbilityLevel(u,Custom_SkillW_Ability))
local real stat=I2R(GetHeroAgi(u,true))
local real r=(Custom_SkillW_C_Chance_Crit_Base+Custom_SkillW_C_Chance_Crit_PerLvl*(level-1))+stat*(Custom_SkillW_C_Chance_Crit_Stat_Base+Custom_SkillW_C_Chance_Crit_Stat_PerLvl*(level-1))
if level!=0 and (GetRandomReal(.0,100.)<=r or GetUnitTypeId(u)==Custom_SkillW_HeroID_B) and ( not IsUnitIllusion(GetAttacker()) ) and index==-1 then
call SetUnitAnimation( u, "slam" )
set SkillW_D__Source[SkillW_D__MAX]=u
set SkillW_D__Target[SkillW_D__MAX]=t
set SkillW_D__Trigger[SkillW_D__MAX]=CreateTrigger()
set SkillW_D__Effect[SkillW_D__MAX]=AddSpecialEffectTarget( GetAbilityEffectById(Custom_SkillW_Ability,EFFECT_TYPE_MISSILE,0), u, "hand, left")
call TriggerRegisterDeathEvent( SkillW_D__Trigger[SkillW_D__MAX], t)
call TriggerRegisterUnitEvent( SkillW_D__Trigger[SkillW_D__MAX], t, EVENT_UNIT_DAMAGED)
call TriggerRegisterDeathEvent( SkillW_D__Trigger[SkillW_D__MAX], u)
call TriggerRegisterTimerEvent( SkillW_D__Trigger[SkillW_D__MAX], 2.,false)
call TriggerAddCondition( SkillW_D__Trigger[SkillW_D__MAX], Condition( function SkillW_D_Func_Second) )
set SkillW_D__MAX=SkillW_D__MAX+1
set t=null
set u=null
return true
endif
set t=null
set u=null
return false
endfunction
//===========================================================================
function SkillW_E_Func_GetTriggerIndex takes trigger t returns integer
local integer index=0
loop
exitwhen index==SkillW_E__MAX
if t==SkillW_E__Trigger[index] then
set t=null
return index
endif
set index=index+1
endloop
set t=null
return index
endfunction
function SkillW_E_Func_GetUnitIndex takes unit u returns integer
local integer index=0
loop
exitwhen index==SkillW_E__MAX
if u==SkillW_E__Unit[index] then
set u=null
return index
endif
set index=index+1
endloop
set u=null
return index
endfunction
function SkillW_E_Func_TargetActions takes nothing returns boolean
local trigger tr=GetTriggeringTrigger()
local integer index=SkillW_E_Func_GetTriggerIndex(tr)
local unit u=SkillW_E__Unit[index]
local unit t=SkillW_E__Target[index]
local real stat=I2R(GetHeroAgi(u,true))
local real lvl=I2R(GetUnitAbilityLevel(u,Custom_SkillW_Ability)-1)
local real bd=(Custom_SkillW_E_Bonus_Dmg_Base+Custom_SkillW_E_Bonus_Dmg_PerLvl*lvl)+(stat*(Custom_SkillW_E_Bonus_Stat_Dmg_Base+Custom_SkillW_E_Bonus_Stat_Dmg_PerLvl*lvl))
local boolean b=false
if GetTriggerEventId()==EVENT_UNIT_ATTACKED then
if GetTriggerUnit()==t and GetAttacker()==u then
if IsUnitType(t,UNIT_TYPE_HERO) then
set SkillW_E__Bonus[index]=bd
set STATS_UNIT=u
set STATS_VALUE=SkillW_E__Bonus[index]
set STATS_ADDER=0
call TriggerEvaluate(gg_trg_Stats)
else
call UnitAddAbility(u,Custom_SkillW_Ability_E)
call SetUnitAbilityLevel(u,Custom_SkillW_Ability_E,R2I(lvl+1))
endif
call SetUnitAnimation( u, "slam" )
call TriggerRegisterUnitEvent( SkillW_E__Trigger[index], t, EVENT_UNIT_DAMAGED)
else
call DisableTrigger(tr)
set b=true
endif
elseif GetTriggerEventId()==EVENT_UNIT_DAMAGED then
if GetTriggerUnit()==t and GetEventDamageSource()==u and RegisterDamage then
call DisableTrigger(tr)
set b=true
endif
else
call DisableTrigger(tr)
set b=true
endif
if b then
call UnitRemoveAbility(u,Custom_SkillW_Ability_E)
set STATS_UNIT=u
set STATS_VALUE=-SkillW_E__Bonus[index]
set STATS_ADDER=0
call TriggerEvaluate(gg_trg_Stats)
set SkillW_E__Target[index]=null
call DestroyTrigger(tr)
set SkillW_E__Trigger[index]=null
endif
set tr=null
set u=null
set t=null
return false
endfunction
function SkillW_E_Func_AreaActions takes integer index returns nothing
local group g=CreateGroup()
local player p=GetOwningPlayer(SkillW_E__Unit[index])
local unit t
local real x=GetUnitX(SkillW_E__Unit[index])
local real y=GetUnitY(SkillW_E__Unit[index])
local real angle
local integer i=0
set FilterPlayer=p
set FilterVisible=true
call GroupEnumUnitsInRange(g,x,y,SkillW_E__Area[index],Filter(function GroupFilter))
set FilterPlayer=null
set FilterVisible=false
loop
set t=FirstOfGroup(g)
exitwhen t==null
if GetRandomInt(0,i)==0 then
set i=i+1
set SkillW_E__Target[index]=t
endif
call GroupRemoveUnit(g,t)
endloop
if SkillW_E__Target[index]!=null then
if GetUnitTypeId(SkillW_E__Unit[index])==Custom_SkillW_HeroID_A then
call UnitAddAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_C)
call UnitRemoveAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_C)
endif
call SetUnitPathing(SkillW_E__Unit[index],false)
call SetUnitTimeScale( SkillW_E__Unit[index], 3)
set angle=GetRandomReal(.0,bj_PI*2)
set x=GetUnitX(SkillW_E__Target[index])+50*Cos(angle)
set y=GetUnitY(SkillW_E__Target[index])+50*Sin(angle)
call DestroyTrigger(SkillW_E__Trigger[index])
call SetUnitPosition(SkillW_E__Unit[index],x,y)
call SetUnitFacing(SkillW_E__Unit[index],bj_RADTODEG*Atan2(GetUnitY(SkillW_E__Target[index])-GetUnitY(SkillW_E__Unit[index]),GetUnitX(SkillW_E__Target[index])-GetUnitX(SkillW_E__Unit[index])))
call IssueInstantTargetOrder(SkillW_E__Unit[index],"attack",SkillW_E__Target[index],SkillW_E__Target[index])
set SkillW_E__Trigger[index]=CreateTrigger()
call TriggerRegisterDeathEvent( SkillW_E__Trigger[index], SkillW_E__Target[index])
call TriggerRegisterUnitEvent( SkillW_E__Trigger[index], SkillW_E__Target[index], EVENT_UNIT_ATTACKED)
call TriggerRegisterDeathEvent( SkillW_E__Trigger[index], SkillW_E__Unit[index])
call TriggerRegisterTimerEvent( SkillW_E__Trigger[index], 0.25, false)
call TriggerAddCondition( SkillW_E__Trigger[index], Condition( function SkillW_E_Func_TargetActions) )
else
if GetUnitTypeId(SkillW_E__Unit[index])==Custom_SkillW_HeroID_B then
call UnitAddAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_D)
call UnitRemoveAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_D)
endif
call SetUnitPathing(SkillW_E__Unit[index],true)
call SetUnitTimeScale( SkillW_E__Unit[index], 1)
endif
call DestroyGroup(g)
set p=null
set t=null
set g=null
endfunction
function SkillW_E_Func_Periodic takes nothing returns nothing
local integer index=0
loop
exitwhen index==SkillW_E__MAX
if SkillW_E__Time[index]>.0 and (not IsUnitType(SkillW_E__Unit[index],UNIT_TYPE_DEAD)) then
set SkillW_E__Time[index]=SkillW_E__Time[index]-Custom_SkillW_E_Interval
if SkillW_E__Target[index]==null then
call SkillW_E_Func_AreaActions(index)
endif
else
call UnitRemoveAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_E)
set STATS_UNIT=SkillW_E__Unit[index]
set STATS_VALUE=-SkillW_E__Bonus[index]
set STATS_ADDER=0
call TriggerEvaluate(gg_trg_Stats)
if GetUnitTypeId(SkillW_E__Unit[index])==Custom_SkillW_HeroID_B then
call UnitAddAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_D)
call UnitRemoveAbility(SkillW_E__Unit[index],Custom_SkillW_Ability_D)
endif
call SetUnitPathing(SkillW_E__Unit[index],true)
call SetUnitTimeScale( SkillW_E__Unit[index], 1)
call TriggerExecute(SkillW_E__Trigger[index])
call SetUnitAnimation( SkillW_E__Unit[index], "stand" )
set SkillW_E__MAX=SkillW_E__MAX-1
set SkillW_E__Unit[index]=SkillW_E__Unit[SkillW_E__MAX]
set SkillW_E__Time[index]=SkillW_E__Time[SkillW_E__MAX]
set SkillW_E__Area[index]=SkillW_E__Area[SkillW_E__MAX]
set SkillW_E__Target[index]=SkillW_E__Target[SkillW_E__MAX]
set SkillW_E__Trigger[index]=SkillW_E__Trigger[SkillW_E__MAX]
set SkillW_E__Unit[SkillW_E__MAX]=null
set SkillW_E__Target[SkillW_E__MAX]=null
set SkillW_E__Trigger[SkillW_E__MAX]=null
set SkillW_E__Time[SkillW_E__MAX]=.0
set SkillW_E__Area[SkillW_E__MAX]=.0
set index=index-1
if SkillW_E__MAX==0 then
call PauseTimer(SkillW_E__Timer)
endif
endif
set index=index+1
endloop
endfunction
function SkillW_E_Func_Condition takes nothing returns boolean
local unit u=GetTriggerUnit()
local integer level=GetUnitAbilityLevel(u,Custom_SkillW_Ability)
local real time=Custom_SkillW_E_Time_A-Custom_SkillW_E_Time_B+(Custom_SkillW_E_Time_B*level)
if GetSpellAbilityId()==Custom_SkillW_Ability then
if SkillW_E__MAX==0 then
call TimerStart(SkillW_E__Timer,Custom_SkillW_E_Interval,true,function SkillW_E_Func_Periodic)
endif
set BuffSystem_TARGET=u
set BuffSystem_ID_Ability=Custom_SkillW_Ability_B
set BuffSystem_ID_Buff=Custom_SkillW_Buff_B
set BuffSystem_TIME=time
call TriggerEvaluate(gg_trg_BuffSystem)
set SkillW_E__Unit[SkillW_E__MAX]=u
set SkillW_E__Time[SkillW_E__MAX]=time
set SkillW_E__Area[SkillW_E__MAX]=Custom_SkillW_E_AoE_A-Custom_SkillW_E_AoE_B+(Custom_SkillW_E_AoE_B*level)
set SkillW_E__Target[SkillW_E__MAX]=null
set SkillW_E__Trigger[SkillW_E__MAX]=null
set SkillW_E__MAX=SkillW_E__MAX+1
set u=null
return true
endif
set u=null
return false
endfunction
function SkillW_Func_Init takes nothing returns nothing
local unit u=CreateUnit(Player(15),'u000',0,0,0)
local integer index=0
set Custom_SkillW_C_Strings[0]="Не прошел"
set Custom_SkillW_C_Strings[1]="Увернулся"
set Custom_SkillW_C_Strings[2]="Что-то не так"
set Custom_SkillW_C_Strings[3]="Прошло мимо"
set Custom_SkillW_C_Strings[4]="Забавно..."
set Custom_SkillW_C_StringMaxer=4
loop
call TriggerRegisterPlayerUnitEvent(SkillW_A,Player(index),EVENT_PLAYER_HERO_SKILL,null)
call TriggerRegisterPlayerUnitEvent(SkillW_D,Player(index),EVENT_PLAYER_UNIT_ATTACKED,null)
call SetPlayerAbilityAvailable(Player(index),Custom_SkillW_Ability_E,false)
set index=index+1
exitwhen index==16
endloop
call UnitAddAbility(u,Custom_SkillW_Ability)
call UnitAddAbility(u,Custom_SkillW_Ability_B)
call UnitAddAbility(u,Custom_SkillW_Ability_C)
call UnitAddAbility(u,Custom_SkillW_Ability_D)
call UnitAddAbility(u,Custom_SkillW_Ability_E)
call RemoveUnit(u)
set u=null
call TriggerAddCondition(SkillW_A, Condition(function SkillW_A_Func_Condition))
call TriggerAddCondition(SkillW_B, Condition(function SkillW_B_Func_Condition))
call TriggerAddCondition(SkillW_C, Condition(function SkillW_C_Func_Condition))
call TriggerAddCondition(SkillW_D, Condition(function SkillW_D_Func_Condition))
call TriggerAddCondition(SkillW_E, Condition(function SkillW_E_Func_Condition))
endfunction
Custom Stats System v1.0 (not full)
globals
constant real Custom_STATS_RegenInterval=0.125
unit STATS_UNIT=null
real STATS_VALUE=.0
integer STATS_ADDER=0
integer STATS__MAX=0
trigger array STATS__TRIGGER
unit array STATS__UNIT
real array STATS__DMG
real array STATS__AS
real array STATS__DEF
real array STATS__RHP
real array STATS__RMP
real array STATS__HP
real array STATS__MP
endglobals
//===========================================================================
function Stats_Func_Adder takes unit u, integer value, string stat returns nothing
local integer i=0
local integer ii=0
local boolean b=false
if stat=="dmg" then
loop
call UnitMakeAbilityPermanent(u,false,STATS_DMG_Ability[i])
call UnitRemoveAbility(u,STATS_DMG_Ability[i])
exitwhen i==STATS_DMG_MaxInteger
set i=i+1
endloop
if value>STATS_DMG_MaxValue then
set value=STATS_DMG_MaxValue
elseif value<-STATS_DMG_MaxValue then
set value=-STATS_DMG_MaxValue
endif
if value<0 then
set b=true
set value=-value
endif
if value>0 then
loop
exitwhen i<0
set ii=value/STATS_DMG_Integer[i]
if ii>0 then
if b then
call UnitAddAbility(u,STATS_DMG_Ability[i])
call SetUnitAbilityLevel(u,STATS_DMG_Ability[i],2)
else
call UnitAddAbility(u,STATS_DMG_Ability[i])
endif
call UnitMakeAbilityPermanent(u,true,STATS_DMG_Ability[i])
endif
set value=value-(ii*STATS_DMG_Integer[i])
set i=i-1
endloop
endif
endif
set stat=null
set u=null
endfunction
//===========================================================================
function Stats_Func_GetUnitIndex takes unit u returns integer
local integer index=0
loop
exitwhen index==STATS__MAX
if u==STATS__UNIT[index] then
set u=null
return index
endif
set index=index+1
endloop
set u=null
return -1
endfunction
function Stats_Func_GetTriggerIndex takes trigger t returns integer
local integer index=0
loop
exitwhen index==STATS__MAX
if t==STATS__TRIGGER[index] then
set t=null
return index
endif
set index=index+1
endloop
set t=null
call DisplayTimedTextToPlayer(Player(0),0,0,10.,"|cffff0000ОШИБКА! Искомый триггер не находится в цикле!|r")
return -1
endfunction
function Stats_Func_Regen takes unit u, real rh, real rm returns boolean
local real hp=GetWidgetLife(u)
local real mp=GetUnitState(u,UNIT_STATE_MANA)
if rh>.0 then
set hp=hp+rh
elseif rh<.0 then
if (hp-1)>-rh then
set hp=hp+rh
else
set hp=1
endif
endif
if rm>0. then
set mp=mp+rm
elseif rm<.0 then
if mp>-rm then
set mp=mp+rm
else
set mp=0
endif
endif
call SetWidgetLife(u,hp)
call SetUnitState(u,UNIT_STATE_MANA, mp)
set u=null
return true
endfunction
function Stats_Func_Checker takes nothing returns boolean
local trigger t=GetTriggeringTrigger()
local boolean b=false
local integer index=Stats_Func_GetTriggerIndex(t)
if index!=-1 then
if GetTriggerEventId()==EVENT_UNIT_DEATH and not IsUnitType(STATS__UNIT[index],UNIT_TYPE_HERO) then
set b=true
call DisableTrigger(t)
else
if STATS__DMG[index]==0 and STATS__DEF[index]==0 and STATS__AS[index]==0 and STATS__RHP[index]==.0 and STATS__RMP[index]==.0 and STATS__HP[index]==.0 and STATS__MP[index]==.0 then
set b=true
call DisableTrigger(t)
else
if (STATS__RHP[index]!=0. or STATS__RMP[index]!=0) and (not IsUnitType(STATS__UNIT[index],UNIT_TYPE_DEAD)) then
call Stats_Func_Regen(STATS__UNIT[index], STATS__RHP[index]*Custom_STATS_RegenInterval, STATS__RMP[index]*Custom_STATS_RegenInterval)
endif
endif
endif
else
set b=true
call DisableTrigger(t)
endif
if b then
call DestroyTrigger(t)
call Stats_Func_Adder(STATS__UNIT[index],R2I(-STATS__DMG[index]),"dmg")
call Stats_Func_Adder(STATS__UNIT[index],R2I(-STATS__DEF[index]),"def")
call Stats_Func_Adder(STATS__UNIT[index],R2I(-STATS__AS[index]),"as")
set STATS__RHP[index]=.0
set STATS__RMP[index]=.0
set STATS__MAX=STATS__MAX-1
set STATS__UNIT[index]=STATS__UNIT[STATS__MAX]
set STATS__TRIGGER[index]=STATS__TRIGGER[STATS__MAX]
set STATS__DMG[index]=STATS__DMG[STATS__MAX]
set STATS__DEF[index]=STATS__DEF[STATS__MAX]
set STATS__AS[index]=STATS__AS[STATS__MAX]
set STATS__RHP[index]=STATS__RHP[STATS__MAX]
set STATS__RMP[index]=STATS__RMP[STATS__MAX]
set STATS__MP[index]=STATS__MP[STATS__MAX]
set STATS__HP[index]=STATS__HP[STATS__MAX]
set STATS__UNIT[STATS__MAX]=null
set STATS__TRIGGER[STATS__MAX]=null
set STATS__DMG[STATS__MAX]=.0
set STATS__DEF[STATS__MAX]=.0
set STATS__AS[STATS__MAX]=.0
set STATS__RHP[STATS__MAX]=.0
set STATS__RMP[STATS__MAX]=.0
set STATS__MP[STATS__MAX]=.0
set STATS__HP[STATS__MAX]=.0
endif
set t=null
return false
endfunction
function Stats_Func_Main takes nothing returns boolean
local unit u=STATS_UNIT
local integer index=Stats_Func_GetUnitIndex(u)
if index==-1 then
set index=STATS__MAX
set STATS__UNIT[STATS__MAX]=u
set STATS__TRIGGER[STATS__MAX]=CreateTrigger()
call TriggerRegisterUnitEvent(STATS__TRIGGER[STATS__MAX],u,EVENT_UNIT_DEATH)
call TriggerRegisterTimerEvent(STATS__TRIGGER[STATS__MAX],Custom_STATS_RegenInterval,true)
call TriggerAddCondition(STATS__TRIGGER[STATS__MAX],Condition(function Stats_Func_Checker))
set STATS__MAX=STATS__MAX+1
endif
if STATS_ADDER==0 then
set STATS__DMG[index]=STATS__DMG[index]+STATS_VALUE
call Stats_Func_Adder(STATS__UNIT[index],R2I(STATS__DMG[index]),"dmg")
endif
set STATS_UNIT=null
set STATS_VALUE=.0
set STATS_ADDER=0
set u=null
return true
endfunction
function STATS_Func_Init takes nothing returns nothing
set gg_trg_Stats=CreateTrigger()
call TriggerAddCondition(gg_trg_Stats, Condition( function Stats_Func_Main))
endfunction
Мое желание оптимизировать на сколько возможно. Увеличение до 0.03125 сек. периода так же входит в оптимизацию, но не могу додумать, как без периода запустить по повторной функцию на поиск цели.
Добавлю еще часть от системы добавления характеристик. На случай возникновения вопроса о системе.
Custom Stats System v1.0 (DMG part)
globals
integer STATS_DMG_MaxValue=0
integer STATS_DMG_MaxInteger=0
integer array STATS_DMG_Ability
integer array STATS_DMG_Integer
endglobals
function STATS_DMG_Func_Init takes nothing returns nothing
local integer index=1
local unit u=CreateUnit(Player(15),'hpea',0,0,0)
set STATS_DMG_Ability[0]='A009'
set STATS_DMG_Ability[1]='A00A'
set STATS_DMG_Ability[2]='A00B'
set STATS_DMG_Ability[3]='A00C'
set STATS_DMG_Ability[4]='A00D'
set STATS_DMG_Ability[5]='A00E'
set STATS_DMG_Ability[6]='A00F'
set STATS_DMG_Ability[7]='A00G'
set STATS_DMG_Ability[8]='A00H'
set STATS_DMG_Ability[9]='A00I'
set STATS_DMG_Ability[10]='A00J'
set STATS_DMG_Ability[11]='A00K'
set STATS_DMG_MaxInteger=11
set STATS_DMG_Integer[0]=1
set STATS_DMG_MaxValue=1
loop
set STATS_DMG_Integer[index]=STATS_DMG_Integer[index-1]*2
set STATS_DMG_MaxValue=STATS_DMG_MaxValue+STATS_DMG_Integer[index]
exitwhen index==STATS_DMG_MaxInteger
set index=index+1
endloop
loop
call UnitAddAbility(u,STATS_DMG_Ability[index])
exitwhen index==0
set index=index-1
endloop
call RemoveUnit(u)
set u=null
endfunction
Кто заинтересован способностью теперь может скачать и протестировать карту с героем.
В карте примере участвуют еще две способности, которые в дальнейшем тоже подвергнутся оптимизации.
В карте примере участвуют еще две способности, которые в дальнейшем тоже подвергнутся оптимизации.
Поясняю, сия функция находится ниже чем отлов урона, далее сия функция требует целочисленную (index героя).
Запустить нативкой ExecuteFunc не выйдет, в силу требуемой целочисленной.
Ред. Clamp
Пассивно дает шанс при атаке нанести многократный урон и дает шанс избежать любой урон, а так же увеличивает добавку к ловкости за каждый уровень.
При использовании на время действия способности Герой приобретает максимальную скорость и телепортируется к случайному врагу, что находится в области действия. Если враг герой, то наносит доп. урон, иначе урон снижается.
При активации выбираем юнита, проверяем герой или нет и по результату проверки интовой переменной даём значение, равное нужному урону. Затем телепортируем и наносим урон из переменной.
SkillW_E_Func_GetUnitIndex - выдает порядковый номер героя из массива.
SkillW_E_Func_TargetActions - отвечает за отлов атаки и урона.
SkillW_E_Func_AreaActions - отвечает за поиск цели.
SkillW_E_Func_Periodic - отвечает за время действия и обнуления массива.
SkillW_E_Func_Condition - отвечает за использование способности.
Clamp:
По поводу скорости, дается аура (торнадо), что дает макс. скорость атаки и ходьбы.
Урон зависит от ловкости, тем самым здесь участвует система добавления характеристик, в данном случае атаки. Урон же, дается только на одну атаку, поэтому я и мучаюсь с этим отловом атаки и урона.
К тому же я кинул карту с героем, если кому угодно, может протестировать героя и поделиться своим впечатлением.
НО предупреждаю, что Третья способность еще не оптимизирована как мне хочется, в силу этого из-за нее во время теста могут быть лаги.
Ред. nvc123
а не плодить кучу триггеров с одинаковым событием
и не смотреть на то как они отбирают друг у друга процессорное время
Но как я определю нанес ли Герой урон атакованному? Ведь флудить в сия триггере
А так выходит сразу отлов атаки => отлов урона => уничтожение триггера и обнуление массива. Иль это медленней нежили создание системы по отлову атаки и урона?
Ред. nvc123
ты же сказал что событие атаки у тебя используется не только в этом триггере и не только во время этой способности
вот я и говорю что вместо нескольких триггеров с 1 событием лучше использовать 1 триггер с этим же событием
включать/выключать триггер это больший бред чем удаление
Ред. nvc123
учитывая вес триггера и то что триггеры это потоки получается неплохая экономия
в функции SkillW_A_Func_Adder переменная левел юзается только 1 раз а значит нафиг не нужна
также не стоит писать в условиях большой код (иногда бывает баг из за которого условие не успевает вернуть результат а действие уже проверяет результат условия)
когда твоего юнита атакуют то будет срабатывать 2 триггера и у обоих будут проверятся условия
вместо этого можно просто написать в действии триггера с общим событием атаки
а your code это код который ты собирался выполнять для этого юнита
не кажется что это проще чем создавать триггер ради 1 юнита
Ред. DazzleFirst
Это не бред, ибо на время действия способности создается один триггер на отлов атаки и урона именной одной взятой цели, а не нескольких, как ты мне предлагаешь. Ибо при включенной способности каждый атакованный будет проверятся, а скорость-то велика (менее 1 раза в 0.02), тем самым пойдет конкретная нагрузка с перезапусками логических и поиск цели в массивах. А с моим способом проверяется только единственный атакованный с запуском только одного массива, а потом удаление триггера, дабы триггер более не проверял атакованного или получившего урон и не нагружал варчик.
до этого ты говорил что да
Ред. DazzleFirst
Ред. Кет
Или сразу количество прошедего времени посчитать.
Ред. nvc123
DazzleFirst:
+ атаку по твоему юниту отлавливает N+1 раз
я же предлагаю отлавливать лишь 1 раз
т. к. у тебя более 1 пассивки то N>1
следовательно мой вариант выгоднее
ибо он требует в N раз меньше оперативной памяти и процессорного времени
SkillW_E_Func_Periodic - функция, что вызывается каждый период времени.
SkillW_E_Func_AreaActions - функция, что отвечает за поиск цели. Эту же функцию мне хочется вызывать после нанесения урона. В ней:
Первым делом функция срабатывает после того как цель способности (выбирается случайно в области действия) была атакована. Далее проверка на атакующего
Далее проверяем
Даем дополнительную атаку на один удар.
Даем способность, что уменьшает наносимый урон нашим Героем.
Если получивший урон и есть наша цель способности, нанесший урон и есть наш Герой, полученный урон не от способности, то
Надеюсь уже совсем хорошо пояснил, что за что отвечает. И понятно почему нужно отлавливать как атаку так и урон.
Теперь задача:
Как реализовать вызов функции SkillW_E_Func_AreaActions из функции SkillW_E_Func_TargetActions после уничтожение триггера в последней функции?
вместо этого можно у пасивки сделать проверку что скил включен и атакованый юнит == наш юнит
я всё правильно понял
это ты просто тупиш
И меня не евенты интересуют, а функции и их корешки...