• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] Picking all units in front of another unit

Status
Not open for further replies.
I have a little question here.
I'm trying to make a spell, that involves choosing all units in front of the caster and making them recieve 5 random negative buffs at a time.

I'm still making the buffs, but that isn't my main problem.
I'm wondering how I can refer to those units in front of the caster.

View the image below to understand what I mean.
 

Attachments

  • blah.png
    blah.png
    3.6 KB · Views: 171
Level 20
Joined
Jul 6, 2009
Messages
1,885
Anyway, here's how to pick units within circular sector
  • Set Loc1 = <Circle origin point>
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 600.00 (<Circle radius>) of Loc1 matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True)) and do (Actions)
    • Loop - Actions
      • Set Loc2 = (Position of (Picked unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Acos((Cos((<Circular sector facing> - (Angle from Loc1 to Loc2)))))) Less than or equal to <40.00> - half of the angle at sector origin
        • Then - Actions
          • //Put actions for units within sector here
        • Else - Actions
      • Custom script: call RemoveLocation(udg_Loc2)
  • Custom script: call RemoveLocation(udg_Loc1)
lolz
 
Last edited:
Level 20
Joined
Jul 6, 2009
Messages
1,885
Yes, but you need to fill in parameters: Circle origin point (position of caster), Circle radius (range), Circular sector facing (facing of caster) and Angle at sector origin (width of area in front of caster). I have marked them on the trigger by putting < and > around parameters.
attachment.php
 

Attachments

  • lolz.jpg
    lolz.jpg
    17.4 KB · Views: 805
I did it in vJass:

JASS:
scope buffsToSector initializer i //we define a scope and a function to run on initialization
    globals
        private group grp=CreateGroup()
        private real angBetween
        private real tempFacing
        private unit tempOwner
        private constant integer ABILCODE='A000' //Set this to the proper code!
        private constant real ENUMRANGE=500 //Set your max range here, in game units
        private constant real SECTORSIZE=bj_PI/2 //Set the size of the sector you want to apply the effect to, in radians
    endglobals

    private function f takes nothing returns boolean
        local real theta=Acos(Cos(tempFacing-angBetween))
        if IsUnitEnemy(GetFilterUnit(),tempOwner) and theta<.5*SECTORSIZE then //if the enumerated unit is in the proper sector:
            //Apply some buffs!
        endif
        return false
    endfunction
    
    private function c takes nothing returns boolean
        local unit tU
        local unit targ
        if GetSpellAbilityId()==ABILCODE then //if casted abil is the right one:
            set tU=GetTriggerUnit()
            set targ=GetSpellTargetUnit()
            set tempOwner=GetOwningPlayer(tU)
            set tempFacing=GetUnitFacing(tU)*bj_DEGTORAD
            set angBetween=Atan2(GetUnitY(targ)-GetUnitY(tU),GetUnitX(targ)-GetUnitX(tU))
            call GroupEnumUnitsInRange(grp,GetUnitX(tU),GetUnitY(tU),ENUMRANGE,Filter(function f)) //Enumerate all the units within the proper range of the caster (and see function f)
            set tU=null
            set targ=null
        endif
        return false
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t=CreateTrigger() //create a trigger
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) //register ability effect
        call TriggerAddCondition(t,Condition(function c)) //define a conndition/action function
        set t=null
    endfunction
endscope

Let me know if you have any questions
 
Yes, but you need to fill in parameters: Circle origin point (position of caster), Circle radius (range), Circular sector facing (facing of caster) and Angle at sector origin (width of area in front of caster). I have marked them on the trigger by putting < and > around parameters.
attachment.php

Perfect. I will use that trigger. :)
Thank you. +Rep.

I did it in vJass:

JASS:
scope buffsToSector initializer i //we define a scope and a function to run on initialization
    globals
        private group grp=CreateGroup()
        private real angBetween
        private real tempFacing
        private unit tempOwner
        private constant integer ABILCODE='A000' //Set this to the proper code!
        private constant real ENUMRANGE=500 //Set your max range here, in game units
        private constant real SECTORSIZE=bj_PI/2 //Set the size of the sector you want to apply the effect to, in radians
    endglobals

    private function f takes nothing returns boolean
        local real theta=Acos(Cos(tempFacing-angBetween))
        if IsUnitEnemy(GetFilterUnit(),tempOwner) and theta<.5*SECTORSIZE then //if the enumerated unit is in the proper sector:
            //Apply some buffs!
        endif
        return false
    endfunction
    
    private function c takes nothing returns boolean
        local unit tU
        local unit targ
        if GetSpellAbilityId()==ABILCODE then //if casted abil is the right one:
            set tU=GetTriggerUnit()
            set targ=GetSpellTargetUnit()
            set tempOwner=GetOwningPlayer(tU)
            set tempFacing=GetUnitFacing(tU)*bj_DEGTORAD
            set angBetween=Atan2(GetUnitY(targ)-GetUnitY(tU),GetUnitX(targ)-GetUnitX(tU))
            call GroupEnumUnitsInRange(grp,GetUnitX(tU),GetUnitY(tU),ENUMRANGE,Filter(function f)) //Enumerate all the units within the proper range of the caster (and see function f)
            set tU=null
            set targ=null
        endif
        return false
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t=CreateTrigger() //create a trigger
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) //register ability effect
        call TriggerAddCondition(t,Condition(function c)) //define a conndition/action function
        set t=null
    endfunction
