• 🏆 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] Magma Spirit Pack v 1.0c

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This Spell uses vJass so it required the Jass New Gen Pack. Get it here.

It was my submission for the Hero Contest #2
I Got the fourth Place of 26 with it

Includes a custom Attack system used by the Dark Side Summon
Magma Spirit
Contains 4 Spells


Version 1.00
-Official Release

Version 1.00b
-Fixed all return stuff to make it work with 1.24
but still the ultimate does not work, i have not clue why

Version 1.00c
- fixed that bug, thanks to bigappel90/hidden]

Nyctophobia
The Magma Spirit stored that much burning ire inside his soul that he can abuse his enemys fears to harm them with it. He releases some dark souls directly and some delayed which will trace the target and deal damage on impact.|r
JASS:
//////////////////////////////////////Globals with important values////////////////////////////////////////

scope Nyctophobia initializer Init

globals
    private constant integer Spell            = 'A000'  
        //The Spell Ability
        
    private constant integer DummyID          = 'h000'
        //Dummy Unit
        
    private constant integer DummyVertex      = 160
        //Transparency of the dummy
        
    private constant integer DummyDarkness    = 200
        // Darkness of the Dummy
        
    private constant real    MissileAim       = 0.30
        // The rate missiles aim
        
    private constant real    ZAdjustRate      = 55 
        //how fast the missiles height adjustes
           
    private constant real    ReleaseSpeed     = 10
        //The Speed each missile is released in a random direction
        
    private constant real    MaxVZ            = 28.00
    private constant real    MinVZ            = 10.00
        // The Speed in Z axe each missiles can be released at
        
    private constant real    MissileCollision = 40.00
        //How far the Missiles have to reach the target till they damage it
        
    private constant real    Pushback         = 1.75
        ////Knockback on hit (instant)
            
    private constant real    AnimSpeed        = 1.75
        //Animation Speed of the Dummy
        
    private constant real    TimerPeriod      = 0.0325
        //How fast the callbacl executes
        
    private constant string  AOEeffect        = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
        //Effect created if the unit is under the effect of Inner Blaze
        
        
///////////////////////////////////Globals that should not be changed////////////////////////////

    private real MaxX = 0
    private real MaxY = 0 
    private real MinX = 0
    private real MinY = 0
    private timer t = CreateTimer()
    private boolexpr filter = null
endglobals

//////////////////////////////////Editable Functions/////////////////////////////////////////&/

private constant function MissilesNumberDirectly takes integer level returns integer
    return 4 + 2 * level
    //Amount of missiles released instantly
endfunction

private constant function MissilesNumberDelayed takes integer level returns integer
    return 4 + 3 * level
    //Amount of missiles released after the cast in the MissilesDelay intervals
endfunction

private constant function MissilesDelay takes integer level returns real
    return 0.5
    //The time between each Delayed Missile
endfunction

private constant function MissilesDamage takes integer level returns integer
    return 6 + 2 * level
    //Damage each missiles does
endfunction

private function RunCondition takes nothing returns boolean
    return GetSpellAbilityId() == Spell
    //The condition if the spell is casted
endfunction

private function DamageTarget takes real damage, unit target, unit dealer returns nothing
        //Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
        //If you dont want it to splash, replace it, e.g. with the one below or whichever you want
    call IFDamage(damage,target,dealer,AOEeffect,"chest")
    //call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction

///////////////////////////////////////////Main Script//////////////////////////////////////////////
    
private constant function NullFilter takes nothing returns boolean
    return true
endfunction

private function Callback takes nothing returns nothing
    local integer i = 0
    local integer ii = 0
    
    //Looping through each Struct 
    loop
        exitwhen i >= Missiles.Index
        //If no missiles (including the delayed and maybe not created missiles) are left the structs gets destroyed
        if Missiles.Data[i].i == 0 then
            set Missiles.Data[i].ta = null  
            set Missiles.Data[i].ca = null  
            call Missiles.destroy(Missiles.Data[i])
            set Missiles.Index = Missiles.Index - 1
            set Missiles.Data[i] = Missiles.Data[Missiles.Index]
        //Else if the Target or Caster Dies the spell stops
        elseif GetWidgetLife(Missiles.Data[i].ta) <= 0.405 or GetWidgetLife(Missiles.Data[i].ca) <= 0.405 then
            set ii = 0
            loop
                exitwhen ii > Missiles.Data[i].i
                call KillUnit(Missiles.Data[i].m[ii])
                set Missiles.Data[i].m[ii] = null
                set ii = ii + 1
            endloop
            set Missiles.Data[i].i = 0
        else
            //Else just move/create the missiles
            call Missiles.Data[i].move()
            set i = i + 1
        endif
    endloop
    if Missiles.Index > 0 then
         call TimerStart(t, TimerPeriod, true, function Callback)
    endif        
endfunction

struct Missiles
    static integer Index = 0
    static Missiles array Data
    unit array m [23]   //Missile dummy
    unit ta  //Target
    unit ca     //Caster
    real array a [23]   //Creation angle
    real array vx [23]  //Current x movement
    real array vy [23]  //Current y movement
    real array vz [23]  //curren z Movement
    integer array d [23]    //delay of creation
    integer i = 0   //Number of Missile
    real damage
    static method create takes unit c, unit ta, integer level returns Missiles
        local integer i = 0
        local integer ii = 0
        local integer r = 0
        local Missiles data = Missiles.allocate()
        local real a = 0.00
        local real dp = 0.15 //delay per missile when releasing them directly
        local integer n = MissilesNumberDirectly(level)
        set Missiles.Data[Missiles.Index] = data
        
        //looping throught each missiles which will be created
        //The real creation of each missile will be in the Move method when the delay left 
        loop 
            exitwhen r == 2
            loop 
                exitwhen ii == n 
                set a = GetRandomReal(0,2*bj_PI)
                if r == 0 then
                    set data.d[i] = i
                else
                    set data.d[i] = R2I(((ii+1)*dp)/TimerPeriod)
                endif
                set data.i = data.i + 1
                set data.a[i] = a
                set data.vx[i] = ReleaseSpeed * Cos(a)
                set data.vy[i] = ReleaseSpeed * Sin(a)
                set data.vz[i] = GetRandomReal(MinVZ,MaxVZ)
                set ii = ii + 1
                set i = 1 + i
            endloop
            set dp = MissilesDelay(level)
            set n = MissilesNumberDelayed(level)
            set ii = 0
            set r = r + 1
        endloop
        
        set data.ca = c
        set data.ta = ta    
        set data.damage = MissilesDamage(level)
        
        if data.Index == 0 then
            call TimerStart(t, TimerPeriod, true, function Callback)
        endif
        set Missiles.Index = Missiles.Index + 1
        return data
    endmethod
    
    method move takes nothing returns nothing
    
    local integer i = 0
    local real x
    local real y
    local real d
    local real a
    loop 
        exitwhen i == this.i
        
            //Creation of the Dummy
            if this.d[i] == 0 and GetWidgetLife(this.ta) >= 0.405 then 
                set this.d[i] = -1
                set this.m[i] = CreateUnit(GetOwningPlayer(this.ca),DummyID,GetUnitX(this.ca),GetUnitY(this.ca),this.a[i]*180.0/bj_PI)    
                call SetUnitTimeScale(this.m[i],AnimSpeed)
                call SetUnitVertexColor(this.m[i],255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,DummyVertex)
            // Decreasing Left Executions till creation
            elseif this.d[i] > 0 and GetWidgetLife(this.ta) >= 0.405 then
                set this.d[i] = this.d[i] - 1
                
            // Move the dummy
            elseif this.d[i] < 0 and this.m[i] != null and GetWidgetLife(this.ta) >= 0.405 then
                set a = Atan2(GetUnitY(this.ta) - GetUnitY(this.m[i]), GetUnitX(this.ta) - GetUnitX(this.m[i]))
                set x = GetUnitX(this.ta) - GetUnitX(this.m[i])
                set y = GetUnitY(this.ta) - GetUnitY(this.m[i])
                if GetUnitY(this.m[i]) < MaxY and GetUnitY(this.m[i]) > MinY and GetUnitX(this.m[i]) < MaxX and GetUnitX(this.m[i]) > MinX then
                    set d = SquareRoot(x*x+y*y)
                    call SetUnitY(this.m[i],this.vy[i]+GetUnitY(this.m[i])+(Sin(a) * ( -8 + MissileAim * -2 *this.d[i])))
                    set this.vy[i] = 0.98 * this.vy[i]
                    call SetUnitX(this.m[i],this.vx[i]+GetUnitX(this.m[i])+(Cos(a) * ( -8 + MissileAim * -2 *this.d[i])))
                    set this.vx[i] = 0.98 * this.vx[i]
                    call SetUnitFlyHeight(this.m[i],GetUnitFlyHeight(this.m[i])+this.vz[i] - (ZAdjustRate/(d+100))*(GetUnitFlyHeight(this.m[i])-GetUnitFlyHeight(this.ta)) ,0)
                    set this.vz[i] = 0.99 * this.vz[i]
                    set x = GetUnitX(this.ta) - GetUnitX(this.m[i])
                    set y = GetUnitY(this.ta) - GetUnitY(this.m[i])
                    call SetUnitFacing(this.m[i], a* bj_RADTODEG )
                    set this.d[i] = this.d[i] - 1
                    if d <= MissileCollision then
                        call DamageTarget(this.damage,this.ta,this.ca)
                        call SetUnitX(this.ta, GetUnitX(this.ta) + Pushback * Cos(a))
                        call SetUnitY(this.ta, GetUnitY(this.ta) + Pushback * Sin(a))
                        call KillUnit(this.m[i])
                        set this.m[i] = null
                        set this.i = this.i - 1
                        set this.m[i] = this.m[this.i]
                        set this.a[i] = this.a[this.i]
                        set this.vx[i] = this.vx[this.i]
                        set this.vy[i] = this.vy[this.i]
                        set this.vz[i] = this.vz[this.i]
                        set this.d[i] = this.d[this.i]
                        set i = i - 1
                    endif

                else
                    call KillUnit(this.m[i])
                    set this.m[i] = null
                    set this.i = this.i - 1
                    set this.m[i] = this.m[this.i]
                    set this.a[i] = this.a[this.i]
                    set this.vx[i] = this.vx[this.i]
                    set this.vy[i] = this.vy[this.i]
                    set this.vz[i] = this.vz[this.i]
                    set this.d[i] = this.d[this.i]
                    set i = i - 1
                endif

            endif
        set i = i + 1
    endloop
    endmethod
        
