• 🏆 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] Spells Bugged, need help.

Status
Not open for further replies.
Level 31
Joined
May 3, 2008
Messages
3,155
Ok, recently I started to work back at my project and found many of my spells was currently bugged such as having no model or the spells doesn't effect the targeted unit. Here is the list of spells with issues.


1) Arrow Prison Skills
Problem: The skills does damage and work fine, but there should be special effect affected all unit within the spells range when the skills confine the target.

JASS:
scope ArrowPrison initializer init

//##################################################################################################################
globals
//******************************
//* Config
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
    public          constant integer            ABIL_ID             = 'A637'
//*
    public          constant real               HEIGHT_OFFSET       = 70
    public          constant real               SPEED               = 900
    public          constant real               ARC                 = 0
//*
    public          constant string             TARGET_FX_PATH      = "Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl"
//*
//*
    public          real array                  RADIUS          
    public          real array                  EXPIRE_TIME
    public          real array                  ARROW_DAMAGE
    public          integer array               ARROWS
//*
//*
//* Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
    private         
    private         group                       data__tempGrp       = CreateGroup()
//*
//*
//******************************************************************************************************************
endglobals


native UnitAlive takes unit u returns boolean


//##################################################################################################################
struct arrowprison extends projectile
//******************************
//* Arrow Prison Projectile
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
//*
    readonly        integer             level
//*
    private         effect              model           = null
    private static  constant string     modelpath       = "Abilities\\Weapons\\GuardTowerMissile\\GuardTowerMissile.mdl"
    private static  constant integer    unitid          = 'dumm'
//*
    private         group               targets         = null
//*
//*
    method onDestroy takes nothing returns nothing
        call DestroyEffect(model)
        call ReleaseGroup(targets)
    endmethod
//*
//*
    method isValidTargetUnit takes unit u returns boolean
        return IsUnitEnemy(u, GetOwningPlayer(source))  and /*
            */ not IsUnitInGroup(u, targets)            and /*
            */ not IsUnitType(u, UNIT_TYPE_STRUCTURE)   and /*
            */ UnitAlive(u) and u!=toUnit
    endmethod
    method onUnitCollision takes unit u returns nothing
        call GroupAddUnit(targets, u)
        call UnitDamageTarget(source, u, ARROW_DAMAGE[level],   /*
            */ false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null)
    endmethod
//*
//* 
    static method create takes unit caster, real x, real y, real face, unit target, integer level returns thistype
        local thistype m
    
        set m = allocate(CreateUnit(GetOwningPlayer(caster), unitid, x, y, face))
        set m.source  = caster
        set m.target  = target
        set m.level   = level
        set m.model   = AddSpecialEffectTarget(modelpath, m.toUnit, "origin")
        set m.targets = NewGroup()
        
        set m.z = m.z + HEIGHT_OFFSET
        
        set m.activeDestCollision   = false
        set m.activeUnitCollision   = true
        set m.activeRotation        = true
        set m.activePitch           = true
        
        return m
    endmethod
//*
//*
//******************************************************************************************************************
endstruct


//##################################################################################################################
private struct spelltargetdata
//******************************
//* Spell Target Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Tracks units that are affected by "Arrow Prison". When a unit is affected by two individual instances of
//* ArrowPrison I use "AutoData" to ensure that it will not break the functionality. The aim is to eliminate the
//* bugs associated with units being unpaused by a previous instance of the spell.
//*
//*
    implement       AutoData
//*
//*
    method onDestroy takes nothing returns nothing
        if spelltargetdata[me].size <= 1 then   //the buffs applied will only be removed if there are no other
            call SetUnitTimeScale(me, 1)        //instances of "spelltargetdata" that apply to this unit.
            call PauseUnit(me, false)
        endif
    endmethod
//*
//*
    static method create takes unit target returns thistype
        local thistype m
        if spelltargetdata[target] == 0 then    //the buffs will only be applied if the target is not already
            call SetUnitTimeScale(target, 0)    //under the effects of another instance of "spelltargetdata".
            call PauseUnit(target, true)
        endif
        set m = allocate()
        set m.me = target
        return m
    endmethod
//*
//*
//******************************************************************************************************************
endstruct


//##################################################################################################################
private struct spelldata
    public      unit                caster      = null
    public      unit                target      = null
    public      integer             level
    
    public      real                x
    public      real                y
    
    public      group               grp         = null
    public      projectilegroup     grpProj
    
    method onDestroy takes nothing returns nothing
        call ReleaseGroup(grp)
        call grpProj.destroy()
    endmethod
    
    static method create takes nothing returns thistype
        local thistype m = allocate()
        local integer i  = 0
        local integer n 
        local real x
        local real y
        local vector vi
        local vector vf
        
        set m.caster  = GetTriggerUnit()
        set m.target  = GetSpellTargetUnit()
        set m.x       = GetSpellTargetX()
        set m.y       = GetSpellTargetY()
        set m.level   = GetUnitAbilityLevel(m.caster, ABIL_ID)-1
        set m.grp     = NewGroup()
        set m.grpProj = projectilegroup.create()
        
        set vf = vector.createTerrainPoint(m.x, m.y)
        set vf.z = vf.z + HEIGHT_OFFSET
        
        set n  = ARROWS[m.level]
        loop
            exitwhen i == n
            
            set x = GetUnitX(m.target) + RADIUS[m.level] * Cos((2*bj_PI/n)*i)
            set y = GetUnitY(m.target) + RADIUS[m.level] * Sin((2*bj_PI/n)*i)
            call m.grpProj.add( arrowprison.create(m.caster, x, y, (360/n)*i - 180, m.target, m.level) )
            
            set vi = vector.createTerrainPoint(x, y)
            set vi.z = vi.z + HEIGHT_OFFSET
            set m.grpProj.at[i].timescale = 0
            call m.grpProj.at[i].doLaunch(vi, vf, SPEED, ARC)
            
            call vi.destroy()
            set i = i + 1
        endloop
        call vf.destroy()
        
        return m
    endmethod
endstruct

//##################################################################################################################
private function run_efilter takes nothing returns boolean
    local unit t = GetTriggerUnit()
    local unit f = GetFilterUnit()
    local boolean r
    
    set r = IsUnitEnemy(f, GetOwningPlayer(t)) and          /*
        */ not IsUnitType(f, UNIT_TYPE_STRUCTURE) and       /*
        */ not IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) and    /*
        */ UnitAlive(f) and f!=t
        
    if r then
        call spelltargetdata.create(f)
    endif
        
    set t = null
    set f = null
    return r
endfunction

//##################################################################################################################
private function run_expireEnum takes nothing returns nothing
    call spelltargetdata[GetEnumUnit()].destroy()
    
endfunction
private function run_expire takes nothing returns nothing
    local spelldata d = GetTimerData(GetExpiredTimer())
    local integer i   = 0
    
    call ForGroup(d.grp, function run_expireEnum)
    // Remove any buff that this spell applied to the target units.
    
    loop
        exitwhen i == d.grpProj.max
        set d.grpProj.at[i].timescale = 1
        set i = i + 1
    endloop
    
    call d.destroy()
    call ReleaseTimer(GetExpiredTimer())
