• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Jass Attack

Level 6
Joined
Aug 26, 2016
Messages
106
I wrote an attack system, it works great, but only one of the group of enemies near you receives damage, how can I do damage to the entire group of enemies near you?

JASS:
library CopperSwordMelee///1
function Attack_Filter takes nothing returns boolean
    return not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)
endfunction



function Trig_CopperSword1_Actions takes nothing returns nothing
    local unit u = udg_HeroBody[1]
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real f = GetUnitFacing(u) * bj_DEGTORAD
    local player p = GetOwningPlayer(u)
    local unit t
    local real x2
    local real y2
   
    call SetUnitTimeScalePercent( udg_HeroBody[1], 290.00 )
    call SetUnitAnimationByIndex(udg_HeroBody[1],GetRandomInt(1, 3))
   
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, x ,y, 150+140, function Attack_Filter)
    loop
        set t = FirstOfGroup(bj_lastCreatedGroup)
        exitwhen t == null
        set x2 = GetUnitX(t)
        set y2 = GetUnitY(t)
        if IsUnitEnemy(t, p) and IsUnitInRangeXY(t, x, y, 110) and Cos(f-Atan2(y2-y, x2-x)) > 0 then
            call UnitDamageTarget(u, t, 10, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_CLAW_HEAVY_SLICE)
            call CameraSetTargetNoiseForPlayer( GetOwningPlayer(udg_HeroBody[1]),24.80, 7.60 )
            call StopSoundBJ( gg_snd_m1hAxeHitFlesh1a, false )
            call PlaySoundOnUnitBJ( gg_snd_m1hAxeHitFlesh1a, 50.00, GetSpellAbilityUnit() )
            
            
            call GroupClear(bj_lastCreatedGroup)
            
        else
            call GroupRemoveUnit(bj_lastCreatedGroup, t)
        endif
    endloop
          
    set u = null
    set p = null
           call TriggerSleepAction( 0.24 )
           call SetUnitTimeScalePercent( udg_HeroBody[1], 100.00 )
           call SetUnitAnimationByIndex(udg_HeroBody[1],udg_AnimTag[1])
   
    
    
endfunction
function Trig_CopperSword1_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A001' ) ) then
        return false
    endif
    return true
endfunction

//===========================================================================
function InitTrig_CopperSword1 takes nothing returns nothing
    local trigger t22 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t22, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( t22, Condition( function Trig_CopperSword1_Conditions ) )
    call TriggerAddAction( t22, function Trig_CopperSword1_Actions )
     set t22 = null
endfunction

endlibrary
 
Level 24
Joined
Jun 26, 2020
Messages
1,853
I think is because you are clearing the group you are iterating in the first iteration that maches the condition, try to re place this part:
JASS:
    call GroupClear(bj_lastCreatedGroup)
else
    call GroupRemoveUnit(bj_lastCreatedGroup, t)
endif
With this:
JASS:
    // The if... then block
endif
call GroupRemoveUnit(bj_lastCreatedGroup, t)
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,590
I cleaned the code up for you. What Herly said is true but you're also forgetting to create a Unit Group in the first place:
vJASS:
library CopperSwordMelee initializer Init

function Filters takes nothing returns boolean
    return not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)
endfunction

function Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit t
    local player p = GetOwningPlayer(u)
    local group g = CreateGroup()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real f = GetUnitFacing(u) * bj_DEGTORAD

    call SetUnitTimeScalePercent( u, 290.00 )
    call SetUnitAnimationByIndex(u, GetRandomInt(1, 3))
    call GroupEnumUnitsInRange(g, x, y, 290, function Filters)

    loop
        set t = FirstOfGroup(g)
        exitwhen t == null
        if IsUnitEnemy(t, p) and IsUnitInRangeXY(t, x, y, 110) and Cos(f-Atan2(GetUnitY(t)-y, GetUnitX(t)-x)) > 0 then
            call UnitDamageTarget(u, t, 10, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_CLAW_HEAVY_SLICE)
            call CameraSetTargetNoiseForPlayer( p, 24.80, 7.60 )
            call StopSoundBJ( gg_snd_m1hAxeHitFlesh1a, false )
            call PlaySoundOnUnitBJ( gg_snd_m1hAxeHitFlesh1a, 50.00, t )
        endif
        call GroupRemoveUnit(g, t)
    endloop
  
    // Clean up memory leak
    call DestroyGroup(g)

    // Wait 0.24 seconds before resetting animation
    call TriggerSleepAction( 0.24 )
    call SetUnitTimeScalePercent(u, 100.00 )
    call ResetUnitAnimation(u)
    //call SetUnitAnimationByIndex(u, udg_AnimTag[1])

    // Clean up more memory leaks
    set u = null
    set p = null
    set g = null
endfunction

function Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A001' ) ) then
        return false
    endif
    return true
endfunction

function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
    set t = null
endfunction

endlibrary
 
Last edited:
Level 6
Joined
Aug 26, 2016
Messages
106
I cleaned the code up for you. What Herly said is true but you're also forgetting to create a Unit Group in the first place:
vJASS:
library CopperSwordMelee initializer Init

function Filters takes nothing returns boolean
    return not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)
endfunction

function Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit t
    local player p = GetOwningPlayer(u)
    local group g = CreateGroup()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real f = GetUnitFacing(u) * bj_DEGTORAD

    call SetUnitTimeScalePercent( u, 290.00 )
    call SetUnitAnimationByIndex(u, GetRandomInt(1, 3))
    call GroupEnumUnitsInRange(g, x, y, 290, function Filters)

    loop
        set t = FirstOfGroup(g)
        exitwhen t == null
        if IsUnitEnemy(t, p) and IsUnitInRangeXY(t, x, y, 110) and Cos(f-Atan2(GetUnitY(t)-y, GetUnitX(t)-x)) > 0 then
            call UnitDamageTarget(u, t, 10, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_CLAW_HEAVY_SLICE)
            call CameraSetTargetNoiseForPlayer( p, 24.80, 7.60 )
            call StopSoundBJ( gg_snd_m1hAxeHitFlesh1a, false )
            call PlaySoundOnUnitBJ( gg_snd_m1hAxeHitFlesh1a, 50.00, t )
        endif
        call GroupRemoveUnit(g, t)
    endloop
 
    // Clean up memory leak
    call DestroyGroup(g)

    // Wait 0.24 seconds before resetting animation
    call TriggerSleepAction( 0.24 )
    call SetUnitTimeScalePercent(u, 100.00 )
    call ResetUnitAnimation(u)
    //call SetUnitAnimationByIndex(u, udg_AnimTag[1])

    // Clean up more memory leaks
    set u = null
    set p = null
    set g = null
endfunction

function Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A001' ) ) then
        return false
    endif
    return true
endfunction

function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
    set t = null
endfunction

endlibrary
Thank you)
 
Top