Добавлен ArhiMEN,
опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Способность
Версия Warcraft:
1.26 (default)
Решил потестировать параболу и сделал такую способность спасибо UselessLORD за помощь. Механика способности такая - герой вместо стандартной атаки запускает огненный снаряд, который взрывается в точки падения, наносит урон в 200% от интелекта и отскакивает к ближайшим противникам 1-5 раз.
Код1
globals
hashtable H = InitHashtable() //можете приравнять к вашей таблице
location LocationZ = Loaction(0, 0)
integer NimbedoId = 'O000' //Id героя
integer FireBomb = 'A00C' //Id способности
integer FireBombUnitId = 'e005' //Id дамми юнита, который летит
integer FireBombChance = 100 //Шанс на прок способности
endglobals
library FilterLib
function IsDead takes unit u returns boolean
return GetWidgetLife(u) < 0.405 or IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
function Enemy takes nothing returns boolean
return IsDead(GetFilterUnit())==false and IsPlayerAlly(GetOwningPlayer(LoadUnitHandle(H,'Unit','Unit')), GetOwningPlayer(GetFilterUnit())) == false and GetUnitAbilityLevel(GetFilterUnit(),'Aloc')==0 and GetUnitAbilityLevel(GetFilterUnit(),'Avul')==0 and GetUnitAbilityLevel(GetFilterUnit(),'Bcyc')==0
endfunction
endlibrary
function GetLocalZ takes real x, real y returns real
call MoveLocation(LocationZ, x, y)
return GetLocationZ(LocationZ)
endfunction
function GetUnitZ takes unit u returns real
return GetLocalZ(GetUnitX(u),GetUnitY(u)) + GetUnitFlyHeight(u)
endfunction
Код2 (создать триггер с названием FireBomb)
function Trig_FireBomb_Actions takes nothing returns nothing
local unit Caster = GetAttacker()
local unit Target = GetTriggerUnit()
local real x0 = GetUnitX(Caster)
local real y0 = GetUnitY(Caster)
local real x1 = GetUnitX(Target)
local real y1 = GetUnitY(Target)
local real d = SquareRoot( (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) )
local real h = d / 4.0
local real h0 = GetUnitZ(Caster) + 40.0
local real h1 = GetUnitFlyHeight(Target)
local real a = bj_RADTODEG * Atan2(y1 - y0, x1 - x0)
local player Owner = GetOwningPlayer(Caster)
local timer Timer = CreateTimer()
local integer id = GetHandleId(Timer)
local unit dummy
call IssueImmediateOrder(Caster, "stop")
call SetUnitAnimation(Caster, "attack" )
call IssueTargetOrder(Caster, "attack", Target)
if GetRandomInt(1, 100) <= FireBombChance then
set dummy = CreateUnit(GetOwningPlayer(Caster), FireBombUnitId, x0 + 100.0 * Cos(a * bj_DEGTORAD), y0 + 100.0 * Sin(a * bj_DEGTORAD), a)
call ShowUnit(dummy, false)
call TimerStart(Timer, 0.03, true, function FireBomb_Move)
call SaveUnitHandle(H, id, StringHash("Fire Bomb"), dummy)
call SaveUnitHandle(H, id, 'Targ', Target)
call SaveReal(H, id, StringHash("Start X"), x0)
call SaveReal(H, id, StringHash("Start Y"), y0)
call SaveReal(H, id, StringHash("End X"), x1)
call SaveReal(H, id, StringHash("End Y"), y1)
call SaveReal(H, id, StringHash("Distance"), d)
call SaveReal(H, id, StringHash("Max Height"), h)
call SaveReal(H, id, StringHash("Start Height"), h0)
call SaveReal(H, id, StringHash("End Height"), h1)
call SaveReal(H, id, 'time', 0.0)
call SaveEffectHandle(H, id, 'effe', AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", Caster, "weapon"))
call SaveInteger(H, GetHandleId(dummy), 'boun', GetUnitAbilityLevel(Caster, FireBomb))
call SaveUnitHandle(H, GetHandleId(dummy), 'nimb', Caster)
endif
set Caster = null
set Target = null
set Timer = null
set dummy = null
endfunction
function Trig_FireBomb_Cond takes nothing returns boolean
return GetUnitTypeId(GetAttacker()) == NimbedoId
endfunction
//===========================================================================
function InitTrig_FireBomb takes nothing returns nothing
local integer index
local trigger T1 = CreateTrigger()
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(T1, Player(index), EVENT_PLAYER_UNIT_ATTACKED, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(T1,function Trig_FireBomb_Cond)
call TriggerAddAction(T1, function Trig_FireBomb_Actions)
set T1 = null
endfunction
Код3 (создать триггер с названием FireBombMove)
library FireBombMove
function IsDead2 takes unit u returns boolean
return GetWidgetLife(u) < 0.405 or IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
function Enemy2 takes nothing returns boolean
return GetFilterUnit() != LoadUnitHandle(H, 'Targ', 'Unit') and IsDead(GetFilterUnit())==false and IsPlayerAlly(GetOwningPlayer(LoadUnitHandle(H,'Cast','Unit')), GetOwningPlayer(GetFilterUnit())) == false and GetUnitAbilityLevel(GetFilterUnit(),'Aloc')==0 and GetUnitAbilityLevel(GetFilterUnit(),'Avul')==0 and GetUnitAbilityLevel(GetFilterUnit(),'Bcyc')==0
endfunction
function ParabolaZ2 takes real h0, real h1, real h, real d, real d1 returns real
return ((4 * h / d) * (d - d1) + h1 - h0) * (d1 / d) + h0
endfunction
function FireBomb_Move takes nothing returns nothing
local timer Timer = GetExpiredTimer()
local integer id = GetHandleId(Timer)
local unit dummy = LoadUnitHandle(H, id, StringHash("Fire Bomb"))
local real x0 = LoadReal(H, id, StringHash("Start X"))
local real y0 = LoadReal(H, id, StringHash("Start Y"))
local real x1 = LoadReal(H, id, StringHash("End X"))
local real y1 = LoadReal(H, id, StringHash("End Y"))
local real d = LoadReal(H, id, StringHash("Distance"))
local real h = LoadReal(H, id, StringHash("Max Height"))
local real h0 = LoadReal(H, id, StringHash("Start Height"))
local real h1 = LoadReal(H, id, StringHash("End Height"))
local real a = bj_RADTODEG * Atan2(y1 - y0, x1 - x0)
local real dx
local real dy
local real d1
local real d2
local real height
local group g = CreateGroup()
local unit Target
local real Time = LoadReal(H, id, 'time') + 0.03
call SaveReal(H, id, 'time', Time)
if Time >= 0.48 then
if Time == 0.48 then
call UnitRemoveAbility(dummy, 'Aloc')
call ShowUnit(dummy, true)
call UnitAddAbility(dummy, 'Aloc')
call DestroyEffect(LoadEffectHandle(H, id, 'effe'))
endif
set dx = GetUnitX(dummy)
set dy = GetUnitY(dummy)
set d1 = SquareRoot( (dx - x0) * (dx - x0) + (dy - y0) * (dy - y0) )
set d2 = SquareRoot( (x1 - dx) * (x1 - dx) + (y1 - dy) * (y1 - dy) )
set height = ParabolaZ2(h0, h1, h, d, d1)
if d2 <= 20.0 then
call ShowUnit(dummy, false)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl", dx, dy))
call PauseTimer(Timer)
call DestroyTimer(Timer)
call SaveUnitHandle(H, 'Unit', 'Unit', LoadUnitHandle(H, GetHandleId(dummy), 'nimb'))
call GroupEnumUnitsInRange(g, dx, dy, 200.0, function Enemy)
loop
set Target = FirstOfGroup(g)
exitwhen Target == null
call UnitDamageTarget(LoadUnitHandle(H, GetHandleId(dummy), 'nimb'), Target, GetHeroInt(LoadUnitHandle(H, GetHandleId(dummy), 'nimb'), true) * 2.0, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call GroupRemoveUnit(g, Target)
endloop
call GroupClear(g)
if LoadInteger(H, GetHandleId(dummy), 'boun') > 0 then
call SaveUnitHandle(H, 'Cast', 'Unit', dummy)
call SaveUnitHandle(H, 'Targ', 'Unit', LoadUnitHandle(H, id, 'Targ'))
call GroupEnumUnitsInRange(g, dx, dy, 770.0, function Enemy2)
loop
set Target = GroupPickRandomUnit(g)
exitwhen Target == null
set dx = GetUnitX(Target)
set dy = GetUnitY(Target)
set d2 = SquareRoot( (x1 - dx) * (x1 - dx) + (y1 - dy) * (y1 - dy) )
if d2 < 300.0 or d2 > 700.0 then
call GroupRemoveUnit(g, Target)
else
call FlushChildHashtable(H, id)
call SaveUnitHandle(H, 'Targ', 'Unit', Target)
call SaveInteger(H, GetHandleId(dummy), 'boun', LoadInteger(H, GetHandleId(dummy), 'boun') - 1)
call TriggerExecute(gg_trg_FireBombBounce)
exitwhen Target != null
endif
endloop
else
call RemoveUnit(dummy)
call FlushChildHashtable(H, GetHandleId(dummy))
endif
else
call SetUnitX(dummy, dx + 25.0 * Cos(a * bj_DEGTORAD))
call SetUnitY(dummy, dy + 25.0 * Sin(a * bj_DEGTORAD))
call SetUnitFlyHeight(dummy, height, 0.0)
endif
endif
call GroupClear(g)
call DestroyGroup(g)
set Timer = null
set dummy = null
set g = null
set Target = null
endfunction
endlibrary
Код4 (создать триггер с названием FireBombBounce)
function Trig_FireBombBounce_Actions takes nothing returns nothing
local unit Caster = LoadUnitHandle(H, 'Cast', 'Unit')
local unit Target = LoadUnitHandle(H, 'Targ', 'Unit')
local real x0 = GetUnitX(Caster)
local real y0 = GetUnitY(Caster)
local real x1 = GetUnitX(Target)
local real y1 = GetUnitY(Target)
local real d = SquareRoot( (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) )
local real h = d / 4.0
local real h0 = GetUnitFlyHeight(Caster)
local real h1 = GetUnitFlyHeight(Caster)
local real a = bj_RADTODEG * Atan2(y1 - y0, x1 - x0)
local player Owner = GetOwningPlayer(Caster)
local timer Timer = CreateTimer()
local integer id = GetHandleId(Timer)
call TimerStart(Timer, 0.03, true, function FireBomb_Move)
call SaveUnitHandle(H, id, StringHash("Fire Bomb"), Caster)
call SaveUnitHandle(H, id, 'Targ', Target)
call SaveReal(H, id, StringHash("Start X"), x0)
call SaveReal(H, id, StringHash("Start Y"), y0)
call SaveReal(H, id, StringHash("End X"), x1)
call SaveReal(H, id, StringHash("End Y"), y1)
call SaveReal(H, id, StringHash("Distance"), d)
call SaveReal(H, id, StringHash("Max Height"), h)
call SaveReal(H, id, StringHash("Start Height"), h0)
call SaveReal(H, id, StringHash("End Height"), h1)
call SaveReal(H, id, 'time', 0.0)
call SaveEffectHandle(H, id, 'effe', AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", Caster, "weapon"))
set Caster = null
set Target = null
set Timer = null
endfunction
//===========================================================================
function InitTrig_FireBombBounce takes nothing returns nothing
set gg_trg_FireBombBounce = CreateTrigger()
call TriggerAddAction(gg_trg_FireBombBounce, function Trig_FireBombBounce_Actions)
endfunction
Как импортировать
1). Скопировать код и вставить в карту.
2). Создать пустую способность
3). Создать дамми юнита
4). Внести все необходимые правки в глобальные переменные из Код1
5). Добавить способность герою
2). Создать пустую способность
3). Создать дамми юнита
4). Внести все необходимые правки в глобальные переменные из Код1
5). Добавить способность герою
П.с. понимаю что гифка не очень, но если смотреть на х3, то норм
Другие способности героя можно посмотреть у меня в блоге))
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован rsfghd
Заметил другие баги пока тестировал и на видео тоже можно их наблюдать, огни порой не отскакивают даже, след от огня пропадает куда-то, летающие юниты под игнор идут, нормализацию анимации атаки вообще поленился сделать
вот формулы параболы, юзай вторую xgm.guru/p/wc3/parabolicmovement
Отредактирован Гуванч
переменную типа игрок не обнулил