Help with Custom Function

Kenny

Back for now.
Reaction score
202
JASS:
function FilterIsEnemyAlive takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction


I think thats your problem. If that is in the custom functions library you have, then Caster is probably not refering to anything.

In these situations it is best to make a custom filter for your new library, so it does not have to rely on your other one.

So, basically make a new filter in the CAS library. Just copy and paste the one you have posted, make it private, and then you will need to make a global unit that is set to the casting in the create method.

JASS:
library CAS requires CSData,CSSafety

globals  
    private constant real Start = 30.00   
    private constant real Radius = 50       
    private constant real Scale = 0.6            
    private constant real Fly_height = 60.00   
    private constant attacktype A = ATTACK_TYPE_CHAOS
    private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
    private unit Caster = null // The global unit
endglobals

private function FilterIsEnemyAlive takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction // New filter
               
//=======================================================================
private struct Data
    unit u
    unit d
    real moved
    real cd
    real maxd
    real dmg
    real angle
    group g1 = CreateGroup()
    group g2 = CreateGroup()
    timer t
       
    static method create takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real moved, real maxd, real dmg returns Data
        
        local Data d = Data.allocate()
        set d.t = NewTimer()
        set d.u = u
        set d.cd = Start
        set d.maxd = maxd
        set d.angle = AngleXY(cx,cy,tx,ty)
        set d.dmg = dmg
        set d.d = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, d.angle), PolarProjectionY (cy, Start, d.angle) , Rad2Deg(d.angle))
        call SetUnitMoveSpeed(d.d, moved)
        set d.moved = moved
        set Caster = u // Setting global unit to caster
        
        call SetUnitPathing(d.d,false)
        call SetUnitScale(d.d,Scale,Scale,Scale)
        call SetUnitFlyHeight(d.d,Fly_height,0.00)
        call TimerStart(d.t,period,true,function Data.Execute)
        call SetCSData(d.t,d)
        
        return d
    endmethod
    
    static method Execute takes nothing returns nothing
        local real x
        local real y
        local unit u
        local Data d = GetCSData(GetExpiredTimer())
        
        set d.moved = GetUnitMoveSpeed(d.d)
        set d.cd = d.cd + d.moved
        
            if d.cd >= d.maxd then
                call d.destroy()
                return
            endif
            
            if d.d == null then
                call d.destroy()
                return
            endif

        set x = GetUnitX(d.d)
        set y = GetUnitY(d.d)    
        set x = SafeX(PolarProjectionX(x, d.moved, d.angle))
        set y = SafeY(PolarProjectionY(y, d.moved, d.angle))
        
        call SetUnitX(d.d, x)
        call SetUnitY(d.d, y)
        call GroupClear(d.g2)
        call GroupEnumUnitsInRange(d.g2,x,y,Radius,Condition(function FilterIsEnemyAlive))
            
            loop
                set u = FirstOfGroup(d.g2)
                exitwhen u == null
                    if not(IsUnitInGroup(u,d.g1)) then
                        call GroupAddUnit(d.g1,u)
                        call UnitDamageTarget(d.u,u,d.dmg,false,false,A,D,null)
                        call GroupRemoveUnit(d.g2,u)
                    endif                    
                call GroupRemoveUnit(d.g2,u)
            endloop
    endmethod
    
    private method onDestroy takes nothing returns nothing
        call RemoveUnit(.d)
        call GroupClear(.g1)
        call DestroyGroup(.g1)
        call GroupClear(.g2)
        call DestroyGroup(.g2)
        call ReleaseTimer(.t)
    endmethod
endstruct

public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real moved, real maxd, real dmg returns nothing    
    call Data.create(ut,u,cx,cy,tx,ty,period,moved,maxd,dmg)
endfunction  

endlibrary
 

cleeezzz

The Undead Ranger.
Reaction score
268
does caster have to be global? wont that overwrite on multi instances?, in otherwords is it possible to load d.u (the caster) into the filter? instead of using a global?

another question

library CAS requires CSData,CSSafety

so if its a library, and you want to use functions from another library, you must put, requires (Library_Name)? if so, how come i didn't put..

