• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] [Help] Air Strike Ability

Status
Not open for further replies.
I am trying to mae an Air Strike ability, but I don't know enough JASS to finish it completely. As it is, I just made most of it in GUI then converted it to JASS, put it into JASS craft and have been making it so you can have as many coppies of the spell going at once, but it won't work atm, and I was wondering if someone could tell me what to do, or clean it up for me if you're feeling nice ><

The main problem now: I need to select every unit in a group, set the level of an ability, make them cast the ability, remove the unit (I forgot that lie in the code ><), then check to see if the plane (gyrocopter) is outside of the ability area, and if they are remove them.

JASS:
function Trig_Air_Strike_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A032' ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func014C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 2) == 1 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func015C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 3) == 1 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func016C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 4) == 1 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func017C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 5) == 1 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func018C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 6) == 1 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func020Func001Func002Func004Func002001001003 takes nothing returns boolean
    return ( IsUnitInGroup(GetEnumUnit(), udg_TempUnitGroup) == true )
endfunction
function Trig_Air_Strike_Func020Func001Func002Func004C takes nothing returns boolean
    if ( not ( CountUnitsInGroup(GetUnitsInRangeOfLocMatching(1000.00, udg_TempPoint, Condition(function Trig_Air_Strike_Func020Func001Func002Func004Func002001001003))) == 0 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Func020Func001C takes nothing returns boolean
    if ( not ( CountUnitsInGroup(udg_TempUnitGroup) > 0 ) ) then
        return false
    endif
    return true
endfunction
function Trig_Air_Strike_Actions takes nothing returns nothing
    local integer y
    local integer w
    local real z = GetRandomInt(0, 360)
    local real x
    local location a = GetSpellTargetLoc()
    local location b = PolarProjectionBJ(a, 500.00, z)
    local location c
    local unit group d
 
    set y = GetUnitAbilityLevelSwapped('A032', GetTriggerUnit())
 
    if (( z) < 180 ) ) then
 
        set x = z + 180
 
    endif
 
    if (( z) >= 180 ) ) then
 
        set x = z - 180
 
    endif
 
    set c = PolarProjectionBJ(a, 500.00, x)
 
    call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
    call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
    call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
    call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
    call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
    call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    if ( Trig_Air_Strike_Func014C() ) then
 
        call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
        call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    else
    endif
 
    if ( Trig_Air_Strike_Func015C() ) then
 
        call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
        call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    else
    endif
 
    if ( Trig_Air_Strike_Func016C() ) then
 
        call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
        call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    else
    endif
 
    if ( Trig_Air_Strike_Func017C() ) then
 
        call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
        call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    else
    endif
 
    if ( Trig_Air_Strike_Func018C() ) then
 
        call CreateNUnitsAtLoc( 1, 'h00W', GetOwningPlayer(GetTriggerUnit()), a), bj_UNIT_FACING )
 
        call GroupAddUnitSimple( GetLastCreatedUnit(), d )
 
    else
    endif
 
    call GroupPointOrderLoc (d, "move", c)
 
    set w = 1
 
    loop
        exitwhen w > 100
        if ( Trig_Air_Strike_Func020Func001C() ) then
 
            call CreateNUnitsAtLoc( 1, 'h00X', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
 
            call SetUnitAbilityLevelSwapped( 'A031', GetLastCreatedUnit(), y )
 
            call IssuePointOrderLocBJ( GetLastCreatedUnit(), "clusterrockets", GetUnitLoc(GetLastCreatedUnit()) )
 
            if ( Trig_Air_Strike_Func020Func001Func002Func004C() ) then
                call RemoveUnit( GetEnumUnit() )
            else
 
            endif
        else
        endif
        set w = w + 1
    endloop
endfunction
//===========================================================================
function InitTrig_Air_Strike takes nothing returns nothing
    set gg_trg_Air_Strike = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Air_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Air_Strike, Condition( function Trig_Air_Strike_Conditions ) )
    call TriggerAddAction( gg_trg_Air_Strike, function Trig_Air_Strike_Actions )
endfunction
 
Ok, what I want the spell to do is this:

It creates 5-10 "bomber planes ('h00W' is the unit code)" at a random point 500 radius away from the area that the spell is cast on. It then orders them to go across the target area, and continue on to a point 500 radius past the target again, so bassically: the target is x, it creates the bnombers at an offset of 500 to a random degrees, then orders them to go across to another offset of a predermened degrees. so if the 1st gree is 90 it will go to 270 degreees.

As the planes fly across, every 1 second they drops bombs on the ground, which do damage ('h00X' is the unit code for the dummy bomber and 'A031' is the unit code for the ability).
 