endstruct

private function InitMissiles takes nothing returns nothing
    call Missiles.create(GetTriggerUnit(),GetSpellTargetUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction

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

private function Init takes nothing returns nothing
    local trigger tr = CreateTrigger()
    local integer index = 0
    
    //Setting the max rects due the lil knockback can eventuelly push the target outside 
    set MaxX = GetRectMaxX(bj_mapInitialPlayableArea) - 64
    set MaxY = GetRectMaxY(bj_mapInitialPlayableArea) - 64
    set MinX = GetRectMinX(bj_mapInitialPlayableArea) + 64
    set MinY = GetRectMinY(bj_mapInitialPlayableArea) + 64
    set filter = Filter(function NullFilter)
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( tr, Condition( function RunCondition ) )
    call TriggerAddAction( tr, function InitMissiles )

    call Preload(AOEeffect) //Effect Preload
endfunction

endscope

Combusting Brood
The Magma Spirit is able to form a Combusting Brood of his scorching energy which can Jump from target to target dealing damage each. If the Brood finds no new target it will release its rage on the current target dealing 15 bonus damage per jump left. Each time killing a unit in its fury a small Brood will spawn for a short duration which is stronger when killing the target with its remaining ire depending on the number of jumps left.
JASS:
//////////////////////////////////////Globals with important values////////////////////////////////////////

scope CombustingBrood initializer Init

globals
    private constant integer Spell         = 'A002'
        //The Main Combusting Brood Spell
        
    private constant integer DummyID       = 'h001'
        //The Missiles Dummy
        
    private constant integer DummyVertex   = 170
        // How Transparent the missile is 
        
    private constant integer DummyDarkness = 170
        // How dark the missiles is
        
    private constant integer VertexChange  = 10
        // At the start the missile has 100% alpha and fades in in this step per interval
        // To disable it set it to the DummyVertex or right 
        
    private constant real    DamageBonus   = 15. 
        // Bonus Damage for each remaining Jump if there are no valid targets left
        
    private constant real    DummyHeight   = 80
        //The base Height of the missile and the height it hits the target
        
    private constant real    JumpSpeed     = 12
        // Yeh, obv the missiles Speed
        
    private constant real    JumpHeight    = 360
        // Max Height reached in the jump
        
    private constant real    TimerPeriod   = 0.0325
        // Interval the timer executes
               
    private constant string  DamageEffect  = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        // Effect displayed when the missile hits an enemy        
        
    private constant string  AOEeffect     = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
        // Effect displayed when hitting a target under the effect of Inner Blaze
        
    private constant boolean HitThree      = true
        // This declares how many units a missile must hit to hit the same target again
        // True means the missile can hit the same target after hitting 2 others, if its cast at 2 units standing there it will end after hitting them both
        // False means the missile needs to hit one other unit till it can hit the same again, if there are 2 units it can jump from each to each again
    
    private integer array    SpawnUnit    [8]
        // The Unit IDs of the summons when killing enemys, Index must be the max. jumps a missile can do
 
 
///////////////////////////////////Globals that should not be changed////////////////////////////

    private timer t = CreateTimer()
    private group g = CreateGroup()
    private boolexpr filter = null
    private boolexpr ufilter = null
endglobals

///////////////////////////////////Important Editable Functions////////////////////////////////////

private function RunCondition takes nothing returns boolean
    return GetSpellAbilityId() == Spell
    //The condition if the spell is casted
endfunction

private function SpawnUnitInit takes nothing returns nothing
    //Sets the Spawntype for each Jump Left ( SpawnUnit[0] will also be the type when killing a unit during the jumps)
    set SpawnUnit[0] = 'n000' // Minor brood (0)
    set SpawnUnit[1] = 'nlv1' // Weak brood (1-2)
    set SpawnUnit[2] = 'nlv1' 
    set SpawnUnit[3] = 'nlv2' // Brood (3-5)
    set SpawnUnit[4] = 'nlv2' 
    set SpawnUnit[5] = 'nlv2' 
    set SpawnUnit[6] = 'nlv3' // Strong Brood (6-8)
    set SpawnUnit[7] = 'nlv3' 
    set SpawnUnit[8] = 'nlv3' 
endfunction

private function SpawnDuration takes integer jumps returns real
    return 7.0 + 1.5 * jumps
    // Duration of the Spawns per Jump Left (e.g. Minor brood will always have a 7 sec live due the 0 jumps left, Strong Brood have a duration from 16-19 seconds)
endfunction

private constant function MoveSpeedFaktor takes real x returns real
    return JumpSpeed * 0.01 * (0.45 * x * x - 1.1 * x + 1.2)
    // Defines the Speed of the Combusting Brood while its Movement (slower in the middle part and faster at the end, i you want to "reset" it change it to : JumpSpeed * 0.01
    // Else if you dont really know what it should be dont modify it
endfunction

private constant function JumpsPerLevel takes integer level returns integer 
    return 2 + 2 * level
    // How Many Jumps the Brood can do per level
endfunction

private function TargetUnitCondition takes unit a, unit b returns boolean
    // Additional Condition for Targeting a new target
    return IsPlayerEnemy(GetOwningPlayer(a),GetOwningPlayer(b))
endfunction

private constant function DamagePerLevel takes integer level returns integer 
    // Blablubb, Damager deal per level each jump  obv
    return 50 + 25 * level
endfunction

private constant function JumpRangePerLevel takes integer level returns real
    // Range per level the Brood can jump/ search a new target in
    return 220.0 + 40.0 * level
endfunction

private function UnitFilter takes nothing returns boolean
    //Conditions of Targeting a Unit
    return not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)) and not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)) and  IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and  (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction

private function DamageTarget takes real damage, unit target, unit dealer returns nothing
        //Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
        //If you dont want it to splash, replace it, e.g. with the one below or whichever you want
    call IFDamage(damage,target,dealer,AOEeffect,"chest")
    //call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction

///////////////////////////////////////////Main Script//////////////////////////////////////////////
    
private constant function NullFilter takes nothing returns boolean
    return true
endfunction

private function GetUnitDistance takes unit a, unit b returns real
    local real dx = GetUnitX(a) - GetUnitX(b)
    local real dy = GetUnitY(a) - GetUnitY(b)
    return SquareRoot(dx*dx+dy*dy)
endfunction

private function GetUnitsAngle takes unit a, unit b returns real
    return Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
endfunction

private function GetNewTarget takes Brood d returns unit
    local unit a
    call GroupEnumUnitsInRange(g, GetUnitX(d.b), GetUnitY(d.b),JumpRangePerLevel(d.level),ufilter)
    
    //looping through each near target and checking it
    loop
        set a = FirstOfGroup(g)
        exitwhen a == null
        
        //Checks if the units got already hit in the last 2 jumps
        if a != d.l1 and a != d.l2 and TargetUnitCondition(d.b,a) then
            call GroupClear(g)
            return a
        else
            call GroupRemoveUnit(g,a)
        endif
    endloop
    return a   
endfunction

private function Callback takes nothing returns nothing
    local integer i = 0
    
    //looping throught all structs
    loop
        exitwhen i >= Brood.Index
        //Destroying the struct
        if Brood.Data[i].Jleft == 0 then
            set Brood.Data[i].b = null
            set Brood.Data[i].ta = null
            set Brood.Data[i].amp = 0
            call Brood.destroy(Brood.Data[i])
            set Brood.Data[i] = Brood.Data[Brood.Index - 1]
            set Brood.Index = Brood.Index - 1
        else
        //Calliing the move method
            call Brood.Data[i].move()
            set i = i + 1
        endif
    endloop
    
    if Brood.Index > 0 then
         call TimerStart(t, TimerPeriod, true, function Callback)
    endif        
endfunction

struct Brood
    static integer Index = 0
    static Brood array Data
    unit c //Caster , deals the damage 
    unit b //Missile , Bombusting Brood
    unit ta //Target
    unit l1 //Unit hit 1 jump ago
    unit l2 // Unit hit 2 jumps ago
    integer Jleft //Amount of jumps left
    integer level //Level of the Spell
    integer Vertex // Current vertex of the missile
    real amp //current Amplitude while the jump
    
    static method create takes unit c, unit ta, integer level returns Brood
    
        local Brood data = Brood.allocate()
        local unit u = CreateUnit(GetOwningPlayer(c),DummyID,GetUnitX(c),GetUnitY(c),bj_RADTODEG * GetUnitsAngle(c,ta))
        set Brood.Data[Brood.Index] = data
        set data.c = c
        set data.b = u
        set data.ta = ta
        set data.l1 = ta
        set data.Jleft = JumpsPerLevel(level)
        set data.level = level
        set data.Vertex = 0
        call SetUnitVertexColor(u,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,0)
        
        if data.Index == 0 then
            call TimerStart(t, TimerPeriod, true, function Callback)
        endif
        set Brood.Index = Brood.Index + 1        
        return data
    endmethod
    
    method move takes nothing returns nothing
        local real step = MoveSpeedFaktor(this.amp) //Adjusting the speed depending on the function
        local real x = ( step) / (bj_PI - this.amp + 0.25 )
        local real b = GetUnitDistance(this.b,this.ta)
        local real d = 0.5 + x * (25 + b)
        local real a = GetUnitsAngle(this.b,this.ta)      
        local unit s
        local unit u
        local real damage = DamagePerLevel(this.level)
        
        if d >= b then
            set d = b //Avoid to speed up the target too fast if its very very near
        endif
        
        call SetUnitX(this.b,GetUnitX(this.b) + d * Cos(a))
        call SetUnitY(this.b,GetUnitY(this.b) + d * Sin(a))
        call SetUnitFacing(this.b,bj_RADTODEG * GetUnitsAngle(this.b,this.ta))
        set this.amp = this.amp + step
        call SetUnitFlyHeight(this.b,DummyHeight + JumpHeight * Sin(this.amp),0)
        
        //Adjust its vertex
        if this.Vertex <= DummyVertex then
            set this.Vertex = this.Vertex + VertexChange 
            call SetUnitVertexColor(this.b,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
        endif
        
        //Reached its target , Damage deal / Summons ect
        if this.amp >= bj_PI then
            set u = GetNewTarget(this)
            if u == null then
                set damage = damage + (this.Jleft -1) * DamageBonus
            endif
            if GetWidgetLife(this.ta) >= 0.405 then
                call DamageTarget(damage,this.ta,this.c)
                // To remove its conntection replace it with a normal damage deal
                
                if GetWidgetLife(u) >= 0.405 then
                    set u = GetNewTarget(this) 
                endif
                call DestroyEffect(AddSpecialEffect(DamageEffect,GetUnitX(this.ta),GetUnitY(this.ta)))
                if GetWidgetLife(this.ta) < 0.405 and u != null then
                    set s = CreateUnit(GetOwningPlayer(this.c),SpawnUnit[0],GetUnitX(this.ta),GetUnitY(this.ta),GetUnitFacing(this.ta))
                    call UnitApplyTimedLife(s, 'BTLF', SpawnDuration(0))
                    call SetUnitVertexColor(s,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
                elseif GetWidgetLife(this.ta) < 0.405 and u == null then
                    set s = CreateUnit(GetOwningPlayer(this.c),SpawnUnit[this.Jleft-1],GetUnitX(this.ta),GetUnitY(this.ta),GetUnitFacing(this.ta))
                    call UnitApplyTimedLife(s, 'BTLF', SpawnDuration((this.Jleft-1)) )
                    call SetUnitVertexColor(s,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
                endif
            endif
            
            if HitThree == true then
                set this.l2 = this.l1
            endif
            set this.l1 = u
            set this.ta = u
            if this.ta == null then
                call KillUnit(this.b)
                set this.Jleft = 0
            else
                set this.amp = 0
                set this.Jleft = this.Jleft - 1
                if this.Jleft == 0 then
                    call KillUnit(this.b)
                endif
            endif
            set s = null
            set u = null
        endif
    endmethod
            
endstruct


private function InitBrood takes nothing returns nothing
    call Brood.create(GetTriggerUnit(),GetSpellTargetUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction

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

private function Init takes nothing returns nothing
    local trigger tr = CreateTrigger()
    local integer index = 0
    call SpawnUnitInit()
    set filter = Filter(function NullFilter)
    set ufilter = Filter(function UnitFilter)
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( tr, Condition( function RunCondition ) )
    call TriggerAddAction( tr, function InitBrood )
    
    //Preloading effects
    call Preload(DamageEffect)
    call Preload(AOEeffect)
endfunction

endscope

Inner Blaze
The Magma Spirit developed in his years of restless wandering such a destructive mind that he even ignites his enemys anger with his presence. Enemys under this effect of Inner Blaze take damage per second and each spell damage dealt by the Magma Spirit will release an explosion splashing a part of that damage to nearby enemys. If an enemy dies in such an explosion its Inner Blaze releases eneries and transfers them to the Magma Spirit giving him a temporary damage bonus.
JASS:
//////////////////////////////////////Globals with important values////////////////////////////////////////


library InnerFire initializer Init

globals 

    private constant integer InnerFireSpell     = 'A001'
        //Inner Blaze Ability
        
    private constant integer PreloadDummy       = 'h002'
        //Dummy to preload the Damage Ability
        
    private constant integer InnerFireBuffSpell = 'A003'
        //Dummy Ability which gives the buff (the base ability (Immolation) has no buff)
        
    private constant integer BonusAbility       = 'A004'
        //The Bonus Ability When Killing a Target, in this case its damage bonus
        
    private constant integer InnerFireBuff      =  'B000'
        //The Buff the units under this Spell got
        
    private constant real    TimerPeriod        = 0.05
        //Timer Inverval used to change the lightnings vertex
        
    private constant real    LightningSpeed     = 0.20
        //The rate the lightning changes its vertex 
        
    private constant string  Lightning          = "AFOD"
        //The Lightning type , its Finger Of Death

     
///////////////////////////////////Globals that should not be changed////////////////////////////
      
    private group g = CreateGroup()
    private boolexpr filter = null
    private boolexpr unitfilter = null
    private timer t = CreateTimer()
endglobals

///////////////////////////////////Important Editable Functions////////////////////////////////////

function DamageBonus takes integer level returns integer
    return 1
    // The number of level steps for the damage ability
    // 1 means it will always be increased by 1 (ability gives 6 bonus per level) = 6 damage bonus on each level
endfunction

function IFAOEPart takes integer level returns real
    return 0.15 + 0.15 * level
    //The part of Spell damage which will be splashed , should be between 0 and 1
endfunction

function IFAOERadius takes integer level returns real
    return 60.0 + 20.0 * level
    // The Area of the Spell Damage Splash per level
endfunction

private function BonusDuration takes integer level returns real
    return 8.0 + 4.0 * level 
    //Duration the bonus damage stays when killing a target with a Spell
endfunction

private function SplashCondition takes unit a , unit b returns boolean
    // The condition if a unit is damaged
    return IsPlayerEnemy(GetOwningPlayer(a),GetOwningPlayer(b)) // The condition if a unit is damaged
endfunction

private function UnitFilter takes nothing returns boolean
    if not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)) and not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)) then
        return IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and  (GetWidgetLife(GetFilterUnit()) > 0.405)
    endif
    return false
    // The Condition a unit can be hit by a Damage Splash
endfunction

 //The condition if trigger should run (refers to the event : EVENT_PLAYER_HERO_SKILL)
private function RunCondition takes nothing returns boolean
    return GetLearnedSkill() == InnerFireSpell
endfunction


///////////////////////////////////////////Main Script//////////////////////////////////////////////

private constant function NullFilter takes nothing returns boolean
    return true
endfunction

private function Callback takes nothing returns nothing
    local integer i = 0
    loop
        //Looping through all structs
        exitwhen i >= Li.Index
        if Li.Data[i].left <= 0 then
            set Li.Data[i].ta = null
            call SetUnitAbilityLevel(Li.Data[i].h,BonusAbility, (GetUnitAbilityLevel(Li.Data[i].h,BonusAbility)-Li.Data[i].bonus))
            set Li.Data[i].h = null  
            call Li.destroy(Li.Data[i])
            set Li.Index = Li.Index - 1
            set Li.Data[i] = Li.Data[Li.Index]
        else
            call Li.Data[i].looping()
            set i = i + 1
        endif
    endloop
    if Li.Index > 0 then
         call TimerStart(t, TimerPeriod, false, function Callback)
    endif        
endfunction
    
struct Li // The lightning which appeas when a unit gets killed

    static integer Index = 0
    static Li array Data
    lightning li
    boolean inde = true //increase / decrease the lightnings alpha
    unit h //hero
    unit ta //Target
    real alpha = 0.00 //Current alpha
    integer bonus //Damage bonus a lightning gives
    real left //Duration of the damage bonus left
    
    static method create takes unit c, unit ta, integer level returns Li
    
        //Creating the lightning and adding damage bonus
        local Li data = Li.allocate()
        local real a = 0.00
        set data.ta = ta
        set data.h = c 
        set data.li = AddLightning(Lightning, true , GetUnitX(ta),  GetUnitY(ta), GetUnitX(c), GetUnitY(c))
        call SetLightningColor(data.li,1.00,1.00,1.00,0.00)
            //In case you dont want to create the lightning at full alpha thange the colour from 1.00 to any other below
        set data.left = BonusDuration(level) 
        set data.bonus = DamageBonus(level)
        set Li.Data[Li.Index] = data
        call SetUnitAbilityLevel(c,BonusAbility, GetUnitAbilityLevel(c,BonusAbility)+data.bonus)
        
        if data.Index == 0 then
            call TimerStart(t, TimerPeriod, false, function Callback)
        endif
        set data.Index = data.Index + 1
        return data
    endmethod
    
    method looping takes nothing returns nothing
    
        //looplooploop changes the lightnings alpha
        if this.li != null then
        
            if this.alpha >= 1.0 and this.inde == true then
                //Lightning reached its max visibility and its "fade" is declared
                set this.inde = false
                set this.alpha = 1.0
                
            elseif this.alpha <= 1.0 and this.inde == true then
                //Increase its visibility
                set this.alpha = this.alpha + LightningSpeed
                if this.alpha >= 1.00 then
                    set this.alpha = 1.00
                endif
            elseif this.alpha >= 0.0 and this.inde == false then
                //Decrease its visibility
                set this.alpha = this.alpha - LightningSpeed
            endif
            call SetLightningColor(this.li,1,1,1,this.alpha)
            call MoveLightning(this.li,true, GetUnitX(this.ta), GetUnitY(this.ta), GetUnitX(this.h), GetUnitY(this.h))
            if this.alpha <= 0.0 and this.inde == false then
                call DestroyLightning(this.li)
                set this.li = null
            endif
        endif
        set this.left = this.left - TimerPeriod
    endmethod 
    
endstruct

//Thie is the main damage function used by all other spells which use the splash of Inner Blaze
function IFDamage takes real damage, unit t, unit s , string e, string attach returns nothing
    local integer l = GetUnitAbilityLevel(s,InnerFireSpell)
    local lightning li
    local unit b 
    
    if GetUnitAbilityLevel(t,InnerFireBuff) == 0 or GetUnitAbilityLevel(s,InnerFireSpell) == 0 then
        //If the target does not have the buff and the damage dealer does not have the ability its a normal damage deal
        call UnitDamageTarget(s,t,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
    
    elseif GetUnitAbilityLevel(s,InnerFireSpell) != 0 and GetWidgetLife(t) >= 0.405 then
        //Else if the DamageDealer has the abiliy and the target is alive the damage is splaaashed
        call DestroyEffect(AddSpecialEffectTarget(e,t,attach))
        call UnitDamageTarget(s,t,damage*(1-IFAOEPart(l)),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)    
        
        if GetWidgetLife(t) <= 0.405 and GetUnitFlyHeight(t) == 0 then 
            // Init Bonus with teh lightning
            call Li.create(s,t,GetUnitAbilityLevel(s,InnerFireSpell))
        endif
        
        //Splashing damage with looping through all units near
        call GroupEnumUnitsInRange(g, GetUnitX(t), GetUnitY(t),IFAOERadius(l), unitfilter)
        loop
            set b = FirstOfGroup(g)
            exitwhen b==null
            call GroupRemoveUnit(g,b)
            //Checking conditions
            if SplashCondition(s,b) == true then
                //Damaging the target (also the main target, but it got less damage befor that it has 100% of it atall and not more)
                call UnitDamageTarget(s,b,damage*IFAOEPart(l),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)              
                if GetWidgetLife(b) <= 0.405 and GetUnitFlyHeight(b) == 0 then 
                    // Init Bonus and lightning
                    call Li.create(s,b,GetUnitAbilityLevel(s,InnerFireSpell))
                endif
            endif
        endloop
        call GroupClear(g)
        set b = null
        set li = null
    endif
endfunction

private function Actions takes nothing returns nothing
    local unit c = GetTriggerUnit()
    
    //Checking if the unit already got the dummy buff spell and increasing level /ading it
    if (GetUnitAbilityLevel(c,InnerFireBuffSpell) == 0) then
        call UnitAddAbility(c,BonusAbility)
        call UnitAddAbility(c,InnerFireBuffSpell)
    else
        call SetUnitAbilityLevel(c,InnerFireBuffSpell, GetUnitAbilityLevel(c,InnerFireSpell))
    endif
    
    set c = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local integer index = 0
    local boolexpr cond = Condition( function RunCondition )
    local trigger t = CreateTrigger(  )
    
    //Preloading the damag ability due its big amount of levels leads into a lag else
    local unit preload = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),PreloadDummy,0,0,0)
    call UnitAddAbility(preload,BonusAbility)
    call RemoveUnit(preload)
    
    set filter = Filter(function NullFilter)
    set unitfilter = Filter( function UnitFilter)
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_HERO_SKILL, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( t, cond )
    call TriggerAddAction( t, function Actions )
    set cond = null
    set preload = null
