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

[vJass] Why does this not work? :S

Status
Not open for further replies.
Level 18
Joined
Oct 18, 2007
Messages
930
Ok i have been tried to fix this for a while, but i cant find the problem :S

Here is the Code
JASS:
scope Spell initializer Init

    globals
        // General Globals
        private constant integer AID = 'A000'
        private constant integer DID = 'n000'
        
        private constant string CAST_EFFECT = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl"
        private constant string CAST_EFFECT_ATTACH = "origin"

        // Missile Globals, keyword here is M
        private constant real M_TICK = 0.035
        private constant string M_LOOK = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl"
        private constant string M_LOOK_ATTACH = "origin" // Only thing that works with the dummy model
        private constant real M_HEIGHT = 30.
        private constant real M_SPEED = 20.
        private constant integer M_ANGLE_OF_ATTACK = 90

        // The Buff globals here. In other words, the light that sticks to the unit. Keyword here is B
        private constant real B_TICK = 0.25
        private constant string B_EFFECT = "Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl"
        private constant string B_EFFECT_ATTACH = "chest"
        private constant real B_AOE = 125. // The Area Of Effect for Damaging and Healing
        private constant real B_AOE_INCREASE = 50.
        private constant real B_TIME = 5.
        private constant real B_TIME_INCREASE = 2.

        // The Over Time Damage from the bolt, keyword here is D
        private constant string D_EFFECT = "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedDamage.mdl"
        private constant string D_EFFECT_ATTACH = "chest"
            // The damage is dealed every B_TICK interval
        private constant real D_DAMAGE = 15.
        private constant real D_DAMAGE_INCREASE = 8.
        private constant unittype D_AFFECTED = UNIT_TYPE_UNDEAD
        private constant attacktype D_AT = ATTACK_TYPE_MAGIC
        private constant damagetype D_DT = DAMAGE_TYPE_DIVINE

        // The Over Time Healing from the bolt, keyword here is H
        private constant string H_EFFECT = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
        private constant string H_EFFECT_ATTACH = "origin"
            // The healing is done every B_TICK interval
        private constant real H_HEALED = 10.
        private constant real H_HEALED_INCREASE = 5.
            // Here it is no affected. The light will only heal allied non unittypes of globals D_AFFECTED

        // The globals for the Uber Splat that appears if the unit dies when affected by the missile. Keyword here is S
        private constant string S_FIRST_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        private constant string S_SECOND_EFFECT = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
        private constant real S_AOE = 200.
        private constant real S_AOE_INCREASE = 50.
        private constant real S_DAMAGE_BOOST = 1.5 // How many times the Damage is multiplicated ( Must be over 1! or it will be a lower number )
        private constant real S_HEALING_BOOST = 1.5 // How many times the Healing is multiplicated ( Must be over 1! or it will be a lower number )
        private constant real S_KNOCKBACK_DIST = 125.
        private constant real S_KNOCKBACK_TIME = 0.8
        
        // ======================================================
        private group tmpG = CreateGroup()
        private player tmpP = null
        private unit tmpU = null
        private real tmpR = 0.0
        private real tmpR2 = 0.0
        private boolexpr Bool = null
        private real SAFETY_COLLISION
    endglobals
    
    private constant function GetTime takes integer lvl returns real
        return B_TIME + ( B_TIME_INCREASE * ( lvl - 1 ) )
    endfunction
    
    private constant function GetD_DAMAGE takes integer lvl returns real
        return D_DAMAGE + ( D_DAMAGE_INCREASE * ( lvl - 1 ) )
    endfunction
    
    private constant function GetH_HEALED takes integer lvl returns real
        return H_HEALED + ( H_HEALED_INCREASE * ( lvl - 1 ) )
    endfunction
    
    private constant function GetS_DAMAGE takes integer lvl returns real
        return ( D_DAMAGE + ( D_DAMAGE_INCREASE * ( lvl - 1 ) ) ) * S_DAMAGE_BOOST
    endfunction
    
    private constant function GetS_HEALED takes integer lvl returns real
        return ( H_HEALED + ( H_HEALED_INCREASE * ( lvl - 1 ) ) ) * S_HEALING_BOOST
    endfunction
    
    private constant function GetS_AOE takes integer lvl returns real
        return S_AOE + ( S_AOE_INCREASE * ( lvl - 1 ) )
    endfunction
    
    private constant function GetB_AOE takes integer lvl returns real
        return B_AOE + ( B_AOE_INCREASE * ( lvl - 1 ) )
    endfunction

    private function BoolFilter takes nothing returns boolean
        return GetWidgetLife(GetFilterUnit()) > .405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)
    endfunction
    
    private struct Buff
        unit u
        unit t
        player p
        integer l
        real c=0
        real mc
        
        effect e
        
        static integer array Index
        static integer Total=0
        static timer Tim=CreateTimer()
        static real nX=0
        static real nY=0
        static real nD=0
        static real nH=0
        
        static method Loop takes nothing returns nothing
            local Buff dat
            local integer i=0
            
            loop
                exitwhen i >= dat.Total
                set dat = dat.Index[i]
                
                if GetWidgetLife(dat.t) > .405 then
                    if dat.c < dat.mc then
                        set dat.nX = GetUnitX(dat.t)
                        set dat.nY = GetUnitY(dat.t)
                        
                        set tmpP = dat.p
                        call GroupEnumUnitsInRange(tmpG, dat.nX, dat.nY, GetB_AOE(dat.l), Bool)
                        
                        set dat.nD = GetD_DAMAGE(dat.l)
                        set dat.nH = GetH_HEALED(dat.l)

                        loop
                            set tmpU = FirstOfGroup(tmpG)
                            exitwhen tmpU == null
                            
                            if IsUnitAlly(tmpU, dat.p) and not IsUnitType(tmpU, D_AFFECTED) then
                                set tmpR = GetWidgetLife(tmpU)
                                set tmpR2 = GetUnitState(tmpU, UNIT_STATE_MAX_LIFE)
                                
                                if tmpR + dat.nH > tmpR2 then
                                    call SetUnitState(tmpU, UNIT_STATE_LIFE, tmpR2)
                                else
                                    call SetUnitState(tmpU, UNIT_STATE_LIFE, tmpR + dat.nH)
                                endif
                                
                                if H_EFFECT != "" then
                                    call DestroyEffect(AddSpecialEffectTarget(H_EFFECT, tmpU, H_EFFECT_ATTACH))
                                endif
                            elseif IsUnitType(tmpU, D_AFFECTED) then
                                call UnitDamageTarget(dat.u, tmpU, dat.nD, false, true, D_AT, D_DT, null)
                                
                                if D_EFFECT != "" then
                                    call DestroyEffect(AddSpecialEffectTarget(D_EFFECT, tmpU, D_EFFECT_ATTACH))
                                endif
                            endif
                            
                            call GroupRemoveUnit(tmpG, tmpU)
                            set tmpU = null
                        endloop
                        
                        set dat.c = dat.c + B_TICK
                    else
                        call DestroyEffect(dat.e)
                        set dat.u=null
                        set dat.t=null
                        set dat.e=null
                        set dat.p=null

                        set dat.Total = dat.Total - 1
                        set dat.Index[i] = dat.Index[dat.Total]
                        
                        call dat.destroy()
                        
                        set i = i - 1
                    endif
                else
                    set dat.nX = GetUnitX(dat.t)
                    set dat.nY = GetUnitY(dat.t)
                    
                    set tmpP = dat.p
                    call GroupEnumUnitsInRange(tmpG, dat.nX, dat.nY, GetS_AOE(dat.l), Bool)
                        
                    set dat.nD = GetS_DAMAGE(dat.l)
                    set dat.nH = GetS_HEALED(dat.l)
                
                    loop
                        set tmpU = FirstOfGroup(tmpG)
                        exitwhen tmpU == null
                            
                        if IsUnitAlly(tmpU, dat.p) and not IsUnitType(tmpU, D_AFFECTED) then
                            set tmpR = GetWidgetLife(tmpU)
                            set tmpR2 = GetUnitState(tmpU, UNIT_STATE_MAX_LIFE)
                                
                            if tmpR + dat.nH > tmpR2 then
                                call SetUnitState(tmpU, UNIT_STATE_LIFE, tmpR2)
                            else
                                call SetUnitState(tmpU, UNIT_STATE_LIFE, tmpR + dat.nH)
                            endif
                                
                            if H_EFFECT != "" then
                                call DestroyEffect(AddSpecialEffectTarget(H_EFFECT, tmpU, H_EFFECT_ATTACH))
                            endif
                        elseif IsUnitType(tmpU, D_AFFECTED) then
                            call UnitDamageTarget(dat.u, tmpU, dat.nD, false, true, D_AT, D_DT, null)
                                
                            if D_EFFECT != "" then
                                call DestroyEffect(AddSpecialEffectTarget(D_EFFECT, tmpU, D_EFFECT_ATTACH))
                            endif
                        endif
                        
                        call Knockback(tmpU, S_KNOCKBACK_DIST, Atan2(GetUnitY(tmpU) - dat.nY, GetUnitX(tmpU) - dat.nX), S_KNOCKBACK_TIME)
                            
                        call GroupRemoveUnit(tmpG, tmpU)
                        set tmpU = null
                    endloop
                    
                    if S_FIRST_EFFECT != "" then
                        call DestroyEffect(AddSpecialEffect(S_FIRST_EFFECT, dat.nX, dat.nY))
                        if S_SECOND_EFFECT != "" then
                            call DestroyEffect(AddSpecialEffect(S_SECOND_EFFECT, dat.nX, dat.nY))
                        endif
                    endif
                    
                    call SetUnitExploded(dat.t, true)
                    call KillUnit(dat.t)
                    call SetUnitExploded(dat.t, false)
                    
                    call DestroyEffect(dat.e)
                    set dat.u=null
                    set dat.t=null
                    set dat.e=null
                    set dat.p=null
                    
                    set dat.Total = dat.Total - 1
                    set dat.Index[i] = dat.Index[dat.Total]
                        
                    call dat.destroy()
                        
                    set i = i - 1
                endif

                set i = i + 1
            endloop
            
            if dat.Total == 0 then
                call PauseTimer(dat.Tim)
            endif
        endmethod
        
        static method create takes unit u, unit t, player p, integer l returns Buff
            local Buff dat = Buff.allocate()
            
            set dat.u = u
            set dat.t = t
            set dat.p = p
            set dat.l = l
            set dat.mc = GetTime(l)
            
            if B_EFFECT != "" then
                set dat.e = AddSpecialEffectTarget(B_EFFECT, t, B_EFFECT_ATTACH)
            endif
            
            if dat.Total == 0 then
                call TimerStart(dat.Tim, B_TICK, true, function Buff.Loop)
            endif
            
            set dat.Total = dat.Total + 1
            set dat.Index[dat.Total] = dat
            
            return dat
        endmethod
    endstruct
        
    private struct Missile
        unit u
        unit t
        unit m
        player p
        integer l
        
        effect e
            
        static integer array Index
        static integer Total=0
        static timer Tim=CreateTimer()
        static real nX=0
        static real nY=0
        static real nX2=0
        static real nY2=0
        static real nA=0
        
        static method Loop takes nothing returns nothing
            local Missile dat
            local integer i=0
            
            loop
                exitwhen i >= dat.Total
                set dat = dat.Index[i]
                
                set dat.nX=GetUnitX(dat.m)
                set dat.nY=GetUnitY(dat.m)
                set dat.nX2=GetUnitX(dat.t)
                set dat.nY2=GetUnitY(dat.t)
                
                if SquareRoot((dat.nX2-dat.nX)*(dat.nX2-dat.nX)+(dat.nY2-dat.nY)*(dat.nY2-dat.nY)) <= SAFETY_COLLISION then
                    call Buff.create(dat.u, dat.t, dat.p, dat.l)

                    call DestroyEffect(dat.e)
                    call KillUnit(dat.m)
                    set dat.u=null
                    set dat.t=null
                    set dat.m=null
                    set dat.e=null
                    
                    set dat.Total = dat.Total - 1
                    set dat.Index[i] = dat.Index[dat.Total]
                    
                    call dat.destroy()
                    
                    set i = i - 1
                else
                    set dat.nA = Atan2(dat.nY2 - dat.nY, dat.nX2 - dat.nX)
                    call SetUnitX(dat.m, dat.nX + M_SPEED * Cos(dat.nA))
                    call SetUnitY(dat.m, dat.nY + M_SPEED * Sin(dat.nA))
                    call SetUnitFacing(dat.m, dat.nA * bj_RADTODEG)
                endif
                
                set i = i + 1
            endloop
            
            if dat.Total == 0 then
                call PauseTimer(dat.Tim)
            endif
        endmethod
        
        static method create takes real x, real y, unit u, unit t, player p, integer l returns Missile
            local Missile dat = Missile.allocate()
            
            set dat.u = u
            set dat.t = t
            set dat.p = p
            set dat.l = l
            set dat.m = CreateUnit(p, DID, x, y, GetUnitFacing(u))
            call SetUnitAnimationByIndex(dat.m, M_ANGLE_OF_ATTACK)

            if M_LOOK != "" then
                set dat.e = AddSpecialEffectTarget(M_LOOK, dat.m, M_LOOK_ATTACH)
            endif

            
            if dat.Total == 0 then
                call TimerStart(dat.Tim, M_TICK, true, function Missile.Loop)
            endif
            
            set dat.Total = dat.Total + 1
            set dat.Index[dat.Total] = dat
            
            return dat
        endmethod
    endstruct
        
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId()==AID
    endfunction

    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit t = GetSpellTargetUnit()
        local player p = GetOwningPlayer(u)
        call Missile.create(GetUnitX(u), GetUnitY(u), u, t, p, GetUnitAbilityLevel(u, AID))
        set u = null
        set t = null
        set p = null
    endfunction
        
    private function Init takes nothing returns nothing
        local trigger trg = CreateTrigger()
        local player p = null
        local integer i = 0
        
        loop
            set p = Player(i)
            call TriggerRegisterPlayerUnitEvent(trg, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            
            set p = null
            set i = i + 1
            exitwhen i == bj_MAX_PLAYER_SLOTS
        endloop
        
        call TriggerAddAction(trg, function Actions)
        call TriggerAddCondition(trg, Condition(function Conditions))
        set trg = null
        
        set SAFETY_COLLISION = M_SPEED * 2 + 1

        // Preloading Stuff
        call Preload(M_LOOK)
        call Preload(B_EFFECT)
        call Preload(D_EFFECT)
        call Preload(H_EFFECT)
        call Preload(S_FIRST_EFFECT)
        call Preload(S_SECOND_EFFECT)
        call PreloadStart()
        
        // Setting the boolexpr's settings
        set Bool = Condition(function BoolFilter)
    endfunction
endscope

Here is the error message im getting all the time
attachment.php


Anyone knows why this is happening?

Attached a map ;)
 

Attachments

  • Spell.w3x
    32.8 KB · Views: 56
  • ssss.png
    ssss.png
    62.2 KB · Views: 208
Status
Not open for further replies.
Top