library CAS requires CSData,CSSafety,HandyFunctions

yet i can still use AngleXY function thats within HandyFunctions library?
 

quraji

zap
Reaction score
144
If the Caster global is only being used in the filter it should be fine. And to be technical d.u still is a global :p

You're not required to write "requires Library1, Library2, ...", but it ensures that those libraries will be moved above the requiring library in the script. It's by chance you're still able to use the other library without requiring it.
 

quraji

zap
Reaction score
144
hmm..


how do i do that for all players.


JASS:
call GetUnitsOfTypeIdAll('h00K')


ok.. so this returns a group that has units of type h00K, but how do i refer to this group?
JASS:
  set g1 = GetUnitsOfTypeIdAll('h00K')
does that work?

1. Either loop through or use GetLocalPlayer. Ex:
JASS:

local integer i = 0

loop
  exitwhen i ==12

    call CameraClearNoiseForPlayer(Player(i))
    set i = i + 1
endloop

//or:
    call CameraClearNoiseForPlayer(GetLocalPlayer())


Looking at the function you'll find that it is a BJ, and you can just do this to inline the code:
JASS:

...
    call CameraSetSourceNoise(0,0) // both of these functions apply to all players
    call CameraSetTargetNoise(0,0)



2. Yes, that's how you would do it. If it returns a group, then you can store it in a group variable.
 

cleeezzz

The Undead Ranger.
Reaction score
268
whats the difference between CameraSetSourceNoise and CamerSetTargetNoise

EDIT: also, using the same custom function,..

JASS:
scope HA initializer Init

private function Damage takes integer i returns real
    return 350.00+(100.00*i)
endfunction

private function Damage2 takes integer i returns real
    return 100.00*i
endfunction

private function MaxDist takes integer i returns real
    return 1500.00+(500.00*i)
endfunction

private struct Data
    unit d
    timer t
    
    static method create takes nothing returns Data
        local Data d = Data.allocate()
        local unit u = GetTriggerUnit()
        local real cx = GetUnitX(u)
        local real cy = GetUnitX(u)   
        local location tp = GetSpellTargetLoc()
        local real tx = GetLocationX(tp)
        local real ty = GetLocationY(tp)
        local integer i = GetUnitAbilityLevel(GetTriggerUnit(),GetSpellAbilityId())
        
        set d.t = NewTimer()
        set d.d = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h000',0,0,0)
        call UnitApplyTimedLife(d.d,'BTLF',20)
                 
            
        call DestroyEffect(AddSpecialEffect( "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", cx, cy ))  //none of these special effects are created.. is the struct not being created?
        call DestroyEffect(AddSpecialEffect( "Abilities\\Spells\\Orc\\AncestralSpirit\\AncestralSpiritCaster.mdl", cx, cy ))
        call DestroyEffect(AddSpecialEffect( "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", cx, cy ))

        call TerrainDeformRipple ( cx, cy, 2000, 60, 4, 20, 1000.00 , 0.5 , 500.00 , true)
        call SetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE, GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_LIFE))

        call CAS_SA('h00J',u,cx,cy,tx,ty,0.03,33,MaxDist(i),Damage(i))  //the custom function mentioned earlier.
        call CAS_SA('h00K',u,cx,cy,tx,ty,0.03,33,MaxDist(i),Damage2(i))
    
        
        call TimerStart(d.t, 0.27, true, function Data.Execute)  //does running data.execute only work in libraries? it doesn't seem to have an affect
        call SetCSData(d.t, d)
    
        call RemoveLocation(tp)
        set u = null
        return d
    endmethod
    
    static method Execute takes nothing returns nothing
        local Data d = GetCSData(GetExpiredTimer())
        local group g
        local real x
        local real y
        local unit u
        
        set g = GetUnitsOfTypeIdAll('h00K')
        set u = FirstOfGroup(g)
        if u == null then  // I want to make it so that if theres no units of type 'h00K' on the map, then it stops the trigger, there has to be a better way than this?
            call d.destroy()
        endif
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                set x = GetUnitX(u)
                set y = GetUnitY(u)
                call IssuePointOrder(d.d, "flamestrike", x, y)
                call DestroyEffect(AddSpecialEffect( "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl", x, y ))
            endloop
        call GroupClear(g)
        call DestroyGroup(g)
    endmethod
    
    private method onDestroy takes nothing returns nothing
        call RemoveUnit(.d)
        set .d = null
        call ReleaseTimer(.t)
    endmethod