endfunction

endlibrary

Dark Side
The Magma Spirit releases its powerfull dusky side which will fight for him. This Dark Side has 600 healthpoints, divine armour and will bear all damage the Magma Spirit takes. It has the Cruelty ability and its attack will also cause the units ire to explde if they are under the effect of Inner Blaze.
JASS:
//////////////////////////////////////Globals with important values////////////////////////////////////////

scope DuskySoul initializer Init

globals
    private constant integer Spell            = 'A005'
        //Dark Soul Spell 
        
    private constant integer Summon           = 'n001'
        //Summoned unit (Dark Soul)
        
    private constant integer AttackDummy      = 'h002'
        //An Attack dummy to fake an attack at the target
        
    private constant integer AttackProjectile = 'h003'
        //Projectile of the Dark Soud
        
    private constant integer DummyVertex      = 170
        //Vertex the Summon has
        
    private constant integer DummyDarkness    = 255
        //How dark the summon is

    private constant real    TimerPeriod      = 0.0225
        //Timer Interval of the custom projectiles
        
    private constant real    TimerPeriodDsys  = 0.1    
        //Timer Interval for the Attack dummys locaation adjust (moves the dummy to the target to faake an attack)
        
    private constant real    CrueltyDamage    = 0.14
        //Percentage damage of hp missing 
        
    private constant real    HitRange         = 30
        //Range in which the projectiles hit an enemy
        
    private constant real    HitHeight        = 45
        //Height in which the projectiles will reach the target (flying heigh wwill be additional)

    private constant real    ProjectileSpeed  = 18
        //Speed the Projectiles got, also affaectey by the timer period
        
    private constant real    ProjectileStartX = -12
        // X Offset of the Projectile Creation (look at the model you used)
        
    private constant real    ProjectileStartY = 100
        // Y Offset of the Projectile Creation (look at the model you used) 
        
    private constant real    ProjectileStartZ = 130
        // Z Offset of the Projectile Creation (look at the model you used) 
        
    private constant real    ProjectileSway   = 0.15
        //Defines the amplitude of the projectiles movement (their distance to each other increaes while flying like a parabula
        // 0.15 means the amplitube will be 15% of the flying distance
        
    private constant real    GrowSpeed        = 7
        //Rate the summon will grow and shring (played when creating it)
        
    private constant real    DummySize        = 1.15
        //The normal size of the Summon (needed for the grow/shrink)
    
    private constant string  AttackEffect     = "Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl"
        //The effects displayed the the darksould hands when releasing a missile
        
    private constant string AOEeffect         = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"
        // AOE effect when hitting a target with Inner Blaze
    
    private constant string  StartAnimation   = "Spell"
        //The animation the dummy plays when being created
        
    private constant boolean KillDS           = false //Sets the action if the hero casts the ability while he already got one Dark soul summoned
        //True = Kiling the current Dark Sould when casting it again
        //False = Odering the caster to stop
        