endscope

Let me know if you have any questions

Yeah, I asked for GUI though...
But a vJASSer could find this helpful.
 
Level 37
Joined
Mar 6, 2006
Messages
9,243
@Garfield1337, this
  • (Acos((Cos((<Circular sector facing> - (Angle from Loc1 to Loc2)))))) Less than or equal to <40.00>
could be simplified to this
  • (Cos((Sector facing - (Angle from Loc1 to Loc2)))) Greater than 0.00
The values used in place of that 0.00 should then be between -1 and 1. If greater than 0, the unit is in front of the caster. The closer the value is to one, the smaller the angle within which the units are chosen will be. You can calculate the value in degrees with simple math.

The sector facing could be the facing of the caster.


@Cokemonkey11, It think it should be like this since I gathered the ability was instant cast. And your tempOwner should be player, not unit :)

JASS:
scope buffsToSector initializer i //we define a scope and a function to run on initialization
    globals
        private group grp=CreateGroup()
        private real angBetween
        private real tempFacing
        private player tempOwner
        private unit un
        private constant integer ABILCODE='AHtc' //Set this to the proper code!
        private constant real ENUMRANGE=500 //Set your max range here, in game units
        private constant real SECTORSIZE=0.0 //Set the size of the sector you want to apply the effect to, between -1 and 1
    endglobals

    private function f takes nothing returns boolean
        local unit filt = GetFilterUnit()
        local real theta
        set angBetween=Atan2(GetUnitY(filt)-GetUnitY(un),GetUnitX(filt)-GetUnitX(un))
        set theta = Cos(tempFacing-angBetween)
        if IsUnitEnemy(filt,tempOwner) and theta>SECTORSIZE  then //if the enumerated unit is in the proper sector:
            // Apply buffs
        endif
        set filt = null
        return false
    endfunction
    
    private function c takes nothing returns boolean
        if GetSpellAbilityId()==ABILCODE then //if casted abil is the right one:
            set un = GetTriggerUnit()
            set tempOwner=GetOwningPlayer(un)
            set tempFacing=GetUnitFacing(un)*bj_DEGTORAD
            call GroupEnumUnitsInRange(grp,GetUnitX(un),GetUnitY(un),ENUMRANGE,Filter(function f)) //Enumerate all the units within the proper range of the caster (and see function f)
        endif
        return false
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t=CreateTrigger() //create a trigger
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) //register ability effect
        call TriggerAddCondition(t,Condition(function c)) //define a conndition/action function
        set t=null
    endfunction
endscope
 
@Cokemonkey11, It think it should be like this since I gathered the ability was instant cast. And your tempOwner should be player, not unit :)

Ah good catch.

What did you change beside that? I think you just updated the math to reflect what you said to garfield (good point by the way)
 
No you didn't.

The thread's name is:
[Trigger] Picking all units in front of another unit

@Garfield1337, this
  • (Acos((Cos((<Circular sector facing> - (Angle from Loc1 to Loc2)))))) Less than or equal to <40.00>
could be simplified to this
  • (Cos((Sector facing - (Angle from Loc1 to Loc2)))) Greater than 0.00
The values used in place of that 0.00 should then be between -1 and 1. If greater than 0, the unit is in front of the caster. The closer the value is to one, the smaller the angle within which the units are chosen will be. You can calculate the value in degrees with simple math.

The sector facing could be the facing of the caster.

I'll change some functions now, thanks, Maker.
 
The thread's name is:
[Trigger] Picking all units in front of another unit

Here's my trigger:

JASS:
local trigger t=CreateTrigger() //create a trigger

If function c you used SpellTargetUnit and calculated the angle for that. I calculate the angle in the filter function for each unit.

That's a big error on my part then. Nice catch.

Edit: Oops double post :(
 
Last edited by a moderator:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,259
@Garfield1337, this
  • (Acos((Cos((<Circular sector facing> - (Angle from Loc1 to Loc2)))))) Less than or equal to <40.00>
could be simplified to this
  • (Cos((Sector facing - (Angle from Loc1 to Loc2)))) Greater than 0.00

It should be
  • (Cos((Sector facing - (Angle from Loc1 to Loc2)))) Greater than or equal to 0.766
Yes the simplification holds true but the 2 lines of code given do not produce the same result.
 
Status
Not open for further replies.
Top