• 🏆 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] nearby units receive damage

Status
Not open for further replies.
Level 6
Joined
Apr 16, 2011
Messages
158
I have this code:
JASS:
function Trig_unit_attacked takes nothing returns boolean
    if (not(GetUnitAbilityLevel(GetTriggerUnit(), 'B000') > 0))then
    return false
    endif
    return true
endfunction

function Trig_check takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetUnitAbilityLevel(GetFilterUnit(),'Aloc') == 0
endfunction

function Trig_chainlightning takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit e = GetAttacker()    
    local unit d = CreateUnit(GetOwningPlayer(u),'n00Z',GetUnitX(e),GetUnitY(e),0)
    call UnitAddAbility(d,'A002')
    call SetUnitAbilityLevel(d,'A002',GetUnitAbilityLevel(u,'A001')+4)
    call IssueTargetOrder(d,"chainlightning",e)
    call UnitApplyTimedLife(d,'BTLF',3)
    
    set e = null
    set d = null
endfunction

function Trig_group takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local group g = CreateGroup()
    local boolexpr b = Condition(function Trig_check)
    call GroupEnumUnitsInRect(g,GetPlayableMapRect(),b)
    call ForGroup(g,function Trig_chainlightning)
    call DestroyBoolExpr(b)
    call DestroyGroup(g)
    
    set u = null
    set g = null
    set b = null
    
endfunction

function InitTrig_Statick_Fild takes nothing returns nothing
    set gg_trg_Statick_Fild = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Statick_Fild, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(gg_trg_Statick_Fild, Condition(function Trig_unit_attacked))
    call TriggerAddAction(gg_trg_Statick_Fild, function Trig_chainlightning)
endfunction
What it does: when the User with this buff active receives a shock.

I want to exchange it for a code where only units very close to take the shock, and I want him not to be activated by EVENT_PLAYER_UNIT_ATTACKED
but units close to the caster
I can take advantage of this code?

JASS:
call GroupEnumUnitsInRect(g,GetPlayableMapRect(),b)
GetPlayableMapRect ---in--> units around

any tips on how to do?
-
edit:
I have this:
I'm not sure how to use
JASS:
constant unittype UNIT_TYPE_RANGED_ATTACKER=ConvertUnitType(8)

and
JASS:
native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
I'm not sure about X, Y goes radius
 
Level 7
Joined
Jul 3, 2011
Messages
251
Either move your actions into conditions; they proc faster, or do this.
JASS:
function Trig_unit_attacked takes nothing returns boolean
    if (not(GetUnitAbilityLevel(GetTriggerUnit(), 'B000') > 0))then
    return false
    endif
    return true
endfunction
-->
JASS:
Trig_unit_attacked takes nothing returns boolean
    return GetUnitAbilityLevel(GetTriggerUnit(), 'B000') > 0
endfunction

JASS:
function InitTrig_Statick_Fild takes nothing returns nothing
    set gg_trg_Statick_Fild = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Statick_Fild, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(gg_trg_Statick_Fild, Condition(function Trig_unit_attacked))
    call TriggerAddAction(gg_trg_Statick_Fild, function Trig_chainlightning)
endfunction
-->
JASS:
function InitTrig_Statick_Fild takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function Trig_unit_attacked))
    call TriggerAddAction(t, function Trig_chainlightning)
    set t = null
endfunction

As for picking units near the attacked unit, use this
JASS:
 native GroupEnumUnitsInRange                takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing

If i read this post right, then you're unsure how to use it?
JASS:
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, 500., <your condition filter>
Where i put 500. that is the area in which it will pick units from, if they meet the condition filter's conditions.
 
Level 6
Joined
Apr 16, 2011
Messages
158
-.-.-.-.-.-.-.-.-.-.-.-.-.-
of the things I'm trying to learn is to clear the codes.
understood that they refer to my unit.in
JASS:
 GroupEnumUnitsInRange
I was unsure about
JASS:
 real radius
and on X, Y, but now I
thanks
+rep
-.-.-.-.-.-.-.-.-.-.-.-.-.-
the code was the following:
JASS:
function Trig_unit_buff_Overload takes nothing returns boolean
    return GetUnitAbilityLevel(GetTriggerUnit(), 'B000') > 0
endfunction

function Trig_Overload_check takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetUnitAbilityLevel(GetFilterUnit(),'Aloc') == 0 and IsUnitHidden(GetFilterUnit()) == false
endfunction

function Trig_Overload_Action takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit e = GetAttacker()    
    local unit d = CreateUnit(GetOwningPlayer(u),'n00Z',GetUnitX(e),GetUnitY(e),0)
    
    call UnitAddAbility(d,'A002')
    call SetUnitAbilityLevel(d,'A002',GetUnitAbilityLevel(u,'A001')+4)
    call IssueTargetOrder(d,"chainlightning",e)
    call UnitApplyTimedLife(d,'BTLF',3)
    
    set e = null
    set d = null
endfunction

function Trig_group takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local group g = CreateGroup()
    local boolexpr b = Condition(function Trig_Overload_check)    
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, 500., b)
    call ForGroup(g,function Trig_Overload_Action)
    call DestroyBoolExpr(b)
    call DestroyGroup(g)
    
    set u = null
    set g = null
    set b = null
    
