В этой статье создадим заклинание, чтобы лучше ознакомиться с некоторыми возможностями и попрактиковаться Предполагается что читатель ознакомился со статьей по основам джаса В итоге будет такое: В области появляется сияющее кольцо, отшвыривающее врагов, затем взрыв из лучей в разные стороны, наносящие урон, в итоге появляется тролль, награждающий героя ледяным щитом, и исчезает через 6 секунд Будут рассмотрены циклы, функции, работа с группами, и прочие мелочи. Сделайте способность, применяемую на область - я взял канал Создадим триггер, назовем abc, событие - приводит способность в действие, условие - ваша способность Правка - конвертировать в текст Перемещаем код для удобства, упрощаем условие, я сделал так: Code function Trig_abc_Actions takes nothing returns nothing endfunction
//=========================================================================== function Trig_abc_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A000' endfunction // function InitTrig_abc takes nothing returns nothing set gg_trg_abc = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_abc, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_abc, Condition( function Trig_abc_Conditions ) ) call TriggerAddAction( gg_trg_abc, function Trig_abc_Actions ) endfunction далее работаем с функцией действий Code
function Trig_abc_Actions takes nothing returns nothing endfunction создадим локальные переменные: Code
function Trig_abc_Actions takes nothing returns nothing local unit u= GetTriggerUnit() // колдун // координаты local real x= GetSpellTargetX() local real y= GetSpellTargetY() // для цикла local integer i=1 local integer j=1 // будущий тролль local unit d
// обнуление set d=null set u=null endfunction далее создадим пару функций для спецэффектов Code
function DE takes string s, real x, real y returns nothing call DestroyEffect( AddSpecialEffect(s,x,y) ) endfunction
function DET takes string s, unit u, string a returns nothing call DestroyEffect( AddSpecialEffectTarget(s,u,a) ) endfunction и еще две для измерения расстояния и угла: Code
function Dist takes real x1, real y1, real x2, real y2 returns real return SquareRoot( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) ) endfunction
function Angle takes real x1, real y1, real x2, real y2 returns real return Atan2( y2-y1,x2-x1 ) endfunction и функцию отталкивания, точнее она просто мгновенно помещает всех на расстоянии от центра (x,y) Code function PushAoe takes unit u, real x, real y, real r, string s returns nothing local group g= CreateGroup() local unit e= null local player p= GetOwningPlayer(u) local real ex local real ey
call GroupEnumUnitsInRange(g,x,y,r,null)
loop set e=FirstOfGroup(g) exitwhen e==null // пробег по группе if IsUnitEnemy(e,p) then call DET(s ,e,"origin") set ex= GetWidgetX(e) set ey= GetWidgetY(e) call SetUnitPosition(e, x+r*Cos(Angle(x,y,ex,ey)), y+r*Sin(Angle(x,y,ex,ey)) ) endif // удаляем использованного юнита и продолжаем, пока остаются юниты call GroupRemoveUnit(g,e) endloop call DestroyGroup(g) set g=null endfunction возвращаемся в функцию действий и используем сделанные функции, затем создаем сопровождающие эффекты циклом: Code call DE("Abilities\\Spells\\Items\\AIso\\AIsoTarget.mdl",x,y) call PushAoe(u,x,y,250., "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl")
loop exitwhen i>12 // call DE("Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl", x+250.*CosBJ(i*30.), y+250.*SinBJ(i*30.) ) // set i=i+1 endloop создадим функцию нанесения урона по области, используем в ней другой способ работы с группой Code function DMG takes nothing returns nothing call UnitDamageTarget(GetTriggerUnit(),GetEnumUnit(),bj_forLoopAIndex,true,true,null,null,null) endfunction
function abcFilt takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) endfunction
function GroupDmg takes unit u, real x, real y, real r, real dmg returns nothing local group g= CreateGroup() call GroupEnumUnitsInRange(g,x,y,r, Filter(function abcFilt) ) set bj_forLoopAIndex=R2I(dmg) // R2I() - конвертация реального числа в целое call ForGroup(g,function DMG) call DestroyGroup(g) set g=null endfunction - к такому способу обычно идут еще две функции, не слишком удобно а для переноса урона в функцию DMG используем вшитую переменную варкрафта - bj_forLoopAIndex, хотя можно было поискать реальную... продолжаем: ждем полсекунды, затем двойной цикл для эффектов и урона по их местам. Здесь 'j' - количество лучей, 'i' - длина луч ждем 0.4+ секунды таким образом, чтобы избежать проблем с "зависаниями игрока", которые обычно портят ожидания это намного удобнее, чем создавать таймер, однако точное время оно ждет только на средней скорости игры Code
call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1)
loop exitwhen j>10 set i=1 loop exitwhen i>8
call DE("Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl", x+i*100.*CosBJ(j*36.), y+i*100.*SinBJ(j*36.)) call GroupDmg(u, x+i*100.*CosBJ(j*36.), y+i*100.*SinBJ(j*36.), 128., 50.)
set i=i+1 endloop set j=j+1 endloop снова ждем и создаем тролля, ставим время его жизни на 6 секунд, приказываем повесить щит Code call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1)
set d= CreateUnit(GetOwningPlayer(u),'nith',x,y,270.) call UnitApplyTimedLife(d,'BTLF',6.) call IssueTargetOrder(d, "frostarmor" ,u) в итоге будет так: Code function DE takes string s, real x, real y returns nothing call DestroyEffect( AddSpecialEffect(s,x,y) ) endfunction
function DET takes string s, unit u, string a returns nothing call DestroyEffect( AddSpecialEffectTarget(s,u,a) ) endfunction
function Dist takes real x1, real y1, real x2, real y2 returns real return SquareRoot( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) ) endfunction
function Angle takes real x1, real y1, real x2, real y2 returns real return Atan2( y2-y1,x2-x1 ) endfunction
function DMG takes nothing returns nothing call UnitDamageTarget(GetTriggerUnit(),GetEnumUnit(),bj_forLoopAIndex,true,true,null,null,null) endfunction
function abcFilt takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) endfunction
function GroupDmg takes unit u, real x, real y, real r, real dmg returns nothing local group g= CreateGroup() // call GroupEnumUnitsInRange(g,x,y,r,Filter(function abcFilt)) set bj_forLoopAIndex=R2I(dmg) call ForGroup(g,function DMG) // call DestroyGroup(g) set g=null endfunction
function PushAoe takes unit u, real x, real y, real r, string s returns nothing local group g= CreateGroup() local unit e= null local player p= GetOwningPlayer(u) local real ex local real ey
call GroupEnumUnitsInRange(g,x,y,r,null)
loop set e=FirstOfGroup(g) exitwhen e==null
if IsUnitEnemy(e,p) then call DET(s ,e,"origin") set ex= GetWidgetX(e) set ey= GetWidgetY(e) call SetUnitPosition(e, x+r*Cos(Angle(x,y,ex,ey)), y+r*Sin(Angle(x,y,ex,ey)) ) endif
call GroupRemoveUnit(g,e) endloop call DestroyGroup(g) set g=null endfunction
function Trig_abc_Actions takes nothing returns nothing local unit u= GetTriggerUnit() local real x= GetSpellTargetX() local real y= GetSpellTargetY() local integer i=1 local integer j=1 local unit d
call DE("Abilities\\Spells\\Items\\AIso\\AIsoTarget.mdl",x,y) call PushAoe(u,x,y,250., "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl")
loop exitwhen i>12 // call DE("Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl",x+250.*CosBJ(i*30.),y+250.*SinBJ(i*30.)) // set i=i+1 endloop
call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1)
loop exitwhen j>10 set i=1 loop exitwhen i>8
call DE("Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl",x+i*100.*CosBJ(j*36.),y+i*100.*SinBJ(j*36.)) call GroupDmg(u,x+i*100.*CosBJ(j*36.),y+i*100.*SinBJ(j*36.),128.,50.)
set i=i+1 endloop set j=j+1 endloop
call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1) call TriggerSleepAction(.1)
set d= CreateUnit(GetOwningPlayer(u),'nith',x,y,270.) call UnitApplyTimedLife(d,'BTLF',6.) call IssueTargetOrder(d, "frostarmor" ,u)
set d=null set u=null endfunction
//=========================================================================== function Trig_abc_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A000' endfunction // function InitTrig_abc takes nothing returns nothing set gg_trg_abc = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_abc, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_abc, Condition( function Trig_abc_Conditions ) ) call TriggerAddAction( gg_trg_abc, function Trig_abc_Actions ) endfunction
|