endfunction

//##################################################################################################################
public function checkid takes nothing returns boolean

    return GetSpellAbilityId() == ABIL_ID
    
endfunction
public function run takes nothing returns nothing
    local spelldata d = spelldata.create()
    local timer t = NewTimer()
    
    call GroupEnumUnitsInRange(d.grp, GetUnitX(d.target), GetUnitY(d.target),   /*
                                            */ RADIUS[d.level], Filter(function run_efilter))
    call SetTimerData(t, d)
    call TimerStart(t, EXPIRE_TIME[d.level], false, function run_expire)
    
    set t = null
endfunction

//##################################################################################################################
public function init takes nothing returns nothing
    local trigger t = CreateSpellTrigger(null)
    call TriggerAddCondition(t, Filter(function checkid))
    call TriggerAddAction(t, function run)
    
    //--------------------------------------------------------------------------------------------------------------
    // Spell Constant Values
    //--------------------------------------------------------------------------------------------------------------
    set RADIUS[0]           = 500
    set RADIUS[1]           = 500
    set RADIUS[2]           = 500
    //--------------------------------------------------------------------------------------------------------------
    set EXPIRE_TIME[0]      = 3
    set EXPIRE_TIME[1]      = 4
    set EXPIRE_TIME[2]      = 5
    //--------------------------------------------------------------------------------------------------------------
    set ARROWS[0]           = 12
    set ARROWS[1]           = 12
    set ARROWS[2]           = 12
    //--------------------------------------------------------------------------------------------------------------
    set ARROW_DAMAGE[0]     = 35
    set ARROW_DAMAGE[1]     = 45
    set ARROW_DAMAGE[2]     = 60
    //--------------------------------------------------------------------------------------------------------------
    
    set t = null
endfunction

endscope


2) Arrow Split
Problem: When the arrow travel for a certain distance, it should split into 12 smaller arrow that hit and damage all enemies. Problem is, when the arrow travel a certain distance it just dissappear.

JASS:
scope ArrowSplit initializer init

native UnitAlive takes unit u returns boolean


globals
//******************************
//* Config & Setup
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    public      constant integer        ABIL_ID         = 'A62X'
    public      constant integer        DUMM_ID         = 'dumm'
//*
//* Projectile Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    public      constant real           SPEED_PRIMARY   = 550
    public      constant real           ARC_PRIMARY     = 0
//*
    public      constant real           SPEED_SECONDARY = 800
    public      constant real           ARC_SECONDARY   = 0
    public      constant real           RANGE_SECONDARY = 700
//*
    public      constant real           HEIGHT_OFFSET   = 60
//*
    public      real array              DAMAGE_SECONDARY
    public      integer array           SPLIT_COUNT     
//*
//*
//******************************************************************************************************
endglobals



private struct arrowsplit_arrow extends projectile
//******************************
//* Arrow Split Secondary Projectile
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Duplicate of the "ArrowSplit" projectiles with different actions.
//*
    readonly        integer             level
//*
    private         effect              obj__model      = null
    private static  constant string     obj__modelpath  = "Abilities\\Weapons\\GuardTowerMissile\\GuardTowerMissile.mdl"
//*
//*
    private static  constant real       obj__speed      = SPEED_SECONDARY
    private static  constant real       obj__arc        = ARC_SECONDARY
//*
//*
    method onDestroy takes nothing returns nothing
        call DestroyEffect(obj__model)
    endmethod
//*
//*
    method isValidTargetUnit takes unit u returns boolean
        return IsUnitEnemy(u, GetOwningPlayer(source))  and /*
        */ not IsUnitType(u, UNIT_TYPE_STRUCTURE)       and /*
        */ not IsUnitType(u, UNIT_TYPE_FLYING)          and /*
        */ UnitAlive(u)
    endmethod
    method onUnitCollision takes unit u returns nothing
        call UnitDamageTarget(source, u, DAMAGE_SECONDARY[level], false, false, /*
                                    */ ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null)
        call kill( )
    endmethod
//*
//*
    static method create takes unit source, vector vi, vector vf, integer level returns thistype
        local thistype m
        local real     a = Atan2(vf.y-vi.y, vf.x-vi.x)
        
        set m = allocate(CreateUnit(GetOwningPlayer(source), DUMM_ID, vi.x, vi.y, a*bj_RADTODEG))
        set m.obj__model = AddSpecialEffectTarget(obj__modelpath, m.toUnit, "origin")
        set m.source = source
        set m.level = level
        
        set m.toRemove = true
        set m.toKill = false
        set m.activeDestCollision = false
        
        call m.doLaunch(vi, vf, obj__speed, obj__arc)
        return m
    endmethod
//*
//*
//******************************************************************************************************
endstruct

struct arrowsplit extends projectile
//******************************
//* Arrow Split Projectile
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Primary data structure that represents the initial projectile that is fired when the ability is
//* put into effect. This arrow will split up into several "arrowsplit_arrow" structures.
//*
    readonly        integer             level       
//*
    private         effect              obj__model      = null
    private static  constant string     obj__modelpath  = "Abilities\\Weapons\\GuardTowerMissile\\GuardTowerMissile.mdl"
//*
//*
    private static  constant real       obj__speed      = SPEED_PRIMARY
    private static  constant real       obj__arc        = ARC_PRIMARY
//*
//*
    method onDestroy takes nothing returns nothing
        call DestroyEffect(obj__model)
    endmethod
//*
//*
    method onFinish takes nothing returns nothing
        local integer i = 0
        local integer n = SPLIT_COUNT[level]
        local vector vi
        local vector vf
        
        set vi = vector.create(targetX, targetY, targetZ)
        loop
            exitwhen i == n
            // ----
            // Once the initial arrow has reached its target, it will explode into several smaller
            // arrows that travel outwards and deal damage to enemy units.
            
            set vf = vector.createTerrainPoint(vi.x+RANGE_SECONDARY*Cos((2*bj_PI/n)*i), /*
                                            */ vi.y+RANGE_SECONDARY*Sin((2*bj_PI/n)*i))
            set vf.z = vf.z + HEIGHT_OFFSET
        
            call arrowsplit_arrow.create(source, vi, vf, level)
            call vf.destroy( )
            
            set i = i + 1
        endloop
        call vi.destroy( )
    endmethod
//*
//*
    static method create takes unit source, vector vi, vector vf, integer level returns thistype
        local thistype m
        local real     a = Atan2(vf.y-vi.y, vf.x-vi.x)
        
        set m = allocate(CreateUnit(GetOwningPlayer(source), DUMM_ID, vi.x, vi.y, a*bj_RADTODEG))
        set m.obj__model = AddSpecialEffectTarget(obj__modelpath, m.toUnit, "origin")
        set m.source = source
        set m.level = level
        // Allocate the projectile with a unit using configuration values.
        
        set m.toRemove = true
        set m.toKill = false
        set m.activeDestCollision = false
        set m.activeUnitCollision = false
        
        call m.doLaunch(vi, vf, obj__speed, obj__arc)
        // Launch allocated projectile with specified input.
        
        return m
    endmethod