Last edited:
Level 6
Joined
Aug 15, 2007
Messages
209
DeepSea, for the future, something like:
JASS:
function Trig_Air_Strike_Func015C takes nothing returns boolean
  if ( not ( GetRandomInt(1, 3) == 1 ) ) then  return false  endif  return true endfunction

could be simplified to:

JASS:
function Trig_Air_Strike_Func015C takes nothing returns boolean
return GetRandomInt(1, 3) != 1
endfunction

!= means "not equal to."
 
Level 11
Joined
Feb 22, 2006
Messages
752
JASS:
function Trig_Air_Strike_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A032' )
endfunction

function Trig_Air_Strike_Destroy takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
endfunction

function Trig_Air_Strike_Cast takes nothing returns nothing
    local unit u = GetEnumUnit()
    local unit dummy
    local player owner = GetOwningPlayer( u )
    local real x = GetUnitX( u )
    local real y = GetUnitY( u )
    set dummy = CreateUnit( owner, 'h00X', x, y, 270.0 )
    call UnitAddAbility( dummy, 'A031' )
    call SetUnitAbilityLevel( dummy, 'A031', GetUnitUserData( u ) )
    call UnitApplyTimedLife( dummy, 'BTLF', 1.5 )
    call IssuePointOrder( dummy, "clusterrockets", x, y )
    set u = null
    set dummy = null
    set owner = null
endfunction

function Trig_Air_Strike_Bomb takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local group g = GetHandleGroup( t, "g" )
    call ForGroup( g, function Trig_Air_Strike_Cast )
    set t = null
    set g = null
endfunction

function Trig_Air_Strike_Check takes nothing returns boolean
    return ( GetUnitTypeId( GetFilterUnit() ) == 'h00W' )
endfunction

function Trig_Air_Strike_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local group g = CreateGroup()
    local group g2 = CreateGroup()
    local unit caster = GetTriggerUnit()
    local unit u
    local player owner = GetOwningPlayer( caster )
    local location targetloc = GetSpellTargetLoc()
    local location loc1
    local location loc2
    local real angle1 = GetRandomReal( 1, 360 )
    local real angle2
    local integer level = GetUnitAbilityLevel( caster, 'A032' )
    local integer total = 5
    local integer counter = 2
    if ( angle1 > 180 ) then
        set angle2 = angle1 - 180
    else
        set angle2 = angle1 + 180
    endif
    set loc1 = PolarProjectionBJ( targetloc, 500.0, angle1 )
    set loc2 = PolarProjectionBJ( targetloc, 500.0, angle2 )
    loop
        exitwhen ( counter > 6 )
        set u = CreateUnitAtLoc( owner, 'h00W', loc1, 270.0 ) )
        call GroupAddUnit( g, u )
        call SetUnitUserData( u, level )
        if ( GetRandomInt( 1, counter2 ) == 1 ) then
            set u = CreateUnitAtLoc( owner, 'h00W', loc1, 270.0 ) )
            call GroupAddUnit( g, u )
            call SetUnitUserData( u, level )
            set total = total + 1
        endif
        set counter = counter + 1
    endloop
    call GroupPointOrderLoc( g, "move", loc2 )
    call TimerStart( t, 1.00, true, function Trig_Air_Strike_Bomb )
    call SetHandleHandle( t, "g", g )
    loop
        call GroupEnumUnitsInRangeOfLoc( g2, loc2, 100.0, Condition ( function Trig_Air_Strike_Check )
        exitwhen ( CountUnitsInGroup( g2 ) >= total )
        call GroupClear( g2 )
    endloop
    call ForGroup( g, function Trig_Air_Strike_Destroy )
    call FlushHandleLocals( t )
    call DestroyTimer( t )
    call DestroyGroup( g )
    call DestroyGroup( g2 )
    call RemoveLocation( targetloc )
    call RemoveLocation( loc1 )
    call RemoveLocation( loc2 )
    set t = null
    set g = null
    set g2 = null
    set caster = null
    set owner = null
    set targetloc = null
    set loc1 = null
    set loc2 = null
endfunction

function InitTrig_Air_Strike takes nothing returns nothing
    set gg_trg_Air_Strike = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Air_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Air_Strike, Condition( function Trig_Air_Strike_Conditions ) )
    call TriggerAddAction( gg_trg_Air_Strike, function Trig_Air_Strike_Actions )
endfunction


You will need Kattana's Handle Vars for this.
 
Level 11
Joined
Feb 22, 2006
Messages
752
Make a global gamecache variable named LocalVars (spelled exactly like that, caps sensitive). Then, make a trigger that runs at map initialization that contains the following script in its actions:

JASS:
call FlushGameCache( "jasslocalvars.w3v" )
set udg_LocalVars = InitGameCache( "jasslocalvars.w3v" )


Then, add this to the custom script section of your map:

JASS:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function SetHandleInt takes handle h, string key, integer value returns nothing
    call StoreInteger( udg_LocalVars, I2S( H2I( h ) ), key, value )
endfunction

function SetHandleReal takes handle h, string key, real value returns nothing
    call StoreReal( udg_LocalVars, I2S( H2I( h ) ), key, value )
endfunction

function SetHandleString takes handle h, string key, string value returns nothing
    call StoreString( udg_LocalVars, I2S( H2I( h ) ), key, value )
endfunction

function SetHandleBoolean takes handle h, string key, boolean value returns nothing
    call StoreBoolean( udg_LocalVars, I2S( H2I( h ) ), key, value )
endfunction

function SetHandleHandle takes handle h, string key, handle value returns nothing
    call StoreInteger( udg_LocalVars, I2S( H2I( h ) ), key, H2I( value ) )
endfunction

function GetHandleInt takes handle h, string key returns integer
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
endfunction

function GetHandleReal takes handle h, string key returns real
    return GetStoredReal( udg_LocalVars, I2S( H2I( h ) ), key )
endfunction

function GetHandleString takes handle h, string key returns string
    return GetStoredString( udg_LocalVars, I2S( H2I( h ) ), key )
endfunction

function GetHandleBoolean takes handle h, string key returns string
    return GetStoredBoolean( udg_LocalVars, I2S( H2I( h ) ), key )
endfunction

function GetHandleUnit takes handle h, string key returns unit
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function GetHandleGroup takes handle h, string key returns group
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function GetHandleLoc takes handle h, string key returns location
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function GetHandleTimer takes handle h, string key returns timer
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function GetHandleTrigger takes handle h, string key returns trigger
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function GetHandleEffect takes handle h, string key returns effect
    return GetStoredInteger( udg_LocalVars, I2S( H2I( h ) ), key )
    return null
endfunction

function FlushHandleLocals takes handle h returns nothing
    call FlushStoredMission( udg_LocalVars, I2S( H2I( h ) ) )
endfunction
 
Level 11
Joined
Feb 22, 2006
Messages
752
Deep Sea Kraken said:
Azn, the spell doesn't remove the copters when they reach the end of the area.

Hmmm, that's most likely because the exitwhen condition in that last loop is bugging up. I was afraid of that...

JASS:
function Trig_Air_Strike_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A032' )
endfunction

function Trig_Air_Strike_Cast takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local group g = GetHandleHandle( t, "g" )
    local unit u = GetEnumUnit()
    local unit dummy
    local player owner = GetOwningPlayer( u )
    local real x = GetUnitX( u )
    local real y = GetUnitY( u )
    local real locx = GetHandleReal( t, "locx" )
    local real locy = GetHandleReal( t, "locy" )
    local real dx = x - locx
    local real dy = y - locy
    if ( SquareRoot( dx * dx + dy * dy ) <= 50.0 ) then
        call GroupRemoveUnit( g, u )
        call RemoveUnit( u )
        if ( CountUnitsInGroup( g ) == 0 ) then
            call FlushHandleLocals( t )
            call DestroyTimer( t )
            call DestroyGroup( g )
        endif
    else
        set dummy = CreateUnit( owner, 'h00X', x, y, 270.0 )
        call UnitAddAbility( dummy, 'A031' )
        call SetUnitAbilityLevel( dummy, 'A031', GetUnitUserData( u ) )
        call UnitApplyTimedLife( dummy, 'BTLF', 1.5 )
        call IssuePointOrder( dummy, "clusterrockets", x, y )
    endif
    set t = null
    set g = null
    set u = null
    set dummy = null
    set owner = null
endfunction

function Trig_Air_Strike_Bomb takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local group g = GetHandleGroup( t, "g" )
    call ForGroup( g, function Trig_Air_Strike_Cast )
    set t = null
    set g = null
endfunction

function Trig_Air_Strike_Check takes nothing returns boolean
    return ( GetUnitTypeId( GetFilterUnit() ) == 'h00W' )
endfunction