///////////////////////////////////Globals that should not be changed////////////////////////////

    private trigger array tr  //Trigger for each hero casting and having the summoned unit to protect any damage
    private trigger array tr2 //Trigger to get the damage of each attack dummy and create missiles then
    private integer trin = 0  //Trigger index , how many Summoned units are ingame which use this custom system (equals number of dummies and current triggers Tr1 and Tr2)
    private unit array ds     //Dark soul (with trin index)
    private unit array ad     //Attack Dummy (with trin index)
    private unit array targ   //Target of each Dark sould (with trin index)
    private unit array hero   //Corrensponding hero (with trin index)
    private timer t2 = CreateTimer()
    private boolean cb = false // boolean if any callbacls should run
    private boolexpr filter  
    private timer t = CreateTimer()
endglobals

/////////////////////////////////////////Function modifications////////////////////////////////////////////////////////

private function RunCondition takes nothing returns boolean
    return GetSpellAbilityId() == Spell
    //The condition if the spell is casted
endfunction

private constant function Duration takes integer level returns real
    return 75.00
endfunction

private function DamageTarget takes real damage, unit target, unit dealer returns nothing
        //Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
        //If you dont want it to splash, replace it, e.g. with the one below or whichever you want
    call IFDamage(damage,target,dealer,AOEeffect,"chest")
    //call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction

function DisplayDamage takes real damage, unit u returns nothing
    //Displays the bonus damage of the Dark Soul
    local texttag tt = null
    if R2I(damage) != 0 then // does not display "+0" damage
        set tt = CreateTextTag()
        call SetTextTagText(tt, "|c00ff5656+"+I2S(R2I(damage))+"|r", 0.023)
            //The color is set here 
            
        //Any other things you may want to modify or not
        call SetTextTagPos(tt, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u))
        call SetTextTagColor(tt,255,255,255,255)
        call SetTextTagVisibility(tt, true)
        call SetTextTagFadepoint(tt,3.00)
        call SetTextTagPermanent(tt,false)
        call SetTextTagVelocity(tt,  0, 0.0355)
        call SetTextTagLifespan(tt, 4.00)
        set tt = null
    endif
endfunction

////////////////////////////////////////Main Script /////////////////////////////////////////////////////////////

private constant function NullFilter takes nothing returns boolean
    return true
endfunction

private function GetHeroIndex takes unit a returns integer
    // Gets the trin of the hero to find its correnspoding summon ect
    local integer i = 0 
    loop 
        exitwhen i == trin
        if a == hero[i] then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

private function GetTargIndex takes unit a returns integer
    // Gets the trin of a targeted unit to check if a unit s attacking it (cuz the attack dummy stay and else it would be still "attacked")
    local integer i = 0 
    loop 
        exitwhen i == trin
        if a == targ[i] then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

