• 🏆 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] Locust enum

Status
Not open for further replies.
Level 11
Joined
Apr 6, 2008
Messages
760
i have some problem with picking Locust units, well it works but i have to add the function to pick them in every trigger. i'v tryed to put in to the map header and making a library but then i can't access my struct since i need to check if it is a enemy. so i need to make it usable for any trigger but i dunno how :(

well here is the code

JASS:
scope FireBall

globals
private constant integer Abil_id = 'A000'
private constant integer Dum_id = 'h000'
endglobals

private struct data
unit c
unit dum
real angle
real distance
real maxdistance
real x
real y
timer t
    method onDestroy takes nothing returns nothing
        call PauseTimer(.t)
        call ClearTimerStructA(.t)
        call DestroyTimer(.t)
    endmethod
endstruct
// this is for Picking Locust unit's, Credits to PurplePoot
globals
    private group enumGrp = CreateGroup()
endglobals

private function LocustEnumerators_AntiLeak takes nothing returns boolean
    local data d = GetTimerStructA(GetExpiredTimer())
    local boolean ok = GetWidgetLife(GetFilterUnit()) > .405 and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(d.c))
    return ok
endfunction

private function GroupEnumLocustsInRange takes group g, real x, real y, real radius, boolexpr filter returns nothing
    local integer i = 0
    local unit u
    set filter = Filter( function LocustEnumerators_AntiLeak )
    loop
        exitwhen i > 11
        call GroupEnumUnitsOfPlayer( enumGrp, Player( i ), filter )
        loop
            set u = FirstOfGroup(enumGrp)
            exitwhen u == null
            if IsUnitInRangeXY( u, x, y, radius ) and GetUnitAbilityLevel(u,'Aloc') > 0 then
                call GroupAddUnit( g, u )
            endif
            call GroupRemoveUnit(enumGrp,u)
        endloop
        set i = i + 1
    endloop
endfunction

private function PickFilter takes nothing returns boolean
    local data d = GetTimerStructA(GetExpiredTimer())
    local unit f = GetFilterUnit()
    local boolean ok = GetWidgetLife(f) > .405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and IsUnitEnemy(f,GetOwningPlayer(d.c))
    set f = null
    return ok
endfunction
    
private function Move takes nothing returns nothing
    local data d = GetTimerStructA(GetExpiredTimer())
    local real x = GetUnitX(d.dum)
    local real y = GetUnitY(d.dum)
    local group g = CreateGroup()
    local unit p
    set d.distance = d.distance + 20
    call GroupEnumUnitsInRange(g,x,y,60.,Filter(function PickFilter))
    set p = FirstOfGroup(g)
    if p != null then
        // this awsome knockback by silvernoon
        call Knockback(p, 750., Atan2(GetUnitY(p)-d.y,GetUnitX(p)-d.x), 2.5) 
        call KillUnit(d.dum)
        call d.destroy()
    endif
    call GroupClear(g)
    call GroupEnumLocustsInRange(g,x,y,60.,null) 
    set p = FirstOfGroup(g)
    if p != null then
        call KillUnit(d.dum)
        call KillUnit(p)
        call d.destroy()
    endif
    if x > MinX and x < MaxX then
        call SetUnitX(d.dum,x+20*Cos(d.angle*3.14159/180))
    endif
    if y > MinY and y < MaxY then
        call SetUnitY(d.dum,y+20*Sin(d.angle*3.14159/180))
    endif
    if d.distance >= d.maxdistance then
        call KillUnit(d.dum)
        call d.destroy()
    endif
    if GetWidgetLife(d.dum) > .405 then
        call d.destroy()
    endif
    call DestroyGroup(g)
    set p = null
    set g = null
endfunction
    
private function SpellCast takes nothing returns nothing
    local location loc = GetSpellTargetLoc()
    local real tx = GetLocationX(loc)
    local real ty = GetLocationY(loc)
    local data d = data.create()
    set d.c = GetTriggerUnit()
    set d.x = GetUnitX(d.c)
    set d.y = GetUnitY(d.c)
    set d.angle = Atan2(ty-d.y,tx-d.x)*57.27589
    set d.dum = CreateUnit(GetOwningPlayer(d.c),Dum_id,d.x+75*Cos(d.angle*3.14159/180),d.y+75*Sin(d.angle*3.14159/180),d.angle)
    set d.distance = 0
    set d.maxdistance = 2000.
    set d.t = CreateTimer()
    call SetTimerStructA(d.t,d)
    call TimerStart(d.t,.035,true,function Move)
    call RemoveLocation(loc)
    set loc = null
endfunction

private function condition takes nothing returns boolean
    return GetSpellAbilityId()==Abil_id
endfunction

public function InitTrig takes nothing returns nothing
    local trigger t  = CreateTrigger(  )
    local integer a = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(a),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set a = a + 1
        exitwhen a == 16
    endloop
    call TriggerAddAction(t, function SpellCast)
    call TriggerAddCondition(t,Filter(function condition))
endfunction

endscope

EDIT: typo, damn dylexia :<
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
Ciebron, you're not intended to modify the Antileak function of the locust enum function - leave that to return true.

You just add it to a custom library, the filter doesn't need to be above it since you pass it as a parameter when calling it.

Example: call GroupEnumLocustsInRange(g,x,y,radius,Filter(function YourFireballFilter))
 
Level 11
Joined
Apr 6, 2008
Messages
760
so i can do for example

JASS:
private function PickFilter takes nothing returns boolean
    local data d = GetTimerStructA(GetExpiredTimer())
    local unit f = GetFilterUnit()
    local boolean ok = GetWidgetLife(f) > .405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and IsUnitEnemy(f,GetOwningPlayer(d.c))
    set f = null
    return ok
endfunction

JASS:
call GroupEnumLocustsInRange(g,x,y,radius,Filter(function PickFilter))
 
Status
Not open for further replies.
Top