//*
//*
//******************************************************************************************************
endstruct


//######################################################################################################
//#
//#     SPELL TRIGGER SETUP
//#
//######################################################################################################
public function run takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local vector vi = vector.createTerrainPoint(GetUnitX(u), GetUnitY(u))
    local vector vf = vector.createTerrainPoint(GetSpellTargetX(), GetSpellTargetY())
    
    set vi.z = vi.z + HEIGHT_OFFSET
    set vf.z = vf.z + HEIGHT_OFFSET

    call arrowsplit.create(u, vi, vf, GetUnitAbilityLevel(u, ABIL_ID))
    set u = null
    
endfunction
public function checkId takes nothing returns boolean
    return GetSpellAbilityId()==ABIL_ID
endfunction
//#
//# Initialization
//# ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
public function init takes nothing returns nothing
    local trigger t=CreateSpellTrigger(null)
    
    call TriggerAddCondition(t, Filter(function checkId))
    call TriggerAddAction(t, function run)
    
//# ----------------------------------------------------------------------------------------------------
    set DAMAGE_SECONDARY[0]     = 50
//# ----------------------------------------------------------------------------------------------------
    set SPLIT_COUNT[0]          = 12
//# ----------------------------------------------------------------------------------------------------

endfunction
//#
//######################################################################################################
endscope

3) Electric Chain
Problem: When the unit attack enemies for 7 times, the next attack should had unleash a chain lightning against the enemies but it doesn't seems to happen.

JASS:
library ElectricChain initializer Init requires SpellIndexer
//*
struct Chain
//*
    static constant     real            COOLDOWN    = 0.6 //Prevents spamming "stop"
    static              unit array      Attack
    static              timer array     Tim
    static              Chain array     stack
 
    integer     count   = 0
    boolean     dont    = false
    effect      eff     = null
    player      owner   = null
    timer       tim     = null
//*
//* Get Attacking Unit's ID
//* ============================================================================
    static method RetrieveViaAttacker takes unit u returns Chain
        local integer i = 0
        loop
            if .Attack[i] == u then
                exitwhen true
            elseif .Attack[i] == null then
                set .stack[i]           = Chain.allocate()
                set .Attack[i]          = u
                set .Tim[i]             = CreateTimer()
                set .stack[i].tim       = .Tim[i]
                set .stack[i].owner     = GetOwningPlayer(u)
                exitwhen true
            endif
            set i = i + 1
        endloop
        return .stack[i]
    endmethod
//*
//* Failsafe so player can't spam "Stop"
//* ============================================================================
    static method RetrieveViaTimer takes nothing returns nothing
        local integer i = 0
        local timer t = GetExpiredTimer()
        loop
            exitwhen .Tim[i] == t
            set i = i + 1
        endloop
        set .stack[i].dont = false
    endmethod
//*
//* Main Setup
//* ============================================================================
    static method Actions takes unit att,unit trg,unit u returns nothing
        local Chain this = .RetrieveViaAttacker(att)
        local integer level = GetUnitAbilityLevel(att,'A626')
        if IsUnitEnemy(trg,.owner) and not .dont then
            if .count == 9 - level then
                set .eff = AddSpecialEffectTarget("Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.mdl",att,"weaponleft")
                set .count = .count + 1
            elseif .count == 10 - level then
                set .count = 0
                set u = CreateUnit(.owner,'h60W',GetUnitX(att),GetUnitY(att),GetUnitFacing(att))
                call UnitAddAbility(u,'A61X')
                call SetUnitAbilityLevel(u,'A61X',level)
                call IssueTargetOrder(u,"chainlightning",trg)
                call UnitApplyTimedLife(u,'BTLF',0.50)
                call DestroyEffect(.eff)
            else
                set .count = .count + 1
            endif
        endif
        set .dont = true
        call TimerStart(.tim,COOLDOWN,false,function Chain.RetrieveViaTimer)
    endmethod
//*
//* Conditions
//* ============================================================================
    static method Conditions takes nothing returns boolean
        if GetUnitAbilityLevel(GetAttacker(),'B612') > 0 then
            call .Actions(GetAttacker(),GetTriggerUnit(),null)
        endif
        return false
    endmethod
//*
//*
endstruct
//*
//* Setup Initialization
//* ===========================================================================
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddCondition(t,Condition(function Chain.Conditions))
    endfunction

endlibrary

4) Lightning Strike
Problem: When this skills was activate, there should be a lightning hitting the targeted area, dealing damage and knockback the enemies. However, the spells doesn't seems to be working now.

JASS:
scope LightningStrike initializer init

native UnitAlive takes unit u returns boolean


//##############################################################################################################
private struct spelldata
//******************************
//* Spell Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Stores relevant data to the spell being put into effect so that it can be referenced associatively.
//*
    readonly    unit        caster      = null
    readonly    real        targetx 
    readonly    real        targety
    readonly    integer     level
//*
//*
    static method create takes nothing returns thistype
        local thistype m = allocate()
        
        set m.caster    = GetTriggerUnit()
        set m.targetx   = GetSpellTargetX()
        set m.targety   = GetSpellTargetY()
        set m.level     = GetUnitAbilityLevel(m.caster, GetSpellAbilityId())
        
        return m
    endmethod
//*
//*
//**************************************************************************************************************
endstruct


globals
//******************************
//* Config
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
    public          constant integer        ABIL_ID             = 'A621'
//*
    public          constant real           KNOCKBACK_DISTANCE  = 325
    public          constant real           KNOCKBACK_DURATION  = 1.45
//*
    public          constant real           AREA_OF_EFFECT      = 400
//*
//* Temp Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    private         group                   temp__grp           = CreateGroup()
    private         spelldata               temp__data      
//*
//*
//**************************************************************************************************************
endglobals



//##############################################################################################################
private struct strikeknockback extends knockback
//******************************
//* Ability Knockback
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Controls the knockback when a unit is struck by lightning. Requires the "KnockbackLite" vJass library in
//* order to properly inherit the necessary members. This basically just adds a dust effect to the knock-back.
//*
//* In addition, units that are being knocked back will destroy nearby destructables.
//*
    readonly            real            size            
//*
    private static      timer           loop__tmr       = CreateTimer()
    private static      constant real   loop__tmrRef    = 0.03
//*
    private static      rect            dest__enum      = Rect(0, 0, 0, 0)
    private static      boolexpr        dest__enumfilt  = null
    private static      thistype        dest__tempdata 
//*
    private static      thistype array  loop__stack    
    private static      integer         loop__stacksize = 0
    private             integer         loop__stackindex
//*
    method onDestroy takes nothing returns nothing
        set thistype.loop__stacksize=thistype.loop__stacksize-1
        set thistype.loop__stack[loop__stackindex]=thistype.loop__stack[thistype.loop__stacksize]
        set thistype.loop__stack[loop__stackindex].loop__stackindex=loop__stackindex
    endmethod