private function GetDSIndex takes unit a returns integer
    /// Gets the trin of a Dark sould to let the hero deal the damage (needs to be for Inner Blaze cuz he has the ability)
    local integer i = 0 
    loop 
        exitwhen i == trin
        if a == ds[i] then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

private function GetDummyIndex takes unit a returns integer
    // Gets the trin of a Dummy unit
    local integer i = 0 
    loop 
        exitwhen i == trin
        if a == ad[i] then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

private function GetUnitsAngle takes unit a, unit b returns real
    //angle between units, from a to b
    return Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
endfunction

function GetUnitDistance takes unit a, unit b returns real
    //Distance between 2 units
    return SquareRoot((GetUnitX(a) - GetUnitX(b)) * (GetUnitX(a) - GetUnitX(b)) + (GetUnitY(a) - GetUnitY(b)) * (GetUnitY(a) - GetUnitY(b)))
endfunction

///////////////////////////////////////CallBack//////////////////////////////////////////////

private function Callback takes nothing returns nothing
    local integer i = 0
    local real db
    
    //looping through each dark Sould (creation grow)
    loop
        exitwhen i >= DS.Index
        if DS.Data[i].inc == -1 and DS.Data[i].size == DummySize then
            set DS.Data[i].c = null  
            set DS.Data[i].Ds = null
            call DS.destroy(DS.Data[i])
            set DS.Index = DS.Index - 1
            set DS.Data[i] = DS.Data[DS.Index]
        else
            call DS.Data[i].grow()
            set i = i + 1
        endif
    endloop
    
    
    set i = 0
    //looping through each Projectile to move it
    loop
        exitwhen i >= Pr.Index
        if GetUnitDistance(Pr.Data[i].pr[0],Pr.Data[i].target) <= HitRange then
            //Here is defined if aa Projectile hits its target
            set db = (GetUnitState(Pr.Data[i].target,UNIT_STATE_MAX_LIFE)-GetWidgetLife(Pr.Data[i].target)) * CrueltyDamage
            call UnitDamageTarget(Pr.Data[i].ca,Pr.Data[i].target,0.001,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
            call DamageTarget(Pr.Data[i].dmg+db,Pr.Data[i].target,Pr.Data[i].ma)
            call DisplayDamage(db,Pr.Data[i].target)
            call KillUnit(Pr.Data[i].pr[0])
            call KillUnit(Pr.Data[i].pr[1])
            call KillUnit(Pr.Data[i].pr[2])
            set Pr.Data[i].pr[0] = null  
            set Pr.Data[i].pr[1] = null  
            set Pr.Data[i].pr[2] = null  
            set Pr.Data[i].ca = null  
            set Pr.Data[i].target = null  
            call Pr.destroy(Pr.Data[i])
            set Pr.Index = Pr.Index - 1
            set Pr.Data[i] = Pr.Data[Pr.Index]
        else
            call Pr.Data[i].move()
            set i = i + 1
        endif
    endloop
    
    if DS.Index > 0 or Pr.Index > 0 then
         call TimerStart(t, TimerPeriod, false, function Callback)
    else
        set cb = false
    endif        
endfunction

////////////////////////////////////////Summon Projectile////////////////////////////////////////////

struct Pr //Projectile
    static integer Index = 0
    static Pr array Data
    unit target //Missile dummy
    unit ca //"Caster" , means its the attacking summon
    unit ma //"Master" of the summon, the corrensponding hero 
    real maxd //Distance when creating the missile
    real dmg //dmage stored
    unit array pr [3] // the 3 Proectiles

   static method create takes unit ca, unit ta, real damage returns Pr
   
        local Pr data = Pr.allocate()
        local real a = GetUnitsAngle(ca,ta)
        local integer i = 0
        local real x = GetUnitX(ca) + (Cos(a) * ProjectileStartY) + (Sin(a) * ProjectileStartX)
        local real y = GetUnitY(ca) + (Cos(a) * ProjectileStartX) + (Sin(a) * ProjectileStartY)
        local integer index = GetDSIndex(ca)
        set Pr.Data[Pr.Index] = data
        set data.ma = hero[index]
        
        //Creating the 3 projectiles
        loop
            exitwhen i == 3
            set data.pr[i] = CreateUnit(GetOwningPlayer(ca),AttackProjectile,x,y,a)
            call SetUnitFlyHeight(data.pr[i],ProjectileStartZ,0)
            set i = i + 1
        endloop
        
        set data.maxd = GetUnitDistance(ta,data.pr[1]) * 1.05 // lil bit bigger cuz else its amplitude will not be 0 at the end
        set data.ca = ca
        set data.target = ta    
        set data.dmg = damage
        
        if cb == false then
            call TimerStart(t, TimerPeriod,false, function Callback)
            set cb = true
        endif
        
        set Pr.Index = Pr.Index + 1
        return data
    endmethod 
    
    method move takes nothing returns nothing
        local integer i = 0
        local real a = GetUnitsAngle(this.pr[1],this.target)
        local real d = (ProjectileSpeed+GetUnitDistance(this.target,this.pr[1]))/this.maxd
        local real offset = Sin(3.14159*d) * ProjectileSway * this.maxd
        
        //Moving all 3 Missiles (refers to pr[1]´s x and y because its not affected by the amplitide
        call SetUnitX(this.pr[1],GetUnitX(this.pr[1])+ProjectileSpeed*Cos(a))
        call SetUnitY(this.pr[1],GetUnitY(this.pr[1])+ProjectileSpeed*Sin(a))
        call SetUnitFlyHeight(this.pr[1],ProjectileStartZ + offset + (GetUnitFlyHeight(this.target)  - ProjectileStartZ + HitHeight) * (1-d) ,0)
        call SetUnitX(this.pr[0],GetUnitX(this.pr[1])+offset*Cos(a + (3.14159/2)) )
        call SetUnitY(this.pr[0],GetUnitY(this.pr[1])+offset*Sin(a + (3.14159/2)) )
        call SetUnitFlyHeight(this.pr[0],ProjectileStartZ + (GetUnitFlyHeight(this.target)  - ProjectileStartZ + HitHeight) * (1-d) ,0)
        call SetUnitX(this.pr[2],GetUnitX(this.pr[1])+offset*Cos(a - (3.14159/2)) )
        call SetUnitY(this.pr[2],GetUnitY(this.pr[1])+offset*Sin(a - (3.14159/2)) )
        call SetUnitFlyHeight(this.pr[2],ProjectileStartZ + (GetUnitFlyHeight(this.target)  - ProjectileStartZ + HitHeight) * (1-d) ,0)
    endmethod
    
    
endstruct

////////////////////////////////////////Damage System////////////////////////////////////////////////

function AdjustTarget takes nothing returns nothing
    //If a summon gets aa new target its set here any the dummy is moved
    local unit b = GetAttacker()
    local integer index = GetDSIndex(b)
    local unit a = GetTriggerUnit()
    local real angle = GetUnitsAngle(b,ad[index])
    if GetUnitTypeId(a) != AttackDummy and ad[index] != a then
        set targ[index] = a
        //Need to do this senseless crap here, else the Summons attack animation is not played properly (but i wonder why, it just gets the order to attack another unit)
        // I <3 Blizzard logic
        call SetUnitPosition(ad[index],GetUnitX(a),GetUnitY(a))
        call IssueImmediateOrder(b, "stop" ) 
        call PauseUnit(b,true)
        call PauseUnit(b,false)
        call IssueTargetOrder( b, "attack", ad[index])
    endif
    set b = null
    set a = null
endfunction

function UnitDies takes nothing returns nothing
    //If a unit dies which is "ttacked" by a summon it gets the stor order 8stopt attacking the neutral dummy
    //Then it searched a new target
    local unit u = GetTriggerUnit()
    local integer i = GetTargIndex(u)
    
    if i != -1 then
        call IssueImmediateOrder(ds[i], "stop" ) 
    endif
    
    set u = null
endfunction

function InitDeath takes nothing returns nothing
    local trigger d = CreateTrigger(  )
    local integer index = 0
    // Creates a trigger to check if a target dies 
        
    loop
        call TriggerRegisterPlayerUnitEvent(d, Player(index), EVENT_PLAYER_UNIT_DEATH , filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( d, function UnitDies )
endfunction

function MoveDummy takes nothing returns nothing
    local integer i = 0
    //periodicly movinge the dummy to the real targets location
    loop
        exitwhen i > trin
        call SetUnitX(ad[i],GetUnitX(targ[i]))
        call SetUnitY(ad[i],GetUnitY(targ[i]))
        set i = i + 1
    endloop
    
    if trin > 0 then
         call TimerStart(t2, TimerPeriodDsys, false, function MoveDummy)
    endif   
endfunction

function StartMissile takes nothing returns nothing
    //Event is when a dummy gets damage, then (due the attck of the sumon is instant) its damage is stored and projectiles are creted
    local integer index = GetDummyIndex(GetTriggerUnit())
    call DestroyEffect(AddSpecialEffectTarget(AttackEffect,GetEventDamageSource(),"hand, left"))
    call DestroyEffect(AddSpecialEffectTarget(AttackEffect,GetEventDamageSource(),"hand, right"))
    call Pr.create(GetEventDamageSource(),targ[index],GetEventDamage())
endfunction

function RightDamager takes nothing returns boolean
    //Condition that a summon damaged thee dummy, could also happen with AOE spells 
    return GetUnitTypeId(GetEventDamageSource()) == Summon
endfunction

function InitGetDamage takes unit dummy returns nothing
    //Initializing the Trigger when a Dummy takes damage
    set tr2[trin] = CreateTrigger()
    if trin == 0 then
        call TimerStart(t2, TimerPeriodDsys, true, function MoveDummy)
    endif 
    call TriggerRegisterUnitEvent( tr2[trin], dummy, EVENT_UNIT_DAMAGED )
    call TriggerAddAction( tr2[trin], function StartMissile )
    call TriggerAddCondition( tr2[trin], Condition( function RightDamager ) )
endfunction

function RightAttacker takes nothing returns boolean
    //Condition that its a Summon which targets the dummy
    return GetUnitTypeId(GetAttacker()) == Summon
endfunction

function InitDsys takes nothing returns nothing
    local integer index = 0
    local trigger tr = CreateTrigger(  ) 
    //Generally initializing the system with creating the trigger to get the point a dummy is attacked
    
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_ATTACKED, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( tr, function AdjustTarget )
    call TriggerAddCondition( tr, Condition( function RightAttacker ) )
endfunction

/////////////////////////////////////////////Damage Protection//////////////////////////////////

function ProtectDamage takes nothing returns nothing

    local unit c = GetTriggerUnit()
    local integer index = GetHeroIndex(c)
    //Protects damage from the casting hero , event is that it takes damage, 
    call SetWidgetLife(c,GetWidgetLife(c) + GetEventDamage())
    //Damages the summon instead
    call UnitDamageTarget(GetEventDamageSource(),ds[index],GetEventDamage(),true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
    set c = null
endfunction

function InitDamageProtect takes unit c, unit s returns nothing

    //Initializing the damage protection for the hero
    set tr[trin] = CreateTrigger()
    set ds[trin] = s
    set ad[trin] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackDummy,0,0,0)
    set hero[trin] = c
    
    call TriggerRegisterUnitEvent( tr[trin], c, EVENT_UNIT_DAMAGED )
    call TriggerAddAction( tr[trin], function ProtectDamage )
    call InitGetDamage(ad[trin])
    set trin = trin + 1
endfunction

/////////////////////////////////////////////////////////////////////////////////////////////////

function DestroyTr takes nothing returns nothing
    local integer index = GetDSIndex(GetTriggerUnit())
    
    //Destroying all triggers and the dummy which are not needed anymore when a Summon dies
    call RemoveUnit(ad[index])
    set ds[index] = null
    set hero[index] = null
    set ad[index] = null
    set targ[index] = null
    call DestroyTrigger(tr[index])
    set tr[index] = null
    call DestroyTrigger(tr2[index])
    set tr2[index] = null
    set trin = trin - 1
    set tr[index] = tr[trin]
    set ds[index] = ds[trin]
    set hero[index] = hero[trin]
    set ad[index] = ad[trin]
    set targ[index] = targ[trin]
    
endfunction

private function UnitDeath takes nothing returns boolean
    //Condition that it should be a summon which dies to destroy its correspoding dummy and trigger
    return GetUnitTypeId(GetTriggerUnit()) == Summon
endfunction

function DestroyTrInit takes nothing returns nothing
    local integer index = 0
    local trigger tr = CreateTrigger(  )
    //Initializes the destruction of the dummy and the trigger if a summons dies
    
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_DEATH, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( tr, function DestroyTr )
    call TriggerAddCondition( tr, Condition( function UnitDeath ) )
endfunction

struct DS  //Dark Sould struct
    static integer Index = 0
    static DS array Data
    unit c //Hero 
    unit Ds //Dark Soul
    integer level //level of the spell
    real size = DummySize //Current size
    integer inc = 1 //Defines if the unit is groing or shrinking 
    unit ad //Attackdummy
    
    static method create takes unit a, integer level returns DS
        //Creates the Dark soul
        local DS data = DS.allocate()
        set data.c = a
        set data.Ds = CreateUnit(GetOwningPlayer(a),Summon,GetUnitX(a),GetUnitY(a),GetUnitFacing(a))
        call InitDamageProtect(a,data.Ds)
        call SetUnitPathing(data.Ds,false)
        call PauseUnit(data.Ds,true)
        call SetUnitX(data.Ds,GetUnitX(a))
        call SetUnitY(data.Ds,GetUnitY(a))
        call SetUnitAnimation(data.Ds, StartAnimation)
        call SetUnitVertexColor(data.Ds,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,DummyVertex)
        set DS.Data[DS.Index] = data
        
        if cb == false then
            call TimerStart(t, TimerPeriod, true, function Callback)
            set cb = true
        endif
        
        set data.Index = data.Index + 1
        return data
    endmethod
    
    method grow takes nothing returns nothing
        local real vertex = DummyVertex - (75*(this.size + (GrowSpeed * this.inc * 0.01) - DummySize) )
        set this.size = this.size + (GrowSpeed * this.inc * 0.01)
        
        if vertex <= 0.0 then 
            //Vertex reached 0, setting it to increase again
            set this.inc = -1
            call SetUnitPathing(this.Ds,true)
            call SetUnitPosition(this.Ds,GetUnitX(this.c),GetUnitY(this.c))
            call SetUnitAnimation(this.Ds, StartAnimation)
        endif
        
        if this.inc == -1 and this.size <= DummySize then
            //Unit has its normal size again and animation is finished
            set this.size = DummySize 
            set vertex = DummyVertex
            call PauseUnit(this.Ds,false)
            call UnitApplyTimedLife(this.Ds,0,Duration(this.level))
        endif
        
        call SetUnitScale(this.Ds,this.size,this.size,this.size)
        call SetUnitVertexColor(this.Ds,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,R2I(vertex))
        
    endmethod
    
endstruct    
    
function Actions takes nothing returns nothing
    local integer check = GetHeroIndex(GetTriggerUnit())
    if check == -1 then
        call DS.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
    else
        if KillDS == true then
            call KillUnit(ds[check])
            call DS.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
        else
            call IssueImmediateOrder(GetTriggerUnit(), "stop" )  
        endif
       //A hero cannot have more than one Dark Soul a the same time
    endif
endfunction

private function Init takes nothing returns nothing
    local trigger tr = CreateTrigger()
    local integer index = 0
    
    //Preloading the Units
    local unit preload =  CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackProjectile,0,0,0)
    local unit preload2 =  CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackDummy,0,0,0)
    call KillUnit(preload)
    call KillUnit(preload2)
    //Preloading Effects
    call Preload(AttackEffect)
    call Preload(AOEeffect)
    
    set filter = Filter(function NullFilter)
    //Initializing the 3 systems
    call DestroyTrInit() //General thing if a Summon dies / removing dummy + destroying other triggers
    call InitDeath() //General thing if a target dies
    call InitDsys() //General Damage System with custom projectiles
    
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddCondition( tr, Condition( function RunCondition ) )
    call TriggerAddAction( tr, function Actions )
    set preload = null
