HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Whirlwind/Bladestorm Spell (JASS)

09-24-2006, 02:00 PM#1
Fulla
Ok this is pretty much my first attempt at a pure JASS spell.

What its meant to do is basically.
Hero activates Bladestorm:

It then begins spinning all nearby enemy units around the Hero until the spell wears off.

Collapse JASS:
function Trig_Bladestorm_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A076' ) ) then
        return false
    endif
    return true
endfunction


function Trig_Bladestorm_Actions takes nothing returns nothing
local unit u GetTriggerUnit()
local integer i =0
local group g
local location l
loop
exitwhen (i=50)
set l = GetUnitLoc(GetTriggerUnit()
set g = GetUnitsInRangeOfLocAll(200.00, GetUnitLoc(GetTriggerUnit())
set i ='i+1'
    call SetUnitPositionLoc( GetEnumUnit(), PolarProjectionBJ(GetUnitLoc(GetTriggerUnit()), 200.00, AngleBetweenPoints(GetUnitLoc(GetTriggerUnit()), GetUnitLoc(GetEnumUnit()))) )
    call TriggerSleepAction( 0.04
endfunction

Now im kind of stuck at the bit where I, move 'units in the group'.
This is basically a mix of reading tutorials, using jasscraft and converting bits of GUI into jass in WE.

thx for any help
Fulla
09-24-2006, 02:09 PM#2
Rising_Dusk
This requires more than I would imagine most tutorials offer.
A good reference would be to look at my Hurricane spell, seeing as it generally does the same thing minus the bladestorm and a few other slight differences.

Either way, you're going to want to run a timer every .033 (Or however accurate to framerate you want it) and add X number of nearby units to a group which you keep attached to the timer.
Then in the callback of the timer run a ForGroup() on that group to rotate them around using polar projections.

The trick is that you should store handles onto public units (Those being spun around) and recall them from within the ForGroup() by getting them off of EnumUnit().

If what I've rambled on about makes no sense, I can try to clarify further.
So yeah.
09-24-2006, 02:50 PM#3
Fulla
hmm do I need to use handles for this?

Dont think I quite understand them yet, was hoping to avoid them until later on after a few more spells.

I can do the folliwing it in GUI but not sure how to do this in JASS

Trigger:
Bladestorm3
Collapse Events
Time - Every 0.01 seconds of game time
Conditions
Collapse Actions
Collapse For each (Integer A) from 1 to (Number of units in BladestormGroup), do (Actions)
Collapse Loop - Actions
Set BladestormTempUnit = (Random unit from BladestormGroup)
Unit - Move BladestormTempUnit instantly to ((Position of BladestormUnit) offset by 140.00 towards ((Angle from (Position of BladestormUnit) to (Position of BladestormTempUnit)) + 10.00) degrees)

Also is it possible to have a loop within a loop.
In which case could I have the 2nd/inner loop cycle through each unit in the group and move them invidivually each 'loop' of the main loop.

EDIT: Something like this

Collapse JASS:
  set t = ((GetNextUnitInGroup????))
  call SetUnitPositionLoc( t, PolarProjectionBJ(GetUnitLoc(u), 140.00, ( AngleBetweenPoints(GetUnitLoc(u), GetUnitLoc(t)) + 10.00 )) )
09-24-2006, 04:37 PM#4
Rising_Dusk
Quote:
Also is it possible to have a loop within a loop.
Yes, just be careful of execution limit.

I normally don't like FirstOfGroup() iterations for this kind of spell, but that's me.
And yes, you would need handles, or at least some way to store the angle which the unit is currently being projected from the caster's location.
You could use Custom Values if you dont use them elsewhere and dont have decimal angles.

So if the distance from the caster is constant (Not like for Hurricane, ie) then you would only need to maintain a unit's current angle, which could be managed via custom values if necessary.

Kinda something like this. (This is taken from Hurri's code)
I reduced the code to the bare minimum to show you what I mean.
Collapse JASS:
function Hurr_HydroRevolve_GroupStuff takes nothing returns nothing
    local unit e = GetEnumUnit()
    local real dist = GetHandleReal(e, "dist")
    //^- You'll notice if you dont need to manage distance this will be constant.
    local real angl = GetHandleReal(e, "angl")
    //^- However you maintain this number, it is the one most important datum.
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real xf
    local real yf
    
    //This is the polar projection and revolving of the EnumUnit in the group.
    set angl = angl + 7
    set xf = x + dist * Cos(angl * 0.017453)
    set yf = y + dist * Sin(angl * 0.017453)
    call SetUnitPosition(e, xf, yf)
    call SetHandleReal(e, "angl", angl)
    
    set e = null
endfunction

function Hurr_HydroRevolve takes nothing returns nothing
    local integer i = H2I(GetExpiredTimer())
    local real maxdur = GetHandleReal(I2Timer(i), "maxdur")
    local real dur = GetHandleReal(I2Timer(i), "dur")
    local group g = GetHandleGroup(I2Timer(i), "g")
    
    //This is the ForGroup() for the group of units being revolved.
    call ForGroup(g, function Hurr_HydroRevolve_GroupStuff)
    call SetHandleReal(I2Timer(i), "dur", dur+.033)
    if dur+.033 >= maxdur then
        //Clean up the timer here
        call FlushHandleLocals(I2Timer(i))
        call PauseTimer(I2Timer(i))
        call DestroyTimer(I2Timer(i))
    endif
    
    set g = null
endfunction