//*
//*
    private static method loopfunc_enumfilter takes nothing returns boolean
        local thistype kb = dest__tempdata
        local destructable dest = GetFilterDestructable()
        local real x = GetWidgetX(dest)-GetWidgetX(kb.subject)
        local real y = GetWidgetY(dest)-GetWidgetY(kb.subject)
        if (x*x + y*y) <= (kb.size*kb.size) then
            call KillDestructable(dest)
        
        endif
        set dest = null
        return false
    endmethod
    private static method loopfunc takes nothing returns nothing
        local integer i = loop__stacksize-1
        local thistype kb
        local real x
        local real y
        loop
            exitwhen i < 0
            set kb = loop__stack[i]
            if kb != 0 then
                set x = GetWidgetX(kb.subject)
                set y = GetWidgetY(kb.subject)
            
                set dest__tempdata = kb
                call SetRect(dest__enum, x-kb.size/2, y-kb.size/2, x+kb.size/2, y+kb.size/2)
                call EnumDestructablesInRect(dest__enum, dest__enumfilt, null)
                
                // -> Insert other knockback specifications...
                
            endif
            set i = i-1
        endloop
    endmethod
//*
//*
    static method create takes unit u, real angle, real size returns thistype
        local thistype kb = allocate(u, angle, KNOCKBACK_DISTANCE, KNOCKBACK_DURATION)
        
        set kb.size = size
        if loop__stacksize == 0 then
            call TimerStart(loop__tmr, loop__tmrRef, true, function thistype.loopfunc)
        endif
        set kb.loop__stackindex = loop__stacksize
        set loop__stack[loop__stacksize] = kb       // Add the newly initiated instance to the stack.
        set loop__stacksize = loop__stacksize+1
        
        return kb
    endmethod
//*
//*
    private static method onInit takes nothing returns nothing
        set dest__enumfilt = Filter(function thistype.loopfunc_enumfilter)
        // To avoid unnecessary calls to the native "Filter" we can just save this value in memory.
    endmethod
//*
//*
//************************************************************************************************************** 
endstruct


//##############################################################################################################
public function startKB takes nothing returns boolean
    local unit filt = GetFilterUnit()
    local boolean result
    
    set result = IsUnitEnemy(filt, GetOwningPlayer(temp__data.caster))  and /*
                */ not IsUnitType(filt, UNIT_TYPE_STRUCTURE)            and /*
                */ not IsUnitType(filt, UNIT_TYPE_FLYING)               and /*
                */ not IsUnitType(filt, UNIT_TYPE_MAGIC_IMMUNE)         and /*
                */ not IsUnitType(filt, UNIT_TYPE_SNARED)               and /*
                */ UnitAlive(filt)
    
    if result then
        call strikeknockback.create(filt, Atan2(GetUnitY(filt)-temp__data.targety, /*
                                            */ GetUnitX(filt)-temp__data.targetx), 250)
    endif
    set filt = null
    return false
endfunction


//##############################################################################################################
public function checkid takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_ID

endfunction
public function run takes nothing returns nothing
    set temp__data = spelldata.create()
    call GroupEnumUnitsInRange(temp__grp, temp__data.targetx, temp__data.targety, /*
                                        */ AREA_OF_EFFECT, Filter(function startKB))
    call temp__data.destroy()
endfunction

//##############################################################################################################
public function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    loop
        exitwhen i == 16
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set i = i + 1
    endloop
    call TriggerAddCondition(t, Filter(function checkid))
    call TriggerAddAction(t, function run)
endfunction


endscope

5) Stomp of Corruption
Problem: This skill work fine in all way except that it doesn't applied negative buff towards the enemy.

JASS:
scope StompOfCorruption initializer init


//######################################################################################################
globals
//**************************
//* Config 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
    public      constant integer    abilityID       = 'A63J'
//*
    public      constant real       knockbackRange  = 400
    public      constant real       knockbackLife   = 1.5       // ->   this means that the knockback
                                                                //      will last 1.5 seconds.
//*
//*
//******************************************************************************************************
endglobals


//######################################################################################################
public function init takes nothing returns nothing


endfunction


endscope



function Stomp_of_Corruption_Destructible_Utility takes destructable d returns boolean
    local real dx=LoadReal(udg_SOC_Hash,0,7)-GetWidgetX(d)
    local real dy=LoadReal(udg_SOC_Hash,0,8)-GetWidgetY(d)
    if SquareRoot(dx*dx+dy*dy)<=200. then
        call KillDestructable(d)
        endif
        return false
endfunction

function Stomp_of_Corruption_Destructible_Filter takes nothing returns boolean
    return Stomp_of_Corruption_Destructible_Utility(GetFilterDestructable())
endfunction

function Stomp_of_Corruption_Do_Knockback takes integer id,unit u,rect r,real max,real dist,real speed,real vX,real vY returns nothing
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)
    local real inc=2.*speed
    set vX=x+vX*inc
    set vY=y+vY*inc
    call MoveRectTo(r,vX,vY)
    call SaveReal(udg_SOC_Hash,0,7,vX)
    call SaveReal(udg_SOC_Hash,0,8,vY)
    call EnumDestructablesInRect(r,Filter(function Stomp_of_Corruption_Destructible_Filter),null)
    if (GetRandomInt(0,6)<1) then
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",x,y))
    endif
    if (GetRandomInt(0,4)<1) then
        call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl",x,y))
    endif
    call SetUnitX(u,vX)
    call SetUnitY(u,vY)
    call SaveReal(udg_SOC_Hash,id,1,dist + inc)
    call SaveReal(udg_SOC_Hash,id,2,speed)
endfunction

function Stomp_of_Corruption_Knockback_Setup_2 takes nothing returns nothing
    local integer id=GetHandleId(GetEnumUnit())
    local real max=LoadReal(udg_SOC_Hash,id,0)
    local real dist=LoadReal(udg_SOC_Hash,id,1)
    if dist>=max-1.5 then
        call FlushChildHashtable(udg_SOC_Hash,id)
        call GroupRemoveUnit(LoadGroupHandle(udg_SOC_Hash,0,4),GetEnumUnit())
        call SaveInteger(udg_SOC_Hash,0,6,LoadInteger(udg_SOC_Hash,0,6)-1)
    else
        call Stomp_of_Corruption_Do_Knockback(id,GetEnumUnit(),LoadRectHandle(udg_SOC_Hash,0,5),max,dist,7.-(7./max*dist-LoadReal(udg_SOC_Hash,id,2)*0.1),LoadReal(udg_SOC_Hash,id,3),LoadReal(udg_SOC_Hash,id,4))
    endif
endfunction

function Stomp_of_Corruption_Knockback_Setup_1 takes nothing returns nothing
    call ForGroup(LoadGroupHandle(udg_SOC_Hash,0,4),function Stomp_of_Corruption_Knockback_Setup_2)
    if LoadInteger(udg_SOC_Hash,0,6)==0 then
        call PauseTimer(GetExpiredTimer())
    endif
endfunction

function Stomp_of_Corruption_Filter takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit())>0.
endfunction