endfunction

endscope

Thanks alot to bigapple90 for helping fixing a bug which appeared with 1.24



Keywords:
Magma, Lord, Spirit, Fire, Flame, Hero, Spell, Pack, Contest, Combusting, Brood, Summon, Dusky, Dark, Soul, Site, Side, Nyctophobia, Inner, Blaze, Cru
Contents

Magma Spirit (Map)

Reviews
4 November 2015 Bribe: Rejecting due to the status of this resource being "needs fix" for years. 22:04, 2nd Jan 2010 TriggerHappy: All Spells I suggest using a Timer attachment system instead of using O(n) complexity. No need to inline...

Moderator

M

Moderator

4 November 2015
Bribe: Rejecting due to the status of this resource being "needs fix" for years.

22:04, 2nd Jan 2010
TriggerHappy:

All Spells
  • I suggest using a Timer attachment system instead of using O(n) complexity.
  • No need to inline the event.
  • Make your structs private.
  • You should be using UnitAlive instead of GetWidgetLife.
  • NullFilter is not needed anymore.

Nyctophobia
  • InitMissiles could be removed by just using Missles.create directly.

Combusting Brood
  • FirstOfGroup loops are slow.

Dark Soul
  • You never null preload2.
 
Level 15
Joined
Jan 31, 2007
Messages
502
Very cool Rep+++ can u add some of your spells to a map possbly?

Is that a question if you can use it or are you asking if I can implent it in your map?
Shouldnt be hard to add this to a map

laggy but nice (i think it happens when lots of units start to attack but not sure)

edit: ok tested again at it seems to be caused by the ankh (lag occures after hero respawns)


badnpq2eg3zz1s49m.jpg


Hmm.. y - i once got lags too, but i wasnt able to find out what caused them so i thought it would have been my vire scanner or whatever
because in 1000 tests in never had lags anymore
So thank you, its really the Ankh
But atm im really clueless why it should start lagging as hell if a unit rewieves per ankh ~.~
Next days i got time to test and hopefully fix that

Your coding style, i just love it !

And the creativity is awesome, but i don't think this should be in the spell section, maybe it's against the rules ?

Anyway +rep and keep it on coming ^^

Thanks, but why should it be against the rules? You mean the contest?
The contest is over and they are uploaded , or lets say they should be
cuz atm im disqualified because one mod said my submission would have been 1h summer time to late and deleted it


Edit, What the heck?! Even if I disable even single trigger of mine without using any Spells ingame it starts lagging as hell
i made some excluding and it seems to be the Inner Blaze Ability (not the script) but ive got no idea that the problem with that simple edit of Immolation
if the hero skilled it and dies it will lag as hell if get gets attacked after revival

Edit, it was that i forgot to add a duration for level 2 and 3 , it was "0" due it was a non hero skill before
not its fixed
but im still kinda confused why this is something which will bug the game
 