endfunction

function InitTrig_Overload takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function Trig_unit_buff_Overload))
    call TriggerAddAction(t, function Trig_Overload_Action)
    set t = null
endfunction

I still use:
EVENT_PLAYER_UNIT_ATTACKED

there is something that refers to: unit has buff ?
 
Last edited:
Level 7
Joined
Jul 3, 2011
Messages
251
I would still recommend moving your actions into condtions, but you can check if a unit has a buff, but you can not do it as an event
JASS:
native          GetUnitAbilityLevel takes unit whichUnit, integer abilcode returns integer
you can use this to check if a unit has a buff, for instance
JASS:
local unit u = GetTriggerUnit()
if GetUnitAbilityLevel(u, 'Bams') > 0 then
  // Stuff here
that checks if the triggering unit has 'Bams' which is anti-magic.
 
Level 6
Joined
Apr 16, 2011
Messages
158
take a look now
JASS:
function Trig_unit_buff_Overload takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

function Trig_Overload_check takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetUnitAbilityLevel(GetFilterUnit(),'Aloc') == 0 and IsUnitHidden(GetFilterUnit()) == false
endfunction

function Trig_Overload_Action takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit e = GetAttacker()    
    local unit d = CreateUnit(GetOwningPlayer(u),'n00Z',GetUnitX(e),GetUnitY(e),0)

    call UnitAddAbility(d,'A002')
    call SetUnitAbilityLevel(d,'A002',GetUnitAbilityLevel(u,'A001')+4)
    call IssueTargetOrder(d,"chainlightning",e)
    call UnitApplyTimedLife(d,'BTLF',3)
    
    set e = null
    set d = null
    
endfunction

function Trig_group takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local group g = CreateGroup()
    local boolexpr b = Condition(function Trig_Overload_check)    
    if GetUnitAbilityLevel(u, 'B000') > 0 then
    call GroupEnumUnitsInRange(g, x, y, 500., b)
    call ForGroup(g,function Trig_Overload_Action)
    endif
    
    call DestroyBoolExpr(b)
    call DestroyGroup(g) 
    set u = null
    set g = null
    set b = null
endfunction

function InitTrig_Overload takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Trig_unit_buff_Overload))
    call TriggerAddAction(t, function Trig_group)
    set t = null
endfunctionn


everything starts throwing ability A001
the condition is the unit has buff X
he calls Trig_group that takes the units in the region and arranges for Trig_Overload_Action
but in game nothing happens.
 
Level 7
Joined
Jul 3, 2011
Messages
251
Your problem is the function you are calling uses GetTriggerUnit() and GetAttacker(), you can only use theese functions in the condition/action, outside of those the trigger cannot see them, so it does not know what those values are. Also you dont need this line
JASS:
local boolexpr b = Condition(function Trig_Overload_check)
you can do this instead
JASS:
if GetUnitAbilityLevel(u, 'B000') > 0 then
    call GroupEnumUnitsInRange(g, x, y, 500., Filter(function Trig_Overload_check))
    call ForGroup(g,function Trig_Overload_Action)
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Don't create/destroy local group. Use bj_lastCreatedGroup.

No reason to use a Filter AND a ForGroup. In fact, you should be using neither in this case, and instead use a FirstOfGroup loop.

Also, don't destroy boolexpr. This isn't the return bug era any more, boolexprs do not leak if you call the same one multiple times.

The unit is attacked event is abusable. Better get a damage engine to handle the event for you.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Most of what have been already sid plus:

- merge conditions & anctions together
- 'ById' order actions proves to be faster
- GroupEnum does not enumerate locust units
- perform actions via filter function

As said, this script won't work since "GetAttacker() isn't properly response. You should make use of Damage Engine by Bride.
Anyways, here are the improvements implemented; yet it still wont work because of attacking unit reference (udg_GlobalUnit is global unit variable).
JASS:
function Trig_Overload_check takes nothing returns boolean
    local unit u = GetFilterUnit()
    local unit e
    if IsUnitType(u,UNIT_TYPE_HERO) and IsUnitEnemy(u,GetOwningPlayer(udg_GlobalUnit)) and not IsUnitHidden(u) then
        set e = GetAttacker()
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(u),'n00Z',GetUnitX(e),GetUnitY(e),0)
        call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',3)
        call UnitAddAbility(bj_lastCreatedUnit,'A002')
        call SetUnitAbilityLevel(bj_lastCreatedUnit,'A002',GetUnitAbilityLevel(u,'A001')+4)
        call IssueTargetOrderById(bj_lastCreatedUnit,852119,e)
        set e = null
    endif
    set u = null
    return false
endfunction

function Trig_group takes nothing returns boolean
    if GetSpellAbilityId() == 'A001' then
        set udg_GlobalUnit = GetTriggerUnit()
        if GetUnitAbilityLevel(udg_GlobalUnit, 'B000') > 0 then
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, GetUnitX(udg_GlobalUnit), GetUnitY(udg_GlobalUnit), 500., Filter(Trig_Overload_check))
        endif
    endif
    return false
endfunction

function InitTrig_Overload takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Filter(function Trig_group))
    set t = null
endfunctionn
 
Status
Not open for further replies.
Top