• 🏆 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!

What's wrong with this?

Status
Not open for further replies.
Level 3
Joined
Sep 9, 2009
Messages
658
I made a spell looks like this.

I realized later on that I could probably do it in one big loop. So I did.

JASS:
        set pf = facing + 0.523
        loop
            exitwhen pi > 3
                loop
                    exitwhen i > 8
                        set px = ux + distance * Cos(pf)
                        set py = uy + distance * Sin(pf)
                        call DestroyEffect(AddSpecialEffect(A, px, py))
                        call GroupEnumUnitsInRange(Group, px, py, 150, null)
                        
                        loop
                            set f = FirstOfGroup(Group)
                            exitwhen f == null
                                if not IsUnitInGroup(f, g) and IsUnitEnemy(f, GetOwningPlayer(u)) and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_FLYING) and not IsUnitType(f, UNIT_TYPE_DEAD) and GetUnitTypeId(f) !=0 then
                                    call GroupAddUnit(g, f)
                                endif
                            call GroupRemoveUnit(Group, f)
                        endloop
                        
                        set distance = distance + 100
                        set i = i + 1
                endloop
            set pf = pf - 0.523
            call BJDebugMsg(R2S(pf))
            set pi = pi + 1
        endloop

the debug message shows the angle increasing by 30 degrees but only one lane of ice shows up. I think all three lanes are made on the same angle.

How do I do this in only one loop?
 

Attachments

  • Anub'arak Skill.png
    Anub'arak Skill.png
    2.2 MB · Views: 86
Level 3
Joined
Sep 9, 2009
Messages
658
Yes, only facing + 30 shows up.

Also upon further testing, the spell makes the game run slower after using it a few times and I don't know why. The only handles I've declared are unit and group (a global one and a local one)

The global group is meant to never be destroyed so I leave it as it is and destroy the local group. I also null both the unit variable and the local group variable at the end.

What's making the game slower after casting it a few times?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
You never reset i between the internal and external loop. As such the internal loop will only run once as i is already larger than 8. You need to set i to 0 after the internal loop ends (such as by the pi increment statement) so that next cycle it will correctly be 0 again and the internal loop will run as intended.
 
Level 3
Joined
Sep 9, 2009
Messages
658
Thank you! I got it working the way I want to. However, I can experience a decline in performance after using it a few times. Here's the entire script. Are there any leaks?

JASS:
scope FreezeWave initializer Init
    globals
        private constant integer AID = 'A009'
        private constant string A = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
        private group Group = CreateGroup()
    endglobals
    
    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit f
        local group g = CreateGroup()
        local real ux = GetUnitX(u)
        local real uy = GetUnitY(u)
        local real sx = GetSpellTargetX()
        local real sy = GetSpellTargetY()
        local real dx = sx - ux
        local real dy = sy - uy
        local real facing
        local real pf
        local real distcheck = (dx * dx) + (dy * dy)
        local real px
        local real py
        local real distance = 100
        local real d = GetUnitAbilityLevel(u, AID) * 1000
        local integer i = 1
        local integer pi = 1
        
        if distcheck > 100 * 100 then
            set facing = Atan2(dy, dx)
        else
            set facing = GetUnitFacing(u) * bj_DEGTORAD
        endif
        
        set pf = facing + 0.523
        
        loop
            exitwhen pi > 3
                loop
                    exitwhen i > 8
                        set px = ux + distance * Cos(pf)
                        set py = uy + distance * Sin(pf)
                        call DestroyEffect(AddSpecialEffect(A, px, py))
                        call GroupEnumUnitsInRange(Group, px, py, 150, null)
                        
                        loop
                            set f = FirstOfGroup(Group)
                            exitwhen f == null
                                if not IsUnitInGroup(f, g) and IsUnitEnemy(f, GetOwningPlayer(u)) and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_FLYING) and not IsUnitType(f, UNIT_TYPE_DEAD) and GetUnitTypeId(f) !=0 then
                                    call GroupAddUnit(g, f)
                                endif
                            call GroupRemoveUnit(Group, f)
                        endloop
                        
                        set distance = distance + 100
                        set i = i + 1
                endloop
            set pf = pf - 0.523
            call BJDebugMsg(R2S(pf))
            set pi = pi + 1
            set distance = 100
            set i = 0
        endloop

        loop
            set f = FirstOfGroup(g)
            exitwhen f == null
            if IsUnitEnemy(f, GetOwningPlayer(u)) and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_DEAD) and not IsUnitType(f, UNIT_TYPE_FLYING) and GetUnitTypeId(f) !=0 then
                call UnitDamageTarget(u, f, d, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_COLD, null)
            endif
            call GroupRemoveUnit(g, f)
        endloop
        
        call DestroyGroup(g)
        
        set g = null
        set u = null
    endfunction
    
    private function Conditions takes nothing returns boolean
        if GetSpellAbilityId() == 'A009' then
            call Actions()
        endif
        return false
    endfunction

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

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
call BJDebugMsg(R2S(pf))
This will possibly leak a unique string and in single player will leak a logged message.

Next to that it should not be leaking. Maybe you are not allowing enough time for the special effects to decay between casts (they only get removed once their animation completes)?

Some people also say special effects leak no mater however that sort of leak should not generate poor performance so quickly.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Make sure the reason of slowing down is this spell by checking the spell on an empty map.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Disable ALL triggers and then repeat the following:
{
Enable the next trigger.
Test the map.
}

When you find the lagg again, you know in which trigger it is.
The you can try to find the leak.
After that, continue to enable triggers and test it until all triggers are enabled again.

You might want to enable them in a specific order because some triggers will be disabled if you disable another one.
 
Status
Not open for further replies.
Top