Last edited:
Level 25
Joined
Jun 5, 2008
Messages
2,572
Found a bug:
Upon multiple casts i got the dark side unit paused doing nothing and unable to move.
Try adding several more firelords to see for yourself.
I don't know what is causing this bug but i suggest you to check your code.
EDIT:
Tested it again and this time it didn't bug, strange Oo.
Still can't you disable those debug messages, they are annoying :p
Also one of my favorite submisions for the contest :D
 
Level 17
Joined
Sep 8, 2007
Messages
994
Spells must be fully multiinstanceable, and done so competently (IE no "indexing systems" which just populate a massive array and count upwards until they hit a maximum, then restarting from the first possible value regardless of whether the position is taken).

I'm afraid you won't get this spell approved. Obviously you make use of indexing what is against the new rules. That's a pity >.< these spells are so f**king great! :( 5/5 and rep from me
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
So you uploaded this here eh? =D I checked it in the submissions, and I must say good job both script-wise and creativity-wise!

EDIT:
when I tested I remember no lag, can't test that now since I have no net at home. And disqualified!? That's just BS!! I mean, it's just one hourrr!
 
Level 15
Joined
Jan 31, 2007
Messages
502
Found a bug:
Upon multiple casts i got the dark side unit paused doing nothing and unable to move.
Try adding several more firelords to see for yourself.
I don't know what is causing this bug but i suggest you to check your code.
EDIT:
Tested it again and this time it didn't bug, strange Oo.
Still can't you disable those debug messages, they are annoying :p
Also one of my favorite submisions for the contest :D

Dunno, what could cause this ;/
it muste be the blizzard bug
sometimes PauseUnit(u,false) just doesnt work, ask blizzard why ~.~


I'm afraid you won't get this spell approved. Obviously you make use of indexing what is against the new rules. That's a pity >.< these spells are so f**king great! :( 5/5 and rep from me

nah, "massive array" ^^ its an array for each player, and because every player cannot have more than one dark soul the max index will be 12... but thats really rare... hmm.. right, why didnt i use the player number ? anyway... :/

So you uploaded this here eh? =D I checked it in the submissions, and I must say good job both script-wise and creativity-wise!

EDIT:
when I tested I remember no lag, can't test that now since I have no net at home. And disqualified!? That's just BS!! I mean, it's just one hourrr!

I hope im in too
it was just the difference between the standart time i looked at and the summer timer (GMT + 1:00)
with the standart time i would have been exactly in time , how i planned that

contacted admines, but didnt really get a decision yet
but Ghan_04 recommended to count my submission
 
Level 15
Joined
Jul 19, 2007
Messages
618
-JohnNny said:
lets say they should be
cuz atm im disqualified because one mod said my submission would have been 1h summer time to late and deleted it

omg i am so sry for u... one 1h? lol how can that even be counted i mean it looks logical that its coz of different GMT but i guess some people dont care about that :/


now about spells!

i can see a lot of work and quite creative from you through i cant test spells for some odd reason... cant find return bug so it must be 1.24 beta bug but anyway back to topic!

when i saw coding i was like oO is that -JohnNny? its like a different coder lol.
i mean when did you get so good at coding? spells are fully editable (my fav thing :D)
seems MUI and Leakless (you learned abiout filters :D) i remember that in ur older spells you where using AnyUnitEventBJ

but most important thing is that your coding stile changed to be more OOP you are more better now using structs and i was really impressed when i saw that, since people usually dont chage there way of coding stile but you did and it turned quite well afterall.

last of all you added more comments i like that a lot!

what i detected that could be improved is: some of functions/structs are not private... well they should be private or public, some spells are in scops and some in librarys.. i suggest you to use only one of them! i saw that you are calling some functions from other spells in current ones and thats why u used library but i suggest you to write a small library for urself rather then making that in spell coz some people might just want one of spells ... and maybe some timers could be dynamic but thats not needed. and btw what could be good if you make librarys is that you need only once to code nullfilter rather then declaring it in every of spells. i saw you using some indexing system for object storage and thats exactly method i was using while learning jass! i still like it today coz it was always very important to flush indexes so loops get decreased and system becames faster... while today we just use bugreturn and flushing is actualy not needed.. its not needed to null integers but in that system it is very important and i just simply like it coz it reminds me of time i was learning jass :D

it was a quick look and i am really sry that i cant help you more.. u know i would tell you why this spells could cause such a massive lagg (3.1 fps) hmm but cant start it :S

while looking at coding i think i know what could cause it!
it can be structs which call methodes before they are declared (coz that creates extra triggers + functions and such) if you still remember methods are functions and functions cant be called before they are declared while methods can which means they are triggers. i was once having such a problem it was bug with jasshelper compiling exactly with this triggers something was compiled wrong and mass lag occured but i did not found why that happend! and it did never happen to me again from that time... so i cant tell do you have same problem but i just told you what i know :S

and ill tell you what all generates triggers/conditions/actions+prototype functions!

JASS:
struct some
method B takes nothing returns nothing
    call this.A() // a is not jet declared so its trigger
endmethod

method A takes nothing returns nothing
endmethod

method onDestroy takes nothing returns nothing
// onDestroy is always trigger with condition! its because this method is special
// method it is called when objects id is geting cleared from memory via .destroy() method
endmethod

endstruct

function A takes nothing returns nothing
endfunction

function B takes nothing returns nothing
   call A.evaluate() // generates an new trigger
   call A.execute() // same
endfunction


interface my_inter

   // generates trigger depending on number of methods
   method MyMethod takes nothing returns nothing defaults nothing
   method MyReal takes nothing returns real defaults 3.14159

endinterface

function interface math takes real x returns real

function Abs takes real a returns real
//code...
endfunction

function mathTest takes nothing returns nothing
     local math abs = Abs // generates trigger
endfunction


all of this triggers require an prototype functions (there own conditions/actions) and such..

well since this algorithms might get sometimes complex the stuff can bug... like maybe calling some null trigger or smth..

i hope this all helped you out a bit.

about spells from code it seems quite fun and since i know you started with new way of coding stile you are quite good and i am sure you will become even better :D spell ideas are quite awesome, so 4.5/5 which we could round to 5/5 ;)

Regards and best of luck on finding the bug!
~Dark Dragon
 
Level 15
Joined
Jan 31, 2007
Messages
502
when i saw coding i was like oO is that -JohnNny? its like a different coder lol.
i mean when did you get so good at coding? spells are fully editable (my fav thing :D)
seems MUI and Leakless (you learned abiout filters :D) i remember that in ur older spells you where using AnyUnitEventBJ

eh, is that a compliment or should that mean my coding befor sucked very hard? x]
but i think it is not really different from my last spells, e.g. my Mind Burst and Life Distortion are quite similar build up
Dont really know whats different here, expect that i used many events and dynamic triggers for the Attack "System"


Btw, i guess i fixed that bug already, it seemed to be the Immolation Ability from Inner Blaze where i forgot to add a duration when changing it to a hero Ability (was still "0" for level 2 and 3)
that lagged the crap out of my computer after the hero respawned with the ankh
but i dont really know what this had to do with the ankh or why it should lag ~.~

Y, i was going to rework this Inner Blaze Library and i was going to add BooleUtils for that stupid Nullfilter which annoyed me really hard here

thanks alot for your time and this review
 
Level 15
Joined
Jul 19, 2007
Messages
618
-JohnNny said:
should that mean my coding befor sucked very hard? x]

no it did not suck but OOP way of coding is more readable, easy modified and easier to make complex systems / (objects)

i dont really know what this had to do with the ankh or why it should lag ~.~

well i would like to help but it seems that your spells are not compatible with 1.24 and still i cant find that return bug so it must be smth else ~.~ ankh you say? well maybe try using hero ability from TC! if you did not already :]

i was going to add BooleUtils

well you can but i dont think its neccessary since it has false filter too, but you need only an true one! well what i thought is that you simply only once code your own NullFilter in your library and then use it in all of your spells.

thanks alot for your time and this review

well since i could have not help you with lag i was not to much usefull but still i said stuff i know x]

Greets!
~Dark Dragon
 
Level 15
Joined
Jan 31, 2007
Messages
502
It seems to work again now, would be nice to take off the Needs Fix prefix due its not bugged
updated the code i posted in the description
fixed a bug Eccho mention where i accidentely destoyed a wrong Struct

updated and got a new screenshot but it doest want to show up
thats strange because if you maximize it there is the one i want ~.~
 


Concept (30):

Idea
9 /10
Complexity
8 /10
Style
10 /10
Comment:
Yay, another pack by jonny!
Very nice ideas, very nice style.
Nothing to complain at all.
Effects (10):

All:
8 /10
Comment:
The effects fit and do work very well, however,
there is something I miss here.
Scripting (30):