function Stomp_of_Corruption_Do_Loop takes integer iterations,integer tot,group g,group kb,unit caster,unit dum,unit tar,player p,real damage,integer level returns nothing
    local integer id
    local integer i=32
    local real x
    local real y
    local real sx=GetUnitX(caster)
    local real sy=GetUnitY(caster)
    local real pos
    loop
        exitwhen (i==0)
        set i=i-1
        set x=sx+(100.*iterations*LoadReal(udg_SOC_Hash,1,i))
        set y=sy+(100.*iterations*LoadReal(udg_SOC_Hash,2,i))
        call GroupEnumUnitsInRange(g,x,y,150.,Filter(function Stomp_of_Corruption_Filter))
        call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl",x,y))
        loop
            set tar=FirstOfGroup(g)
            call GroupRemoveUnit(g,tar)
            exitwhen (tar==null)
            if (not IsUnitType(tar,UNIT_TYPE_STRUCTURE) and not IsUnitType(tar,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(tar,UNIT_TYPE_FLYING) and IsUnitEnemy(tar,p)) then
                call UnitDamageTarget(caster,tar,damage,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
                set id=GetHandleId(tar)
                call SaveReal(udg_SOC_Hash,id,0,100.*level)
                call SaveReal(udg_SOC_Hash,id,1,0.)
                call SaveReal(udg_SOC_Hash,id,2,0.)
                if not (IsUnitInGroup(tar,kb)) then
                    set dum=CreateUnit(p,'n60R',sx,sy,0.)
                    call UnitApplyTimedLife(dum,'BTLF',1.)
                    call UnitAddAbility(dum,'A63I')
                    call SetUnitAbilityLevel(dum,'A63I',level)
                    call IssueTargetOrder(dum,"innerfire",tar)
                    call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl",tar,"overhead"))
                    set pos=Atan2(GetUnitY(tar)-sy,GetUnitX(tar)-sx)
                    call SaveReal(udg_SOC_Hash,id,3,Cos(pos))
                    call SaveReal(udg_SOC_Hash,id,4,Sin(pos))
                    call GroupAddUnit(kb,tar)
                    if tot==0 then
                        call TimerStart(LoadTimerHandle(udg_SOC_Hash,0,3),0.02,true,function Stomp_of_Corruption_Knockback_Setup_1)
                    endif
                    set tot=tot+1
                endif
            endif
        endloop
    endloop
    call SaveInteger(udg_SOC_Hash,0,6,tot)
endfunction

function Stomp_of_Corruption_On_Loop takes nothing returns nothing
    local integer i=3
    local integer tot=LoadInteger(udg_SOC_Hash,0,0)
    local integer iterations
    loop
        set iterations=LoadInteger(udg_SOC_Hash,i,4)+1
        call Stomp_of_Corruption_Do_Loop(iterations,LoadInteger(udg_SOC_Hash,0,6),LoadGroupHandle(udg_SOC_Hash,0,2),LoadGroupHandle(udg_SOC_Hash,0,4),LoadUnitHandle(udg_SOC_Hash,i,0),null,null,LoadPlayerHandle(udg_SOC_Hash,i,1),LoadReal(udg_SOC_Hash,i,2),LoadInteger(udg_SOC_Hash,i,3))
        if (iterations>LoadInteger(udg_SOC_Hash,i,5)) then
            if (i!=tot) then
                call SaveUnitHandle   (udg_SOC_Hash,i,0,LoadUnitHandle   (udg_SOC_Hash,tot,0))
                call SavePlayerHandle (udg_SOC_Hash,i,1,LoadPlayerHandle (udg_SOC_Hash,tot,1))
                call SaveReal         (udg_SOC_Hash,i,2,LoadReal         (udg_SOC_Hash,tot,2))
                call SaveInteger      (udg_SOC_Hash,i,3,LoadInteger      (udg_SOC_Hash,tot,3))
                call SaveInteger      (udg_SOC_Hash,i,4,LoadInteger      (udg_SOC_Hash,tot,4))
                call SaveInteger      (udg_SOC_Hash,i,5,LoadInteger      (udg_SOC_Hash,tot,5))
                set i=i-1
            else
                call PauseTimer(GetExpiredTimer())
            endif
            call FlushChildHashtable(udg_SOC_Hash,tot)
            set tot=tot-1
        else
            call SaveInteger(udg_SOC_Hash,i,4,iterations)
        endif
        exitwhen (i>=tot)
        set i=i+1
    endloop
    call SaveInteger(udg_SOC_Hash,0,0,tot)
endfunction

function Stomp_of_Corruption_Actions takes unit u returns nothing
    local integer level=GetUnitAbilityLevel(u,'A63J')
    local integer tot=LoadInteger(udg_SOC_Hash,0,0) + 1
    call SaveUnitHandle   (udg_SOC_Hash,tot,0,u)
    call SavePlayerHandle (udg_SOC_Hash,tot,1,GetTriggerPlayer())
    call SaveReal         (udg_SOC_Hash,tot,2,I2R(GetHeroStr(u,false))*1.2)
    call SaveInteger      (udg_SOC_Hash,tot,3,level)
    call SaveInteger      (udg_SOC_Hash,tot,4,0)
    call SaveInteger      (udg_SOC_Hash,tot,5,level + 3)
    call SaveInteger(udg_SOC_Hash,0,0,tot)
    if (tot==3) then
        call TimerStart(LoadTimerHandle(udg_SOC_Hash,0,1),0.03,true,function Stomp_of_Corruption_On_Loop)
    endif
endfunction

function Stomp_of_Corruption_Conditions takes nothing returns nothing
    if GetSpellAbilityId()=='A63J' then
        call Stomp_of_Corruption_Actions(GetTriggerUnit())
    endif
endfunction

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

constant function USSOC takes nothing returns boolean
    return true
endfunction

function InitTrig_Stomp_of_Corruption takes nothing returns nothing
    local integer i=11
    local trigger t=CreateTrigger()
    local filterfunc FF=Filter(function USSOC)
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        exitwhen i==0
        set i=i-1
    endloop
    call DestroyBoolExpr(FF)
    call TriggerAddAction(t,function Stomp_of_Corruption_Conditions)
    set FF=null
    set udg_SOC_Hash=InitHashtable()
    call SaveInteger     (udg_SOC_Hash,0,0,2)
    call SaveTimerHandle (udg_SOC_Hash,0,1,CreateTimer())
    call SaveGroupHandle (udg_SOC_Hash,0,2,CreateGroup())
    call SaveTimerHandle (udg_SOC_Hash,0,3,CreateTimer())
    call SaveGroupHandle (udg_SOC_Hash,0,4,CreateGroup())
    call SaveRectHandle  (udg_SOC_Hash,0,5,Rect(-200.,-200.,200.,200.))
    call SaveInteger     (udg_SOC_Hash,0,6,0)
    loop
        call SaveReal    (udg_SOC_Hash,1,i,Cos((i+1)*11.25*bj_DEGTORAD))
        call SaveReal    (udg_SOC_Hash,2,i,Sin((i+1)*11.25*bj_DEGTORAD))
        set i =i+1
        exitwhen (i==32)
    endloop
endfunction

6) Napalm Shock
Problem: This skill work fine, except the dummy unit doesn't applied skill to the targeted unit.

JASS:
scope NapalmShock initializer init


//######################################################################################################
globals
//**********************
//* Config 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯    
//*
    public      constant integer    abilityID       = 'A62A'
//*
//*
//******************************************************************************************************    
endglobals


//######################################################################################################
public function init takes nothing returns nothing


endfunction


endscope




function Napalm_Shock_Conditions takes nothing returns boolean
    return GetSpellAbilityId()=='A62A'
endfunction

function Napalm_Shock_Actions takes nothing returns nothing
    local unit caster=GetTriggerUnit()
    local unit target=GetSpellTargetUnit()
    local unit lastcreated
    local real x1=GetUnitX(caster)
    local real y1=GetUnitY(caster)
    local real x2=GetUnitX(target)
    local real y2=GetUnitY(target)
    local real x3
    local real y3
    local real damage=40+(GetUnitAbilityLevel(caster,'A62A')*15)
    local integer index=1
    local real dx=x2-x1
    local real dy=y2-y1
    local real distance=SquareRoot(dx*dx+dy*dy)/100
    local real angle=bj_RADTODEG*Atan2(y2-y1,x2-x1)
    local real e_distance=0.00
    call UnitDamageTarget(caster,target,damage,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl",x1,y1))
    loop
        exitwhen index>R2I(distance)
        set x3=x1+(e_distance+100)*Cos(angle*bj_DEGTORAD)
        set y3=y1+(e_distance+100)*Sin(angle*bj_DEGTORAD)
        set lastcreated=CreateUnit(GetOwningPlayer(caster),'n61G',x3,y3,angle)
        set e_distance=e_distance+100
        call UnitApplyTimedLife(lastcreated,'BTLF',0.2)
        set index=index+1
    endloop
    set lastcreated=CreateUnit(GetOwningPlayer(caster),'n61E',x2,y2,angle)
    call UnitApplyTimedLife(lastcreated,'BTLF',3)
    call UnitAddAbility(lastcreated,'A629')
    call SetUnitAbilityLevel(lastcreated,'A629',GetUnitAbilityLevel(caster,'A62A'))
    call IssueTargetOrder(lastcreated,"shadowstrike",target)
    set caster=null
    set target=null
    set lastcreated=null
    set e_distance=0.00
endfunction

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

constant function ISNS takes nothing returns boolean
    return true
endfunction

function InitTrig_Napalm_Shock takes nothing returns nothing
    local trigger T=CreateTrigger()
    local integer TI=0
    local filterfunc FF=Filter(function ISNS)
    loop
        exitwhen (TI>=bj_MAX_PLAYER_SLOTS)
        call TriggerRegisterPlayerUnitEvent(T,Player(TI),EVENT_PLAYER_UNIT_SPELL_EFFECT,FF)
        set TI=TI+1
    endloop
    call DestroyBoolExpr(FF)
    call TriggerAddAction(T,function Napalm_Shock_Actions)
    call TriggerAddCondition(T,Condition(function Napalm_Shock_Conditions))
    set FF=null
    set T=null
endfunction

7) Frost Nova
Problem: The skills effect doesn't show properly and doesn't affect enemy units.

JASS:
scope FrostNova initializer init


native UnitAlive takes unit u returns boolean


//######################################################################################################
globals
//**************************
//* Config 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
    public      constant integer    abilityID           = 'A62S'
    public      constant integer    dummyID             = 'dumm'
//*
    public      constant integer    novaFrostID         = 'A62F'    
    public      constant integer    novaEnsnareID       = 'A627'   
    public      constant integer    novaFXAbilID        = 'A628'    
    public      constant integer    novaFXUnitID        = 'h612'   
//*
    public      constant string     novaFrostOrder      = "frostnova"
    public      constant string     novaEnsnareOrder    = "ensnare"
    public      constant string     novaFXAbilOrder     = "breathoffrost"
//*
    public      constant string     novaFXPath          = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
//*
    public      real array          areaRadius      
//*
//* Temp Data
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    private     group               TEMP__enum          = CreateGroup()
    private     boolexpr            TEMP__enumfilter    = null
    private     unit                TEMP__dummy         = null
//*
//*
//******************************************************************************************************    
endglobals


//######################################################################################################
private struct nova
    
    public          unit        caster      = null
    public          integer     level
    
    private static  thistype    TEMP__data
    
    
    private static method freezeAreaFilter takes nothing returns boolean
        local unit filt = GetFilterUnit( )
        local boolean result = IsUnitEnemy(filt, GetOwningPlayer(TEMP__data.caster)) and /*
                                    */ not IsUnitType(filt, UNIT_TYPE_STRUCTURE) and /*
                                    */ UnitAlive(filt)
        if result then
            call ShowUnit(TEMP__dummy, true)
            call SetUnitX(TEMP__dummy, GetUnitX(filt))
            call SetUnitY(TEMP__dummy, GetUnitY(filt))
        
            call SetUnitOwner(TEMP__dummy, GetOwningPlayer(TEMP__data.caster), false)
            call SetUnitAbilityLevel(TEMP__dummy, novaFrostID, TEMP__data.level+1)
            call SetUnitAbilityLevel(TEMP__dummy, novaEnsnareID, TEMP__data.level+1)
            call IssueTargetOrder(TEMP__dummy, novaFrostOrder, filt)
            call IssueTargetOrder(TEMP__dummy, novaEnsnareOrder, filt)
        
            call ShowUnit(TEMP__dummy, false)
        
        endif
        set filt = null
        return false
    
    endmethod
    //--------------------------------------------------------------------------------------------------    
    // freezeArea() ->  the freeze area method is used to enumerate nearby enemy targets that have been
    //                  validated and perform a set of operations to inflict the effects of the spell.
    //--------------------------------------------------------------------------------------------------
    method freezeArea takes nothing returns nothing
        local integer i
        local real x = GetUnitX(caster)
        local real y = GetUnitY(caster)
        local real x2
        local real y2
        local unit u = CreateUnit(Player(15), novaFXUnitID, x, y, 270)
            call SetUnitTimeScale(u, 0.25)
            call KillUnit(u)
            set u = null
    
        call SetUnitX(TEMP__dummy, x)
        call SetUnitY(TEMP__dummy, y)
        set i = 0
        loop
            exitwhen i == 20
            set x2 = x + 600*Cos(i*(bj_PI)/8)
            set y2 = y + 600*Sin(i*(bj_PI)/8)
            call IssuePointOrder(TEMP__dummy, novaFXAbilOrder, x2, y2)
            
            set i = i + 1
        endloop
        set thistype.TEMP__data = this
        call GroupEnumUnitsInRange(TEMP__enum, GetUnitX(caster), GetUnitY(caster), areaRadius[level], /*
                                    */ TEMP__enumfilter)
    endmethod
    
    private static method onInit takes nothing returns nothing
        set TEMP__enumfilter = Filter(function thistype.freezeAreaFilter)
        
    endmethod
    
endstruct


//######################################################################################################
public function typeidfilter takes nothing returns boolean
    return GetSpellAbilityId( )==abilityID

endfunction
public function runfunc takes nothing returns nothing
    local nova n = nova.create()
    set n.caster = GetTriggerUnit()
    set n.level  = GetUnitAbilityLevel(n.caster, abilityID)

    call n.freezeArea( )
    call n.destroy( )
        
endfunction


//######################################################################################################
public function init takes nothing returns nothing
    local trigger t=CreateSpellTrigger(null)
    
    call TriggerAddCondition(t, Filter(function typeidfilter))
    call TriggerAddAction(t, function runfunc)
    
    set t=null
    set TEMP__dummy = CreateUnit(Player(12), dummyID, 0, 0, 0)  // add the necessary abilities to the
        call UnitAddAbility(TEMP__dummy, novaFrostID)           // dummy on initialization; they are
        call UnitAddAbility(TEMP__dummy, novaEnsnareID)         // modified at run-time.
        call UnitAddAbility(TEMP__dummy, novaFXAbilID)
        call UnitRemoveAbility(TEMP__dummy, 'Amov')
        call ShowUnit(TEMP__dummy, false)    
        
    //--------------------------------------------------------------------------------------------------    
    set areaRadius[0]       = 550
    set areaRadius[1]       = 550
    set areaRadius[2]       = 550
    //--------------------------------------------------------------------------------------------------    
        
endfunction


endscope

8) Phoenix Spirit
Problem: This skills work fine. But for some unknown reason, it applied regeneration aura to enemy unit for a couple of seconds.

