Ok, i know there are a lot of Omnislash spells encoded, but only found one approved in THW, and it's GUI. Anyway, i'm not going to send this as a resource because people don't like repeated spells
Requirements:
GT - Jesus4Lyf
TimerUtils - Vexorian
Here's a test map, wich has the dummy spell (i used Channel)
http://www.epicwar.com/maps/156575/
And the code:
Recommendations?
Updates:
15/12/10 : Added method to calculate number of slashs, thanks Carnerox.
Requirements:
GT - Jesus4Lyf
TimerUtils - Vexorian
Here's a test map, wich has the dummy spell (i used Channel)
http://www.epicwar.com/maps/156575/
And the code:
JASS:
scope Omnislash // requires TimerUtils, GT
globals
private constant integer SPELL_ID = 039;A000039; // The ID of the ability
private constant real AREA = 450. // Range of the ennumeration
private constant real LOOP = .4 // Period
private constant string SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl" // Principal SFX
private constant string SFX2 = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl" // SFX created in each slash
private constant string SFXATTACH = "weapon"
private constant string SFX2ATTACH = "chest"
private constant string ATTACKSTG = "attack" // You can change it to "attack slam" if you want
private constant boolean INVULNERABLE = true // Dooes Yurnero becomes invulnerable while omnislashing?
private constant attacktype ATTACKTYPE = ATTACK_TYPE_HERO
private constant damagetype DAMAGETYPE = DAMAGE_TYPE_NORMAL
private group Enum_Group = CreateGroup() // Group for the enum, is always empty
private constant integer MAX_ENUM_UNITS = 30 // Max size of the array...
endglobals
private struct OmniStruct
private effect sfx // Phoenix effect
private player p // Owning player of casting unit
private unit c // Casting unit
private unit t // Target unit
private integer lvl
private integer cnt// Number of slashes
private timer tm
private real ang // Angle used to define a random position around the target
private real cX
private real cY
private real tX
private real tY
private real dmg // Damage, it's a random number between 150 and 250 in each slash
private integer num=2 // Number of actual slashes
private static unit array targets[MAX_ENUM_UNITS] // Used for group the targets and select a random one from there
private static integer index=0
method Slashes takes integer level returns integer
return R2I(0.50*level*level+0.50*level+2.00)
endmethod
method onDestroy takes nothing returns nothing
local integer i=0
call DestroyEffect(.sfx)
call SetUnitVertexColor(.c,255,255,255,255)
call SetUnitInvulnerable(.c,false)
call SetUnitPathing(.c,true)
call ReleaseTimer(.tm)
loop
exitwhen i>30
set .targets<i>=null // Set all the targets to null
set i=i+1
endloop
set .sfx=null
set .p=null
set .c=null
set .t=null
set .tm=null
endmethod
method Slash takes nothing returns nothing
set .ang=GetRandomReal(1.,360.)
set .tX=GetUnitX(.t)+50.*Cos(.ang*bj_DEGTORAD)
set .tY=GetUnitY(.t)+50.*Sin(.ang*bj_DEGTORAD)
call SetUnitFacing(.c,Atan2(.tY-.cY,.tX-.cX)*bj_RADTODEG)
set .dmg=GetRandomReal(150.,250.)
call SetUnitX(.c,.tX)
call SetUnitY(.c,.tY)
call SetUnitAnimation(.c,ATTACKSTG)
call DestroyEffect(AddSpecialEffectTarget(SFX2,.c,SFX2ATTACH))
call UnitDamageTarget(.c,.t,.dmg,true,true,ATTACKTYPE,DAMAGETYPE,null)
call IssueTargetOrder(.c,ATTACKSTG,.t)
endmethod
static method Filter takes nothing returns boolean
local thistype this=GetTimerData(GetExpiredTimer())
set .t=GetFilterUnit()
if IsUnitEnemy(.t,.p) and GetWidgetLife(.t)>.405 and not IsUnitType(.t,UNIT_TYPE_STRUCTURE) and IsUnitVisible(.t,.p) then
set .targets[.index]=.t // If the conditions are true, then add the filter unit to the array
set .index=.index+1
endif
return false // No unit enters the group
endmethod
static method onLoop takes nothing returns nothing
local thistype this=GetTimerData(GetExpiredTimer())
local integer i=0
if .num>.cnt then
call .destroy()
else
set .num=.num+1
call GroupEnumUnitsInRange(Enum_Group,.tX,.tY,AREA,Condition(function thistype.Filter))
set .t=.targets[GetRandomInt(0,.index-1)]
if .t!=null then
call .Slash()
set .index=0
loop
exitwhen i>MAX_ENUM_UNITS
set .targets<i>=null // Cleaning the array
set i=i+1
endloop
else
call .destroy()
endif
endif
endmethod
static method create takes nothing returns thistype
local thistype this=.allocate()
set .tm=NewTimer()
set .c=GetTriggerUnit()
set .cX=GetUnitX(.c)
set .cY=GetUnitY(.c)
set .t=GetSpellTargetUnit()
set .p=GetOwningPlayer(.c)
set .lvl=GetUnitAbilityLevel(.c,SPELL_ID)
set .cnt=Slashes(.lvl)
call SetUnitVertexColor(.c,255,255,255,125)
call SetUnitPathing(.c,false)
call SetUnitInvulnerable(.c,INVULNERABLE)
call .Slash()
set .sfx=AddSpecialEffectTarget(SFX,.c,SFXATTACH)
call SetTimerData(.tm,this)
call TimerStart(.tm,LOOP,true,function thistype.onLoop)
return this
endmethod
endstruct
private function Execute takes nothing returns nothing
call OmniStruct.create()
endfunction
public function InitTrig takes nothing returns nothing
local trigger t=CreateTrigger()
call GT_RegisterStartsEffectEvent(t,SPELL_ID)
call TriggerAddAction(t,function Execute)
set t=null
endfunction
endscope</i></i>
Recommendations?
Updates:
15/12/10 : Added method to calculate number of slashs, thanks Carnerox.