endstruct

private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A006'
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( trig, Condition( function Conditions ) )
endfunction
   
endscope

it does nothing at all. plus read the some of the comments in the trigger

what its supposed to do:

Create 3 special effects, start a periodic timer 0.27 that orders a dummy to cast flamestrike at the position of all units of type 'h00k', then run the custom function to create the arrow.
 

quraji

zap
Reaction score
144
Um...you didn't add an action to the trigger...


And the camera target is where the camera is aimed, the source is the camera itself, kinda.

"CameraClearNoiseForPlayer" is a BJ that clears the noise for both source and target.
 

cleeezzz

The Undead Ranger.
Reaction score
268
hmm i thought the struct was good enough to count as an action rofl. so how do a create an action to run the struct?
 

Kenny

Back for now.
Reaction score
202
JASS:
public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real moved, real maxd, real dmg returns nothing    
    call Data.create(ut,u,cx,cy,tx,ty,period,moved,maxd,dmg)
endfunction


Thats what those kind of things are for. Create an actions function that calls the create method, then its done.
 

quraji

zap
Reaction score
144
hmm i thought the struct was good enough to count as an action rofl. so how do a create an action to run the struct?

Yes you can easily use a struct method as your whole function, but you never added an action in your Init, meaning even if the condition you added was true, nothing would happen.
 

cleeezzz

The Undead Ranger.
Reaction score
268
JASS:
library CAS requires CSData,CSSafety,HandyFunctions

globals  
    private constant real Start = 50.00   
    private constant real Radius = 50.00       
    private constant real Scale = 0.60            
    private constant real Fly_height = 60.00   
    private constant attacktype A = ATTACK_TYPE_CHAOS
    private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
    private unit Caster = null
endglobals

private function FilterIsEnemyAlive takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction  
               