JASS:
library PhoenixSpirit initializer Init requires SpellIndexer
    
private struct dat
 
    static  constant    integer     MAIN_SPELL      = 'A62G'
    static  constant    integer     SUB_SPELL       = 'A62K'
    static  constant    integer     BIRDS_SPELL     = 'A62M'
    static  constant    integer     BIRD_ID         = 'h610'
    static  constant    integer     SUB_ID          = 'n61M'
    
    static integer      total       = 0
    static thistype     index       = 0
    static integer      mark        = 0
    static integer      runningTot  = 0
    
    static timer        loopTimer   = CreateTimer()
    static group        safeGroup   = CreateGroup()
    static group        birdGroup   = CreateGroup()
    static real         radius      = 0.
    static unit         trgUnit     = null
    
    static unit array       birds
    static boolean array    actBird
    
    player owner    = null
    integer level   = 0
    unit hero       = null
    unit bird       = null
 
    static method birdTravel takes nothing returns nothing
        local unit u= GetEnumUnit()
        local real x= GetUnitX(u)
        local real y= GetUnitY(u)
        if GetUnitCurrentOrder(u)!=OrderId("selfdestruct") then
            call IssuePointOrder(u,"selfdestruct",x,y)
            call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl",x,y))
        endif
        set u= null
    endmethod
 
    static method RandomFilt takes nothing returns boolean
        local unit u= GetFilterUnit()
        if GetRandomInt(0,bj_groupRandomConsidered)==0 and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and GetWidgetLife(u) > 0. and IsUnitEnemy(u,bj_groupEnumOwningPlayer) and not IsUnitInGroup(u, .safeGroup) then
            set bj_groupRandomCurrentPick= u
            set bj_groupRandomConsidered= bj_groupRandomConsidered +1
        endif
        set u= null
        return false
    endmethod
 
    static method onLoop takes nothing returns nothing
        local thistype this= .index
        local integer i= 0
        local integer j= 0
        local unit u
        local real array a
        if .radius >= 358. then
            set .radius = 0.
        else
            set .radius = .radius + 2.
        endif
        
        call ForGroup(.birdGroup,function thistype.birdTravel)
        loop
            if .hero != null then
                set a[0]= GetUnitX(.hero)
                set a[1]= GetUnitY(.hero)
                loop
                    set u= .birds[this *5 +i]
                    if .actBird[this *5 +i] then
                        set a[4]= 72. *i -.radius
                        set a[2]= a[0] +200. *Cos(a[4] *bj_DEGTORAD)
                        set a[3]= a[1] +200. *Sin(a[4] *bj_DEGTORAD)
                        call SetUnitX(u,a[2])
                        call SetUnitY(u,a[3])
                        call SetUnitFacing(u,bj_RADTODEG *Atan2(a[3] -a[1],a[2] -a[0]) -90.)
                        
                        set bj_groupEnumOwningPlayer= .owner
                        set bj_groupRandomConsidered= 0
                        call GroupEnumUnitsInRange(bj_lastCreatedGroup,a[2],a[3],400.,Filter(function thistype.RandomFilt))
                        
                        if bj_groupRandomConsidered>0 and GetUnitAbilityLevel(.hero, 'B619')>0 then
                            call GroupAddUnit(.safeGroup,bj_groupRandomCurrentPick)
                            set .actBird[this *5 +i]= false
                            call GroupAddUnit(.birdGroup,u)
                            call IssueTargetOrder(u,"selfdestruct",bj_groupRandomCurrentPick)
                            call SetUnitAbilityLevel(u,.BIRDS_SPELL,4)
                            call SetUnitAbilityLevel(u,.SUB_SPELL,.level)
                        endif
                        
                    else
                        set j = j +1
                    endif
                    exitwhen i==4
                    set i = i + 1
                endloop
                
                if j==5 then
                    call UnitRemoveAbility(.hero,'B619')
                    set .hero= null
                endif
                set i= 0
                set j= 0
            endif
            exitwhen this==1
            set this= this -1
        endloop
    endmethod
    
    static method onDeathEval takes nothing returns boolean
        local unit u
        local integer id= GetUnitTypeId(GetTriggerUnit())
        if id==.BIRD_ID or id==.SUB_ID then
            set u= GetTriggerUnit()
            
            if id==.BIRD_ID then
                set .runningTot= .runningTot +1
                if .runningTot==5 then
                    set .runningTot= 0
                    set .total= .total -1
                    if .total==0 then
                        call PauseTimer(.loopTimer)
                        set .index= 0
                    endif
                endif
                
                call GroupRemoveUnit(birdGroup,u)
            endif
            call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl",GetUnitX(u),GetUnitY(u)))
            call RemoveUnit(u)
            set u= null
        endif
        return false
    endmethod
 
    static method SecondSpellFilter takes nothing returns boolean
        local integer i= GetRandomInt(0,2)
        local unit u= GetFilterUnit()
        local unit d
        if GetWidgetLife(u)>0. and IsUnitEnemy(u,bj_groupEnumOwningPlayer) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl",u,"chest"))
            call UnitDamageTarget(.trgUnit,u,15. *bj_randDistCount,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            
            set d= CreateUnit(bj_groupEnumOwningPlayer,SUB_ID,GetUnitX(u),GetUnitY(u),270.)
            call UnitApplyTimedLife(d,'BTLF',GetRandomReal(0.8,1.2))
            
            if i==0 then
                call SetUnitAbilityLevel(d,'A62H',bj_groupEnumTypeId)
                call IssueTargetOrder(d,"curse",u)
            elseif i==1 then
                call SetUnitAbilityLevel(d,'A62L',bj_groupEnumTypeId)
                call IssueTargetOrder(d,"acidbomb",u)
            else
                call SetUnitAbilityLevel(d,'A62N',bj_groupEnumTypeId)
                call IssueTargetOrder(d,"cripple",u)
            endif
            set d= null
        endif
        return false
    endmethod
 
    static method subActions takes nothing returns nothing
        call GroupRemoveUnit(.safeGroup,GetSpellTargetUnit())
        set .trgUnit= GetTriggerUnit()
        set bj_groupEnumOwningPlayer= GetTriggerPlayer()
        set bj_groupEnumTypeId= GetUnitAbilityLevel(.trgUnit,.SUB_SPELL)
        set bj_randDistCount= GetUnitAbilityLevel(.trgUnit,'A002')
        call GroupEnumUnitsInRange(bj_lastCreatedGroup,GetUnitX(.trgUnit),GetUnitY(.trgUnit),200.,Filter(function thistype.SecondSpellFilter))
    endmethod
 
    static method Actions takes unit u returns nothing
        local integer i= 0
        local real x1= GetUnitX(u)
        local real y1= GetUnitY(u)
        local real x
        local real y
        if .total==0 then
            call TimerStart(.loopTimer,0.02,true,function thistype.onLoop)
        endif
        set .total= .total +1
        set .index= .index +1
        
        set .index.hero= u
        set .index.owner= GetTriggerPlayer()
        set .index.level= GetUnitAbilityLevel(u,.MAIN_SPELL)
        loop
            set x= x1 +200. *Cos(72. *i *bj_DEGTORAD)
            set y= y1 +200. *Sin(72. *i *bj_DEGTORAD)
            set .birds[.index *5 +i]= CreateUnit(.index.owner,.BIRD_ID,x,y,72. *i +90.)
            set .actBird[.index *5 +i]= true
            call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl",x,y))
            call SetUnitAbilityLevel(.birds[.index *5 +i],.BIRDS_SPELL,.index.level)
            
            exitwhen i==4
            set i= i +1
        endloop
    endmethod
 
    static method Conditions takes nothing returns boolean
        if GetSpellAbilityId() == .MAIN_SPELL then
            call .Actions(GetTriggerUnit())
        elseif GetSpellAbilityId() == .SUB_SPELL then
            call .subActions()
        endif
        return false
    endmethod
 
endstruct
//*
//* Main Initialization
//* ============================================================================
    private function Init takes nothing returns nothing
        local trigger t= CreateTrigger()
        call TriggerAddCondition(t,Condition(function dat.onDeathEval))
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH)
        call CreateSpellTrigger(function dat.Conditions)
    endfunction