Speach:
8 /10
Leakage:
10 /10
Effective Coding:
9 /10
Comment:
The code was very nice, I guess only minor things
which would be done to make it perfect. Very very well
made. Also the speach could be a bit more user friendly.
(For example the loops are described, but the actions not.
I would suggest make a block comment and say when you do another action, like:
JASS:
// set the new coordinates
// calculate the new position
Else its very fine.
Score: 62/70
Final Score: 4,42 / 5

Very nicely made spells. Thanks for making this :p . [4/5] vote

[X] +Rep
[ ] Report
(Blank box means no action)

 
Level 15
Joined
Jul 19, 2007
Messages
618
k i tried really hard to find out why does your spell not work ~via 1.24! i did not found out since well its an most likelly blizzard bug. however it is really quite hard to find it coz well there is really a lot of lines and only "i guess" a single one makes it to crash (not start).

code itself is not a problem, what could be is maybe some if/then/else new rule...
i as well found that you forgot to null some variables so they cause leaks, but that would not cause it not to start the game...

as well it would be more easy to debug the spell if you made it more OOP and used macros insted of repeating code over and over again!

as well i suggest you to use some damage detection system coz coding it directly in spell can cause event leaks, but most of all its quite longer and harder to debug...

this are only suggestions and well i really wanted to help but i could not find now why does it not work... if i found it out ill tell u.

Greets!
~Dark Dragon
 
Level 15
Joined
Jan 31, 2007
Messages
502
k i tried really hard to find out why does your spell not work ~via 1.24! i did not found out since well its an most likelly blizzard bug. however it is really quite hard to find it coz well there is really a lot of lines and only "i guess" a single one makes it to crash (not start).

code itself is not a problem, what could be is maybe some if/then/else new rule...
i as well found that you forgot to null some variables so they cause leaks, but that would not cause it not to start the game...

as well it would be more easy to debug the spell if you made it more OOP and used macros insted of repeating code over and over again!

as well i suggest you to use some damage detection system coz coding it directly in spell can cause event leaks, but most of all its quite longer and harder to debug...

this are only suggestions and well i really wanted to help but i could not find now why does it not work... if i found it out ill tell u.

Greets!
~Dark Dragon

thanks alot

A new if/the/else rule? didnt hear about that yet o_O

eh, yeh sometimes i forget to null variable when i create longer scripts
and i loled about YOU telling me 700 lines are long ! x)

I guess macros yould have been really usefull here but i have no real idea about it and i was too lazy till now to read anything about them ^^

and about the event leaks i think its not that bad due theres just one new event in a dynamic trigger per cast which will get destroyed afterwards
 
Level 15
Joined
Jul 19, 2007
Messages
618
thanks alot

A new if/the/else rule? didnt hear about that yet o_O

eh, yeh sometimes i forget to null variable when i create longer scripts
and i loled about YOU telling me 700 lines are long ! x)

I guess macros yould have been really usefull here but i have no real idea about it and i was too lazy till now to read anything about them ^^

and about the event leaks i think its not that bad due theres just one new event in a dynamic trigger per cast which will get destroyed afterwards

well yeah i dont remember where i saw that if then else rule but it was somewhere in 1.24 patch thread i guess.

well no its fine 700 lines but well i thought that it could be easy reduced for a little :)

and yeah macros would reduce it a lot and btw macros are not like functions or anything they are instant which means you have nothing at all to lose :)

yeah i did not check it perfectly and some small event leaks are not problem at all! i as well saw u doing dynamic triggers work but well what i thought was triying maybe to have some simple function like TriggerRegisterAnyUnitDamaged insted of whole the time loading/deleting triggers! it would be better and less lines... sry i could not found the reason why it does not want to compile but i quickly looked at it and well i think it can be optimized... to tell u the truth i have a feeling that this spell is something like my old Max Bash! it was well coded but overcomplicated for no reason! thats what Eccho told me... laiter i really checked it more accurately and i thought the same! this one is like that as well it is good coded but it can be optimized (reducing lines and objects...)

overall its not spells problem for sure its just some blizzard bug! i hope it gets fixed in 1.24b.

if i find out why it does not load by any chances ill fix it for u!

well until then greets!
~Dark Dragon
 
Level 19
Joined
Aug 2, 2008
Messages
442
JASS:
private function InitDsys takes nothing returns nothing
    local integer index = 0
    local trigger tr = CreateTrigger() 
    //Generally initializing the system with creating the trigger to get the point a dummy is attacked
   
    loop
        call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_ATTACKED, filter)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( tr, function AdjustTarget )
    call TriggerAddCondition( tr, Condition( function RightAttacker ) )
    
endfunction
When i commented out these lines (except for private function InitDsys takes nothing returns nothing, and endfunction) the map started.


Also, if i leave the above code as it is, and uncomment these lines below; the map starts and if the dark soul tries to attack i receive a fatal error:
JASS:
function InitDamageProtect takes unit c, unit s returns nothing

    //Initializing the damage protection for the hero
    //set tr[trin] = CreateTrigger() **COMMENTED LINE**
    set ds[trin] = s
    set ad[trin] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackDummy,0,0,0)
    set hero[trin] = c
    
    //call TriggerRegisterUnitEvent( tr[trin], c, EVENT_UNIT_DAMAGED )**COMMENTED LINE**
    //call TriggerAddAction( tr[trin], function ProtectDamage )**COMMENTED LINE**
    call InitGetDamage(ad[trin])
    set trin = trin + 1
endfunction

/////////////////////////////////////////////////////////////////////////////////////////////////

function DestroyTr takes nothing returns nothing
    local integer index = GetDSIndex(GetTriggerUnit())
    
    //Destroying all triggers and the dummy which are not needed anymore when a Summon dies
    call RemoveUnit(ad[index])
    set ds[index] = null
    set hero[index] = null
    set ad[index] = null
    set targ[index] = null
   // call DestroyTrigger(tr[index])**COMMENTED LINE**
   // set tr[index] = null**COMMENTED LINE**
    call DestroyTrigger(tr2[index])
    set tr2[index] = null
    set trin = trin - 1
   // set tr[index] = tr[trin]**COMMENTED LINE**
    set ds[index] = ds[trin]
    set hero[index] = hero[trin]
    set ad[index] = ad[trin]
    set targ[index] = targ[trin]
    
endfunction
 
Level 15
Joined
Jan 31, 2007
Messages
502
Im really confused...
in your first example.. i tried it and it really started !

but if i uncomment e.g. "local integer index = 0" it stops working
so wtf?

edit: what the heck?
if i uncomment the "local integer index = 0" it stops working
but if i let it as a comment and add exactly "local integer index = 0" one line below it works

edit : OMG
i fixed it :/
thanks alot !!
It bugged because i used a global trigger array tr and a local trigger with the same name
after renaming tr into something else it works fine again
i thought this would not give any problems.. o_O tr and tr[ ]
also ive got no idea why this does appear with 1.24 and worked fine before
anyway... thanks alot- works again now :)
 
Level 15
Joined
Jul 19, 2007
Messages
618
Im really confused...
in your first example.. i tried it and it really started !

but if i uncomment e.g. "local integer index = 0" it stops working
so wtf?

edit: what the heck?
if i uncomment the "local integer index = 0" it stops working
but if i let it as a comment and add exactly "local integer index = 0" one line below it works

edit : OMG
i fixed it :/
thanks alot !!
It bugged because i used a global trigger array tr and a local trigger with the same name
after renaming tr into something else it works fine again
i thought this would not give any problems.. o_O tr and tr[ ]
also ive got no idea why this does appear with 1.24 and worked fine before
anyway... thanks alot- works again now :)

well i always name locals like trigger trig, trg, t or smth if its a global then Trig, Trg, T... its quite simple!

i really did not thought that u used same names however in 1.24 that bug was fixed as well! in 1.23- you could have have global and local of same name and then that local will be used! however that was a bug and it was fixed as well. in c++ that is allowed! but special character is requied to know will you call local or global...

anyway bigapple90 you have a nice eye!
~DD
 
Level 15
Joined
Jan 31, 2007
Messages
502
well i always name locals like trigger trig, trg, t or smth if its a global then Trig, Trg, T... its quite simple!

i really did not thought that u used same names however in 1.24 that bug was fixed as well! in 1.23- you could have have global and local of same name and then that local will be used! however that was a bug and it was fixed as well. in c++ that is allowed! but special character is requied to know will you call local or global...

anyway bigapple90 you have a nice eye!
~DD

didnt know that this was "fixed"

but i also thought it would decide between an array and not array
i mean its clear ithats it could get problems with exactly the same name

but i thought it would work with arrays and non array
i mean its sure which variable was ment if i use "tr" or "tr[1]"
 
Level 15
Joined
Jul 19, 2007
Messages
618
didnt know that this was "fixed"

but i also thought it would decide between an array and not array
i mean its clear ithats it could get problems with exactly the same name

but i thought it would work with arrays and non array
i mean its sure which variable was ment if i use "tr" or "tr[1]"

yes well its on our logic! however in memory what is basically an variable?

well its simply has 2 values!

1) Address
2) Value

thats for non-arrays! In Jass we have no right to access address but we can say its an variable name... since every variable has an name it will allocate an new address as that "name"

array is as well an variable exactly looking like non-array!
but what does make it different is that arrays are allocated when you assign a value to it.. example:

Code:
integer i (Address: 0xcc84af) (Value: nothing)
integer j (Address: 0xcc84b0) (Value: nothing)
integer k (Address: 0xcc84b1) (Value: nothing)
...
integer array L (Address: 0xcc84b2) (Value: nothing)

i = 7 (Address: 0xcc84af) (Value: 7)
j = -7 (Address: 0xcc84b0) (Value: -7)
k = 100 (Address: 0xcc84b1) (Value: 100)
L[0] = 101 (Address: 0xcc84b2) (Value: 101)
L[1] = 102 (Address: 0xcc84b2+1) (Value: 102)
L[2] = -10 (Address: 0xcc84b2+2) (Value: -10)

as you can see its no difference... arrays are same but just tells how much offset memory points do you take from its "main" address...

giving names to local as same to global (no matter is it an array or not) is not right in jass!

well in c++ you can do that with special characters but in jass its not possible...

anyway glade that it all works!
~DD
 
Top