function Trig_Air_Strike_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local group g = CreateGroup()
    local unit caster = GetTriggerUnit()
    local unit u
    local player owner = GetOwningPlayer( caster )
    local location targetloc = GetSpellTargetLoc()
    local location loc1
    local location loc2
    local real angle1 = GetRandomReal( 1, 360 )
    local real angle2
    local integer level = GetUnitAbilityLevel( caster, 'A032' )
    local integer total = 5
    local integer counter = 2
    if ( angle1 > 180 ) then
        set angle2 = angle1 - 180
    else
        set angle2 = angle1 + 180
    endif
    set loc1 = PolarProjectionBJ( targetloc, 500.0, angle1 )
    set loc2 = PolarProjectionBJ( targetloc, 500.0, angle2 )
    loop
        exitwhen ( counter > 6 )
        set u = CreateUnitAtLoc( owner, 'h00W', loc1, 270.0 ) )
        call GroupAddUnit( g, u )
        call SetUnitUserData( u, level )
        if ( GetRandomInt( 1, counter2 ) == 1 ) then
            set u = CreateUnitAtLoc( owner, 'h00W', loc1, 270.0 ) )
            call GroupAddUnit( g, u )
            call SetUnitUserData( u, level )
            set total = total + 1
        endif
        set counter = counter + 1
    endloop
    call GroupPointOrderLoc( g, "move", loc2 )
    call TimerStart( t, 1.00, true, function Trig_Air_Strike_Bomb )
    call SetHandleHandle( t, "g", g )
    call SetHandleReal( t, "locx", GetLocationX( loc2 ) )
    call SetHandleReal( t, "locy", GetLocationY( loc2 ) )
    call RemoveLocation( targetloc )
    call RemoveLocation( loc1 )
    call RemoveLocation( loc2 )
    set t = null
    set g = null
    set caster = null
    set owner = null
    set targetloc = null
    set loc1 = null
    set loc2 = null
endfunction

function InitTrig_Air_Strike takes nothing returns nothing
    set gg_trg_Air_Strike = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Air_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Air_Strike, Condition( function Trig_Air_Strike_Conditions ) )
    call TriggerAddAction( gg_trg_Air_Strike, function Trig_Air_Strike_Actions )
endfunction
 
Last edited:
Hey azn, if I want to make the AoE of the spell bigger, other than the two location points, is there any other number I have to change?

Oh great. It gives me another error now *sighs* lol. Here is a screenshot.
 

Attachments

  • Error.jpg
    Error.jpg
    39.9 KB · Views: 119
Level 11
Joined
Feb 22, 2006
Messages
752
Deep Sea Kraken said:
Hey azn, if I want to make the AoE of the spell bigger, other than the two location points, is there any other number I have to change?

Nope.

Bobo_The_Kodo said:
change

Code:
local group g = GetHandleHandle( t, "g" )to


Code:
local group g = GetHandleGroup( t, "g" )

Yeeeep...tht was pretty retarded of me. That's what happens when you switch to vJass, you completely forget gamecache (which might be a good thing actually...)
 
Just 1 thing, that I hate when people say: you DON'T NEED ANY KATANAS SOMETHING SOMETHING TO CREATE SPELLS !! YOU DON?T NEED VJASS OR ANYTHING ELSE !!

Everything can be created without those complicated systems... happens that they help people who understand then some times, but they are NOT a need to make spells work.
They exist only for a purpose of efficiency.

Phew, sry for caps, but that felt good.

Now about your spell, maybe this comment is coming to late, but still, I don't have a clear idea of what you want, but correct me if I am wrong: you want to create kind of stampeede from rexxar, but with planes dropping bombs rit ?? (that's what I understood when reading you huge comments).

Well, You may want to try a different approach. Instead of having a huge complicated code maybe you should try to do like I am:
1 - Create a single bombard spell
2 - That's all !

Then after this, you just create X dummies where you want, and you just order them to cast your spell.
As simple as that. And the advantage is that it is simpler and that you can use the spell with only 1 plane (don't force the player using X planes at the same time).

I am taking this approach and it is working so far.
You may want to check my Fire Bomber Thread here, I believe that my simple code (which was now heavily improved) may help you if you try this approach (we are basically trying to do the same thing with 2 different approaches).
However, I must warn you, my code is not complete yet (that's why I am requesting for help here lol) and it will require some JASS knowledges, but still, it's nothing from another world, and it doesn't use any complex systems like katan's system or vjass or whatever (I don't use such systems for professional courtesy, except when the spell I am importing and/or using has a very strong bound to the system itself).

Btw, maybe it is a good idea for you to check the BombarCommander map from Blizzard. Although it uses pretty complex JASS, you still can learn something from them (my spell is based on their map, but it is way more simple).
Anyway, hope I helped you.
 
The player cannot control the airplanes.

The Caster systems and Katana's allow for Multiple User Instances without creating massive lag, and are used in most very complex spell triggers.

This ability is strong, and does alot of damage, but it requires some luck in the using (except for the spot you cast it on, its not guarenteed to hit anything), so a simple modified blizzard spell wouldn't work.
 
You didn't get the point. The player is never able to control the plane, not even in Blizzard game. Besides There a better chance that my system will NOT lag, and that yours will. Why ? Because system does not use Katans something something and because it is way simpler for the program to compile and run.

Besides, in a final version, it will be a mix of simple spells, that will create the big one.

Still it is Ok if you are not interested. I just think that some1 who wants to learn and enter the world of JASS, entering by such a complicated path is not such a great decision. But, it is your call, so I will leave it up to you.
 
Status
Not open for further replies.
Top