//*
//*
//*
endlibrary

I even provide the map for you to test it, so you can know pretty much whats the problem all about.
 

Attachments

  • Test.rar
    15.4 MB · Views: 33

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
You might consider splitting those or use hidden tags - thats a wall of test ;p
I was loking on scripts 5&6

#5 About negative buff: make sure you are adding proper ability, use proper order and if dummy has enough mana to actually cast the spell (or just remove the cost). Also check if there is no casting time - your dummy lasts for 1. so if spell isn't instant it might have troubles with performing the order.

Possible improvements:

I would suggest using globals/private static or Unit Indexer instead of hashtables, especially timers shouldn't be saved into hashes - it's slows the loop a lot.
I think using unit group with ForGroup function would be much easier and faster instead of iterating through each index. FirstOfGroup is slow function too - ForGroup seems to be faster. However as I see you are doing:
JASS:
// filter 
function Stomp_of_Corruption_Filter takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit())>0.
endfunction

call GroupEnumUnitsInRange(g,x,y,150.,Filter(function Stomp_of_Corruption_Filter))
It's much better to use filter function to apply actions immidiately (so you can omit loop, firstofgroup and a lot more in Loop function:
JASS:
// filter 
function Stomp_of_Corruption_Filter takes nothing returns boolean
  // declare locals here
    if GetWidgetLife(GetFilterUnit())>0. then
        // actions here
    endif
    return false
