Doomhammer
Bob Kotick - Gamers' corporate spoilsport No. 1
- Reaction score
- 67
A spell I rather made for fun: a railgun spiral effect as known from shooters à la Quake 2.
On the pic you can't see that much since I set the bullet velocity pretty high.
As a little annotation, I'm not very proud of my coding, which is based on yesterday's technology (cs cache) and therefore not too efficient in terms of function calls. I'm also using the caster system.
What's more worth being looked at is the maths behind it including the creation of a simple helix:
and the clockwise rotation of our helix in the target direction
So that's basically it. I'm open for all kinds of questions for those who want to make their own spiral spells. With a little effort this might even be made with GUI.
For all those less interested in the maths: Have fun killing some spiders!
On the pic you can't see that much since I set the bullet velocity pretty high.
As a little annotation, I'm not very proud of my coding, which is based on yesterday's technology (cs cache) and therefore not too efficient in terms of function calls. I'm also using the caster system.
What's more worth being looked at is the maths behind it including the creation of a simple helix:
Code:
d = movment speed * timer interval
x = d
y = Cos(d*bj_DEGTORAD)
z = Sin(d*bj_DEGTORAD)
and the clockwise rotation of our helix in the target direction
Code:
w = angle between target and unit
x_new = x*cos(w) - y*sin(w)
y_new = y*cos(w) + x*sin(w)
So that's basically it. I'm open for all kinds of questions for those who want to make their own spiral spells. With a little effort this might even be made with GUI.
For all those less interested in the maths: Have fun killing some spiders!
JASS:
constant function FrostBolt_SpellId takes nothing returns integer
return 039;A004039;
endfunction
constant function Helix_SpellId takes nothing returns integer
return 039;A003039;
endfunction
constant function Helix_Radius takes real w returns real
return 50.0 - 0.01 * w
endfunction
constant function Helix_TimerInterval takes nothing returns real
return 0.01
endfunction
constant function Helix_Speed takes nothing returns real
return 1500.0
endfunction
constant function Spiral_Factor takes nothing returns real
return 3.6
endfunction
constant function Helix_Art takes nothing returns string
return "Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl"
endfunction
function Helix_Filter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit() , bj_groupEnumOwningPlayer) == true and GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit() , UNIT_TYPE_GROUND) == true
endfunction
function Helix_child takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u=GetAttachedUnit(t, "helix_caster")
local real sin=GetAttachedReal(t, "sin_angle")
local real cos=GetAttachedReal(t, "cos_angle")
local real v=Helix_Speed()*Helix_TimerInterval()
local real d=GetAttachedReal(t, "helix_dist")+v
local real x=d
local real y=Helix_Radius(d)*Cos(d*bj_DEGTORAD*Spiral_Factor())
local real z=40.0+Helix_Radius(d)*Sin(d*bj_DEGTORAD*Spiral_Factor())
local real xr=GetAttachedReal(t, "x")+x*cos-y*sin
local real yr=GetAttachedReal(t, "y")+y*cos+x*sin
local unit pro=GetAttachedUnit(t, "cst")
local group g=CreateGroup()
local boolexpr b=Filter(function Helix_Filter)
if d<GetAttachedReal(t, "total_dist") then
call AttachReal(t, "helix_dist",d)
call SetUnitX(pro, xr)
call SetUnitY(pro, yr)
call SetUnitFlyHeight(pro,z, 0)
set bj_groupEnumOwningPlayer=GetOwningPlayer(u)
call GroupEnumUnitsInRange(g, xr, yr, 40, b)
call CasterCastAbilityGroup(GetOwningPlayer(pro), FrostBolt_SpellId(), "frostnova", g, true)
else
call DestroyEffect(GetAttachedEffect(t, "effect"))
call CleanAttachedVars(t)
call ReleaseTimer(t)
endif
call DestroyBoolExpr(b)
call DestroyGroup(g)
set g=null
endfunction
function Helix takes nothing returns nothing
local unit u=GetSpellTargetUnit()
local unit c=GetTriggerUnit()
local real x=GetUnitX(c)
local real y=GetUnitY(c)
local real dx=GetUnitX(u)-x
local real dy=GetUnitY(u)-y
local real d=SquareRoot(dx*dx+dy*dy)
local real ang=Atan2(dy,dx)
local timer t=NewTimer()
local unit cst=CreateCaster(bj_RADTODEG*ang,x+50.0/d*dx,y+50.0/d*dy)
call SetUnitScale(cst,0.4,0.4,0.4)
call AttachObject(t, "helix_caster", c)
call AttachReal(t, "x",x)
call AttachReal(t, "y",y)
call AttachReal(t, "sin_angle", Sin(ang))
call AttachReal(t, "cos_angle", Cos(ang))
call AttachReal(t, "helix_dist", 50.0)
call AttachReal(t, "total_dist", d)
call AttachObject(t, "cst", cst)
call AttachObject(t, "effect", AddSpecialEffectTarget(Helix_Art(),cst,"origin"))
call TimerStart(t, Helix_TimerInterval(), true, function Helix_child)
endfunction
//===========================================================================
function InitTrig_Helix takes nothing returns nothing
call PreloadAbility(FrostBolt_SpellId())
call PreloadAbility(Helix_SpellId())
call OnAbilityEffect(Helix_SpellId(), "Helix")
endfunction