• 🏆 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] Whats wrong?

Status
Not open for further replies.
Level 12
Joined
Dec 10, 2008
Messages
850
Well, I've been wanting to make a spell to get back into things, and I've recently been trying to make a chain lightning spell. I think the problem with it might be the FilterFunc function, but it might not be. Any help is appreciated, but don't yell "OMGZ RIPZ OFFZ".

JASS:
scope ChainLightning initializer init
    
    globals
        private constant integer SPELL_ID = 'A000'
        private constant string Lightning = "CLSB"
        private constant string LightningImpact = "Abilities/Weapons/boltBoltImpact.mdl"
        private constant integer MAX_TARG = 3 // Change this to set what the max amount of targets is mutlitplied by the level.
        private constant boolean Decrease = false
        private constant real DMG = 100 // this will control how much damage is done per level
        boolexpr BOOL
    endglobals
    
    private function FilterFunc takes nothing returns boolean
        local unit u = GetFilterUnit()
        local boolean ok = GetWidgetLife(u) > .045 and IsUnitEnemy(u,GetOwningPlayer(GetTriggerUnit()))
        set u = null
        return ok
    endfunction

    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID
    endfunction
    
    private function Actions takes nothing returns nothing
        local unit U = GetTriggerUnit()
        local real UX = GetUnitX(U)
        local real UY = GetUnitY(U)
        local real TX
        local real TY
        local integer Level = GetUnitAbilityLevel(U,SPELL_ID)
        local integer Max1 =  Level*MAX_TARG
        local integer Max2 = 0
        local unit T 
        local unit Y
        local player P = GetOwningPlayer(U)
        local real Damage = DMG*Level
        local lightning array L
        local integer Index = 0
        local group G = CreateGroup()
        call GroupEnumUnitsInRange(G,UX,UY,99999,BOOL)
        loop
            set T = FirstOfGroup(G)
            exitwhen Max2==Max1
            call GroupRemoveUnit(G,T)
            set UX = GetUnitX(Y)
            set UY = GetUnitY(Y)
            set TX = GetUnitX(T)
            set TY = GetUnitY(T)
            set L[Index] = AddLightningEx(Lightning,false,UX,UY,50,TX,TY,50)
            call UnitDamageTarget(U,T,Damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set Y = T
            set Index = Index +1
            call TriggerSleepAction(.5)
        endloop
        loop
            exitwhen Index == 0
            call DestroyLightning(L[Index])
            set Index = Index - 1
        endloop
        call DestroyGroup(G)
        set U = null
        set T = null
    endfunction
    
//======================================================================================

    private function init takes nothing returns nothing
        local trigger I = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(I,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(I,Condition(function Conditions))
        call TriggerAddAction(I,function Actions)
        set I = null
        set BOOL = Filter(function FilterFunc)
    endfunction
endscope

Pleaase note that theres some stuff in the globals block to be added to the script still, it isn't a major part of the script, thats why I havn't added it yet, as it wouldn't affect the lightning creation part.
 
Level 11
Joined
Apr 6, 2008
Messages
760
I found 2 errors when looking over it quick

1. In the loop you have exitwhen Max2==Max1 that will give you a neverending loop

JASS:
        loop
            set T = FirstOfGroup(G)
            exitwhen Max2==Max1
            call GroupRemoveUnit(G,T)
            set UX = GetUnitX(Y)
            set UY = GetUnitY(Y)
            set TX = GetUnitX(T)
            set TY = GetUnitY(T)
            set L[Index] = AddLightningEx(Lightning,false,UX,UY,50,TX,TY,50)
            call UnitDamageTarget(U,T,Damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set Y = T
            set Index = Index +1
            call TriggerSleepAction(.5)
        endloop

JASS:
        loop
            set T = FirstOfGroup(G)
            exitwhen Index>=Max1 or T == null //you didnt use Max2 in the loop and also exitwhen loop if there is no more units
            call GroupRemoveUnit(G,T)
            set UX = GetUnitX(Y)
            set UY = GetUnitY(Y)
            set TX = GetUnitX(T)
            set TY = GetUnitY(T)
            set L[Index] = AddLightningEx(Lightning,false,UX,UY,50,TX,TY,50)
            call UnitDamageTarget(U,T,Damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set Y = T
            set Index = Index +1
            call TriggerSleepAction(.5)
        endloop

and the second was in the filterfunc

GetWidgetLife(u) > .405 not .045
 
Level 11
Joined
Apr 6, 2008
Messages
760
Check if this works for you, i made some changes.

JASS:
scope ChainLightning initializer init

    globals
        private constant integer SPELL_ID = 'A000'
        private constant string Lightning = "CLSB"
        private constant string LightningImpact = "Abilities/Weapons/boltBoltImpact.mdl"
        private constant integer MAX_TARG = 3 // Change this to set what the max amount of targets is mutlitplied by the level.
        private constant boolean Decrease = false
        private constant real DMG = 100 // this will control how much damage is done per level
        boolexpr BOOL
    endglobals

    private function FilterFunc takes nothing returns boolean
        local unit u = GetFilterUnit()
        local boolean ok = GetWidgetLife(u) > .405 and IsUnitEnemy(u,GetOwningPlayer(GetTriggerUnit()))
        set u = null
        return ok
    endfunction

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

    private function Actions takes nothing returns nothing
        local unit U = GetTriggerUnit()
        local unit T
        local unit Y
        
        local integer Level = GetUnitAbilityLevel(U,SPELL_ID)
        
        local real UX = GetUnitX(U)
        local real UY = GetUnitY(U)
        local real TX
        local real TY
        local real Damage = DMG*Level
        
        local integer Max1 = Level*MAX_TARG
        local integer Index = 0
        

        local player P = GetOwningPlayer(U)
        
        local lightning array L
        
        local group G = CreateGroup()
        
        
        call GroupEnumUnitsInRange(G,UX,UY,99999,BOOL)
        
        //I think the reason your code didnt work, because Y was equal to nothing(not even null). and when u did GetUnitX(Y) caused it to crash
        set Y = FirstOfGroup(G)
        call GroupRemoveUnit(G,Y)
        call UnitDamageTarget(U,T,Damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)

        loop
            set T = FirstOfGroup(G)
            exitwhen T == null or Index >= Max1
            call GroupRemoveUnit(G,T)
            
            set UX = GetUnitX(Y)
            set UY = GetUnitY(Y)
            set TX = GetUnitX(T)
            set TY = GetUnitY(T)
            
            set L[Index] = AddLightningEx(Lightning,false,UX,UY,GetUnitFlyHeight(Y)+50,TX,TY,GetUnitFlyHeight(T)+50)
            
            call UnitDamageTarget(U,T,Damage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            
            set Y = T
            set Index = Index + 1
            call TriggerSleepAction(.5)
        endloop
        
        loop
            exitwhen Index < 0
            call DestroyLightning(L[Index])
            set Index = Index - 1
        endloop
        
        call DestroyGroup(G)
        set U = null
        set T = null
    endfunction

//======================================================================================

    private function init takes nothing returns nothing
        local trigger I = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(I,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(I,Condition(function Conditions))
        call TriggerAddAction(I,function Actions)
        set I = null
        set BOOL = Filter(function FilterFunc)
    endfunction
    
endscope

one thing you should do it make a struct and add a timer (around 0.03 intervals) and move the lightnings. cause it the units do move while they have it look wierd.
 
Status
Not open for further replies.
Top