endfunction

call GroupEnumUnitsInRange(g,x,y,150.,Filter(function Stomp_of_Corruption_Filter))
You forgot to null trigger handle in Init trigger. Also it's better to replace TriggerAddAction with TriggerAddCondition - conditions proves to be faster. The top part of your init should be somewhat:
JASS:
function InitTrig_Stomp_of_Corruption takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Stomp_of_Corruption_Conditions))
    set t=null
    set udg_SOC_Hash=InitHashtable()
 //going further.. Remove the USSOC function too.
Make use of 'abilityID' global instead of writing spell string id yourself.
Inlining UnitEvent doesn't seem to be worth it. BJ does the same thing and takes less memory - stick with BJ (after all thats one of those 'good' BJ).
JASS:
// Dont use square root if you don't have to, you are comparing constant values anywas.
// Jass math is slow enought, you dont need to hurt it even more ;d
local real dx=LoadReal(udg_SOC_Hash,0,7)-GetWidgetX(d)
local real dy=LoadReal(udg_SOC_Hash,0,8)-GetWidgetY(d)
if dx*dx+dy*dy <= 40000. then
    call KillDestructable(d)
endif
return false
endfunction

#6 About buff: read the note in 5th spell.

Improvements:
Don't inline UnitEvent (same as previous one). Use GetTriggerPlayer() instead of GetOwningPlayer(), although I recommend to use local player variable here since you are using loop. bj_lastCreatedUnit can help you get rid of local unit parameters. Reals/integers/booleans/strings does not have to be nulled.
Combine Condition and Action function. This spell is short enough to make me show you some of improvements:
>> Btw why didn't you use abilityID global in 'if' although I'm you declared it exactly for this purpose ;S
JASS:
function Napalm_Shock_Conditions takes nothing returns boolean
  // declare locals I would add:
    local player p = GetTriggerPlayer()
    if GetSpellAbilityId()==abilityID then
        // set locals
        // code
        call UnitDamageTarget(caster,target,damage,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL, null)
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl",x1,y1))
        loop
            exitwhen index>R2I(distance)
            set x3=x1+(e_distance+100)*Cos(angle*bj_DEGTORAD)
            set y3=y1+(e_distance+100)*Sin(angle*bj_DEGTORAD)
            set bj_lastCreatedUnit = CreateUnit(p,'n61G',x3,y3,angle)
            set e_distance=e_distance+100
            call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.2)
            set index=index+1
        endloop
        set bj_lastCreatedUnit = CreateUnit(p,'n61E',x2,y2,angle)
        call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',3)
        call UnitAddAbility(bj_lastCreatedUnit,'A629')
        call SetUnitAbilityLevel(bj_lastCreatedUnit,'A629',GetUnitAbilityLevel(caster,abilityID))
        call IssueTargetOrder(bj_lastCreatedUnit,"shadowstrike",target)
        set caster=null
        set target=null
        set p=null
    endif
    return false
endfunction

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

function InitTrig_Napalm_Shock takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Napalm_Shock_Conditions))
    set t=null
endfunction
There are probably ton of other things to take care of but unfortuantely I'm going off. Good luck.
 
Last edited:
Status
Not open for further replies.
Top