//=======================================================================
private struct Data
    unit u
    unit d
    unit a
    real moved
    real cd
    real maxd
    real dmg
    real angle
    group g1 = CreateGroup()
    group g2 = CreateGroup()
    timer t
    integer aid
    integer lvl
    real int
    real next
    boolean spell
    string sfx
       
    static method create takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real moved, real maxd, real dmg, boolean spell, integer aid, integer lvl, real int, string sfx returns Data
        
        local Data d = Data.allocate()
        set d.t = NewTimer()
        set d.u = u
        set d.cd = Start
        set d.maxd = maxd
        set d.angle = AngleXY(cx,cy,tx,ty)
        set d.dmg = dmg
        set d.d = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, d.angle), PolarProjectionY (cy, Start, d.angle) , Rad2Deg(d.angle))
        call SetUnitMoveSpeed(d.d, moved)
        set d.moved = moved
        set Caster = u
        if spell == true then
            set d.spell = true
            set d.aid = aid
            set d.int = int
            set d.next = int
            set d.a = CreateUnit(GetOwningPlayer(u),'h000',cx,cy,0) //creates dummy to cast ability
            call UnitAddAbility(d.a,aid)  //adds ability to dummy
            call SetUnitAbilityLevel(d.a,aid,lvl) //sets level of ability
            call UnitApplyTimedLife(d.a,'BTLF',20) //expiration
                if sfx != null then
                    set d.sfx = sfx
                else
                    set d.sfx = null
                endif        
        else
            set d.spell = false
        endif
        
        call SetUnitPathing(d.d,false)
        call SetUnitScale(d.d,Scale,Scale,Scale)
        call SetUnitFlyHeight(d.d,Fly_height,0.00)
        call TimerStart(d.t,period,true,function Data.Execute)
        call SetCSData(d.t,d)
        
        return d
    endmethod
    
    static method Execute takes nothing returns nothing
        local real x
        local real y
        local unit u
        local Data d = GetCSData(GetExpiredTimer())
        
        set d.moved = GetUnitMoveSpeed(d.d)
        set d.cd = d.cd + d.moved
        
            if d.cd >= d.maxd then
                call d.destroy()
                return
            endif
            
            if d.d == null then
                call d.destroy()
                return
            endif

        set x = GetUnitX(d.d)
        set y = GetUnitY(d.d)    
        set x = SafeX(PolarProjectionX(x, d.moved, d.angle))
        set y = SafeY(PolarProjectionY(y, d.moved, d.angle))
        
        call SetUnitX(d.d, x)
        call SetUnitY(d.d, y)
        call GroupClear(d.g2)
        call GroupEnumUnitsInRange(d.g2,x,y,Radius,Condition(function FilterIsEnemyAlive))
            
            loop
                set u = FirstOfGroup(d.g2)
                exitwhen u == null
                    if not(IsUnitInGroup(u,d.g1)) then
                        call GroupAddUnit(d.g1,u)
                        call UnitDamageTarget(d.u,u,d.dmg,false,false,A,D,null)
                        call GroupRemoveUnit(d.g2,u)
                    endif                    
                call GroupRemoveUnit(d.g2,u)
            endloop
        
            if d.spell == true then  //checks if user wants to have an ability/effect trailing the arrow
                if d.cd >= d.next then
                    set d.next = d.next + d.int
                    call IssuePointOrderById(d.a, d.aid, x, y) //orders the dummy to cast the ability to trail
                        if d.sfx != null then
                            call DestroyEffect(AddSpecialEffect( d.sfx, x, y )) //creates the special effect to trail
                        endif
                endif
            endif
                    
    endmethod
    
    private method onDestroy takes nothing returns nothing
        call RemoveUnit(.d)
        call GroupClear(.g1)
        call DestroyGroup(.g1)
        call GroupClear(.g2)
        call DestroyGroup(.g2)
        call ReleaseTimer(.t)
    endmethod
endstruct

public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real moved, real maxd, real dmg, boolean spell, integer aid, integer lvl, real int, string sfx returns nothing    
    call Data.create(ut,u,cx,cy,tx,ty,period,moved,maxd,dmg,spell,aid,lvl,int,sfx)
 //Unit-Type, Caster, CasterX, CasterY, TargetX, TargetY, TimerPeriod, DistanceMovedPerPeriod, MaxDistanceMoved, Damage, Enable another ability that trails, level of ability (trailing ability) , interval of trail (in distance intervals), special effect that trails
endfunction  

endlibrary

JASS:
scope HA initializer Init

private function Damage takes integer i returns real  //for the arrow
    return 350.00+(100.00*i)
endfunction

private function Damage2 takes integer i returns real //for the shockwave ('h00K')
    return 100.00*i
endfunction

private function MaxDist takes integer i returns real
    return 1500.00+(500.00*i)
endfunction

private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A006'
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local location l = GetSpellTargetLoc()
    local integer i = GetUnitAbilityLevel(u,GetSpellAbilityId())
    local real cx = GetUnitX(u)
    local real cy = GetUnitY(u)
    local real tx = GetLocationX(l)
    local real ty = GetLocationY(l)
    call CAS_SA('h00J',u,cx,cy,tx,ty,0.03,33,MaxDist(i),Damage(i),false,0,0,0,null)
    //false because i dont want special effects/abilities trailing the arrow
    call CAS_SA('h00K',u,cx,cy,tx,ty,0.03,33,MaxDist(i),Damage(i),true,'A00A',i,250.00,"Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl")
    // true because i want flamestrikes and a pheonix sfx to trail the shockwave
endfunction


//===========================================================================
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( trig, Condition( function Conditions ) )
    call TriggerAddAction( trig, function Actions)
endfunction
   
endscope


ok well i decided to change the custom function so you can decide whether or not you want an ability/effect to follow the arrow. well now everything works, except this line
JASS:
call IssuePointOrderById(d.a, d.aid, x, y)

thats supposed to order the dummy to use flame strike ('A00A')
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top