HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

War Pidgeon

02-14-2007, 05:50 PM#1
wantok
Rain bird droppings onto unsuspecting enemies below!

(Bombard will only work if the bird is moving.)


I read through Vexorians very helpful tutorial on structs and decided to try them out. I previously used gamecache and handle variables on the bombard ability for my war pidgeon. Using structs and a single timer was far less complex.

I'm still new to Jass so I'd appreciate it any of you could look through my functions for improvements or to point out leaks.

Edit: here's the code
Collapse JASS:
globals
    timer PigDrop_Timer = CreateTimer()
    timer PigBomb_Timer = CreateTimer()
    PigsActiveData array PigsActive_Ar 
    unit array PigBombs_Ar 
    integer PigsActive_Total = 0
    integer PigBombs_Total = 0
endglobals

struct PigsActiveData
    unit u
    real x
    real y
endstruct

constant function PigUnit takes nothing returns integer
    return 'n000' //pig unit
endfunction

constant function PigBombUnit takes nothing returns integer
    return 'h000' //bomb unit
endfunction

constant function BombAbility takes nothing returns integer
    return 'A000' //bomb ability
endfunction

constant function BombBuff takes nothing returns integer
    return 'B000' //bomb ability buff
endfunction

constant function PigDamageModel takes nothing returns string
    return "Abilities\\Spells\\Other\\AcidBomb\\BottleImpact.mdl"//bomb explosion effect model path
endfunction

function PigDamage takes nothing returns real
    return 100.
endfunction

function BombAbilityFilter takes nothing returns boolean
    return GetSpellAbilityId() == BombAbility()
endfunction

function CheckEnemyAndFlyingFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

function PigDoDamage takes unit u, location loc, real radius returns nothing
    local group g = CreateGroup()
    local boolexpr bool = Condition(function CheckEnemyAndFlyingFilter)
    local unit a
    set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
    call GroupEnumUnitsInRangeOfLoc(g, loc, radius, bool)
    call DestroyBoolExpr(bool)    
    loop
        set a = FirstOfGroup(g)
        exitwhen a == null
        call GroupRemoveUnit(g,a)
        call UnitDamageTarget(u, a, PigDamage(), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
    endloop    
              
    call RemoveUnit(u)
    set a = null
    call DestroyGroup(g)
    set g = null
    call DestroyBoolExpr(bool)
    set bool = null
endfunction

function PigBomb_Timer_Callback takes nothing returns nothing
    local unit u
    
    local real z
    local location loc
    
    local integer i  =0 
    
    loop
        set u = PigBombs_Ar[i]
        exitwhen i == PigBombs_Total
        set loc = GetUnitLoc(u)
        set z = GetUnitFlyHeight(u)
        
        if  z <= 15 then
            
            call PigDoDamage(u, loc, 60)
            set PigBombs_Ar[i] = PigBombs_Ar[PigBombs_Total-1]
            set PigBombs_Total = PigBombs_Total - 1
            set i = i -1
            call DestroyEffect(AddSpecialEffectLoc(PigDamageModel(), loc))
            
        else
            call SetUnitFlyHeight(u, (z - 13), 10000)
        endif
        set i = i + 1  
    endloop
    
    if PigBombs_Total == 0 then
        call PauseTimer(PigBomb_Timer)
    endif
    
     
    
    set u = null
    set loc = null

endfunction

function PigDrop_Timer_Callback takes nothing returns nothing
    local unit u
    local unit bomb
    local PigsActiveData dat
    local real x
    local real y
    local real d
    local integer i=0
    
    loop
        exitwhen i == PigsActive_Total
        
        set dat = PigsActive_Ar[i]
        set u = dat.u        
        if GetUnitAbilityLevel(u, BombBuff()) > 0 then
            
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            set d = SquareRoot((x - dat.x)*(x - dat.x)+(y-dat.y)*(y-dat.y))
            set dat.y = y
            set dat.x = x
            
            if d > 2 then
                set bomb = CreateUnit(GetOwningPlayer(u), PigBombUnit(), x, y, GetUnitFacing(u))
                call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - 10)
                if PigBombs_Total == 0 then
                    call TimerStart(PigBomb_Timer, .04, TRUE, function PigBomb_Timer_Callback)
                endif
        
                set PigBombs_Ar[PigBombs_Total] = bomb
                set PigBombs_Total = PigBombs_Total + 1
                
            endif
        else
            set PigsActive_Ar[i] = PigsActive_Ar[PigsActive_Total-1]
            set PigsActive_Total = PigsActive_Total - 1
            call dat.destroy()
            set i = i - 1
                        
        endif
        set i = i + 1
    endloop
    
    if PigsActive_Total == 0 then
        call PauseTimer(PigDrop_Timer)
    endif
        
    set u = null
    set bomb = null
endfunction

function AddPigsToActiveGroup takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local PigsActiveData dat = PigsActiveData.create()
    
    set dat.u = u
    set dat.x = GetUnitX(u)
    set dat.y = GetUnitY(u)
             
    if PigsActive_Total == 0 then
        call TimerStart(PigDrop_Timer, .15, TRUE, function PigDrop_Timer_Callback)
    endif
            
    set PigsActive_Ar[ PigsActive_Total] = dat    
    set PigsActive_Total = PigsActive_Total +1
    set u = null
endfunction

function InitTrig_Pig takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(t, Condition(function BombAbilityFilter))
    call TriggerAddAction(t, function AddPigsToActiveGroup)
    set t = null
endfunction


Attached Files
File type: w3xWarPidgeon.w3x (21.4 KB)
02-14-2007, 10:13 PM#2
Rising_Dusk
Post the code and not the map please.
Half of us don't have WC3 installed on the computers we check the forums on.
02-15-2007, 12:47 AM#3
wantok
I added the code to the first post.

When the bombard ability is activated and the casting unit is moving, it drops bombs which damage any enemy ground unit they land near.