Spellpack DotA Spellpack

XeNiM666

I lurk for pizza
Reaction score
138
DotA Spellpack

This spell pack contains 4 spells.
I didn't put in screenshots since almost everyone plays DotA
Also, I think this follows the JESP Standard??

GUI/JASS/vJASS: vJASS ( yay! first time! )
MUI/MPI: Fully
Leakless: I think so...
Lagless: No lag i mine so... Yes.
Import Difficulty: Easy - Normal
Requires: Vexorian's Attachable Vars

Aphotic Shield
Summons dark energies around an ally unit/structure, creating a shield that absorbs a set amount of damage before expiring. When the shield is destroyed it will deal damage equal to the amount it absorbed to an area around it. If cast on self while using borrowed time, the damage you take will heal you.
Lasts 15 seconds.

Level 1 - 100 damage.
Level 2 - 125 damage.
Level 3 - 150 damage.
Level 4 - 175 damage.

Aphotic1.jpg

JASS:
scope AphoticShield initializer Init

//***********************************************//
//**************** CONFIGURATION ****************//
//***********************************************//

globals
    // APHOTIC SHIELD ABILITY ID //
    private constant integer SPELL_ID = 'A002'
    
    // APHOTIC SHIELD BUFF ID //
    private constant integer BUFF_ID = 'B001'
    
    // APHOTIC SHIELD MODEL //
    private constant string SHIELD_MODEL = "war3mapImported\\Defensive Barrier big.mdx"
    
    // APHOTIC SHIELD MODEL ATTACHMENT POINT //
    private constant string SHIELD_ATTACHMENT = "chest"
    
    // APHOTIC SHIELD DAMAGE EFFECT //
    private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
    
    // APHOTIC SHIELD DAMAGE EFFECT ATTACHMENT POINT //
    private constant string DAMAGE_EFFECT_ATTACHMENT = "chest"
endglobals

private function PercentageHealed takes integer lvl returns real
   return 100.00 // PERCENTAGE OF DAMAGE //
endfunction

private function DamageAbsorbed takes integer lvl returns real
    // DAMAGE ABSORBED PER LEVEL //
    return 75.00 + ( lvl * 25.00 )
endfunction

private function Damage takes integer lvl returns real
    // DAMAGE PER LEVEL //
    return 75.00 + ( lvl * 25.00 )
endfunction

private function Area takes integer lvl returns real
    // AREA OF EFFECT PER LEVEL //
    return 700.00
endfunction

//***********************************************//
//************** SPELL STARTS HERE **************//
// DONT TOUCH IF YOU DONT KNOW WHAT YOU'RE DOING //
//***********************************************//

globals
    private group gr = CreateGroup()
endglobals

private function TD_Group_Actions takes nothing returns nothing
    local string ss = GetAttachmentTable(gr)
    
    local unit caster = GetTableUnit(ss, "caster")
    local unit picked = GetEnumUnit()
    
    local real damage = Damage(GetUnitAbilityLevel(caster, SPELL_ID))
    
    call DestroyEffect( AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACHMENT) )

    call UnitDamageTarget( caster, picked, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
    
    set caster = null
    set picked = null
endfunction

private function TD_Group_Conditions takes nothing returns boolean
    local string ss = GetAttachmentTable(gr)
    
    local unit caster = GetTableUnit(ss, "caster")
    
    if IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(caster)) == true then
        set caster = null
        return true
    endif
    
    set caster = null
    return false
endfunction

private function Heal takes nothing returns nothing
    local timer t = GetExpiredTimer()
    
    local string s = GetAttachmentTable(t)
    
    local unit caster = GetTableUnit(s, "caster")
    local unit target = GetTableUnit(s, "taker")
    local real damage = GetTableReal(s, "taken")
    
    local real percentage = PercentageHealed(GetUnitAbilityLevel(caster, SPELL_ID))
    
    local real healed = ( ( (GetUnitState(target, UNIT_STATE_LIFE)) + damage ) / 100.00 ) * percentage
    
    call SetUnitState( target, UNIT_STATE_LIFE, (GetUnitState(target, UNIT_STATE_LIFE)) + damage )
    
    set target = null
    set t = null
endfunction

private function TD_Actions takes nothing returns nothing
    local trigger TD = GetTriggeringTrigger()
    local string s = GetAttachmentTable(TD)
    local string ss
    local string sss
        
    local effect e = null
    
    local timer t = CreateTimer()
    
    local unit caster = GetTableUnit(s, "caster")
    local unit target = GetTableUnit(s, "target")
    
    local real limit = DamageAbsorbed(GetUnitAbilityLevel(caster, SPELL_ID))

    local real d = GetTableReal(s, "damage")
    
    local location target_pos = GetUnitLoc(target)
    
    local real tx = GetLocationX(target_pos)
    local real ty = GetLocationY(target_pos)
    
    local real r = GetEventDamage()
    
    local real AoE = Area(GetUnitAbilityLevel(caster, SPELL_ID))
    
    set sss = GetAttachmentTable(t)
    
    call SetTableReal(sss, "taken", r)
    call SetTableObject(sss, "caster", caster)
    call SetTableObject(sss, "taker", target)
    
    call TimerStart( t, 0.01, false, function Heal)

    set d = ( d + r )
        
    call SetTableReal(s, "damage", d)
    
    if d >= limit then
        
        set ss = GetAttachmentTable(gr)
        
        call SetTableObject(ss, "caster", caster)
        call SetTableObject(ss, "target", target)
        
        call GroupEnumUnitsInRange(gr, tx, ty, AoE, Condition(function TD_Group_Conditions))
        call ForGroup( gr, function TD_Group_Actions )
        
        call GroupClear( gr )
        
        set e = GetTableEffect(s, "effect")
        
        call DestroyEffect(e)
        set e = null
        
        call RemoveLocation(target_pos)
        set target_pos = null
    
        set caster = null
        set target = null
        
        call DestroyTimer(t)
        set t = null
    
        call DestroyTrigger(TD)
        set TD = null
    endif
    
    call RemoveLocation(target_pos)
    set target_pos = null
    
    set caster = null
    set target = null
    
    call DestroyTimer(t)
    set t = null
endfunction

private function TS_Actions takes nothing returns nothing
    local trigger TD = CreateTrigger()
    local string s = GetAttachmentTable(TD)
    
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    
    local effect e = AddSpecialEffectTarget( SHIELD_MODEL, target, SHIELD_ATTACHMENT)
    
    local real d = 0.00
    
    call SetTableReal(s, "damage", d)
    call SetTableObject(s, "effect", e)
    call SetTableObject(s, "caster", caster)
    call SetTableObject(s, "target", target)
    
    call UnitRemoveBuffs( target, false, true )
    
    call TriggerRegisterUnitEvent( TD, target, EVENT_UNIT_DAMAGED )
    call TriggerAddAction( TD, function TD_Actions )
    
    set e = null
    set caster = null
    set target = null
    set TD = null
endfunction

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

//===========================================================================
private function Init takes nothing returns nothing
    local trigger AS = CreateTrigger(  )
    
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent( AS, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        
        set i = i + 1
        exitwhen i == 16
    endloop
    
    call TriggerAddCondition( AS, Condition( function AS_Check_ID ) )
    call TriggerAddAction( AS, function TS_Actions )
    
    set AS = null
endfunction

endscope

Chain Frost
Releases a jumping breath of frost that jumps 7 times.

Level 1 - Deals 280 damage per hit.
Level 2 - Deals 370 damage per hit.
Level 3 - Deals 460 damage per hit.

ChainFrost.jpg

JASS:
scope ChainFrost initializer Init

//***********************************************//
//**************** CONFIGURATION ****************//
//***********************************************//

globals
    // CHAIN FROST ABILITY ID //
    private constant integer SPELL_ID = 'A003'
    
    // CHAIN FROST BUFF ID //
    private constant integer BUFF_ID = 'B002'
    
    // CHAIN FROST CHECKER ID //
    private constant integer CHECKER_ID = 'A006'
    
    // CHAIN FROST CHECKER ORDER STRING //
    private constant string CHECKER_ORDER = "acidbomb"
    
    // CHAIN FROST NOVA ID //
    private constant integer NOVA_ID = 'A005'
    
    // CHAIN FROST NOVA ORDER STRING //
    private constant string NOVA_ORDER = "frostnova"
    
    // DUMMY UNIT ID //
    private constant integer DUMMY_ID = 'u001'
endglobals

private function Bounce takes integer lvl returns integer
    // NUMBER OF BOUNCES PER LEVEL //
    return 7
endfunction

private function Range takes integer lvl returns real
    // RANGE IN BETWEEN BOUNCES PER LEVEL //
    return 800.00
endfunction

//***********************************************//
//************** SPELL STARTS HERE **************//
// DONT TOUCH IF YOU DONT KNOW WHAT YOU'RE DOING //
//***********************************************//

globals
    private group g = CreateGroup()
endglobals

private function Group_Action takes nothing returns nothing
    local string s = GetAttachmentTable(g)
    
    local unit caster = GetTableUnit(s, "caster")
    local unit target = GetTableUnit(s, "target")
    
    if IsUnitType(GetEnumUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitType(GetEnumUnit(), UNIT_TYPE_MECHANICAL) == false and IsUnitType(GetEnumUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(GetTriggerUnit())) == true and GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) > 0 and GetEnumUnit() != caster then
        set target = GetEnumUnit()
        
        call SetTableObject(s, "target", target)
    endif
    
    set caster = null
    set target = null
endfunction

private function CF_Action takes nothing returns nothing
    local unit u = GetTriggerUnit() // Constant Triggering unit //

    local unit caster = GetTriggerUnit()
    local real cx
    local real cy
    
    local unit target = GetSpellTargetUnit()
    local real tx
    local real ty
    
    local string s = GetAttachmentTable(g)
    
    local integer lvl = GetUnitAbilityLevel( caster, SPELL_ID)
    
    local unit dummy = null
    
    local real range = Range(lvl)
    
    local integer i = 0
    local integer bounces = Bounce(lvl)
    
    loop    
        set cx = GetUnitX(caster)
        set cy = GetUnitY(caster)
    
        set dummy = CreateUnit( GetOwningPlayer( u ), DUMMY_ID, cx, cy, 270.00 )
        
        call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )
        call UnitAddAbility( dummy, CHECKER_ID )
        call IssueTargetOrder( dummy, CHECKER_ORDER, target )
        
        set dummy = null
        
        loop
            call TriggerSleepAction(0.10)

            exitwhen GetUnitAbilityLevel(target,BUFF_ID) > 0 or GetUnitState(target, UNIT_STATE_LIFE) <= 0
        endloop
        
        if ( GetUnitState(target, UNIT_STATE_LIFE) > 0 ) then
            set tx = GetUnitX(target)
            set ty = GetUnitY(target)
            
            set dummy = CreateUnit( GetOwningPlayer( u ), DUMMY_ID, tx, ty, 270.00 )

            call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )
            call UnitAddAbility( dummy, NOVA_ID )
            call SetUnitAbilityLevel( dummy, NOVA_ID, lvl )
            call IssueTargetOrder( dummy, NOVA_ORDER, target )
            
            set dummy = null

        else
            return
        endif
        
        set caster = target
        set cx = GetUnitX(caster)
        set cy = GetUnitY(caster)
        
        call GroupEnumUnitsInRange(g, cx, cy, range, null )
        
        call SetTableObject(s, "target", target)
        call SetTableObject(s, "caster", caster)

        call ForGroup( g, function Group_Action )
        
        set s = GetAttachmentTable(g)

        set target = GetTableUnit(s, "target")
        
        call GroupClear( g )
                
        set i = i + 1
        exitwhen i > bounces
    endloop
    
    set u = null
    set caster = null
    set target = null
endfunction

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

//===========================================================================
private function Init takes nothing returns nothing
    local trigger CF = CreateTrigger(  )
    
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent( CF, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        
        set i = i + 1
        exitwhen i == 16
    endloop
    
    call TriggerAddCondition( CF, Condition( function CF_Check_ID ) )
    call TriggerAddAction( CF, function CF_Action )

    set CF = null
endfunction

endscope

Chronosphere
Faceless Void creates a rip in spacetime causing all units in that area to become trapped for its duration. Faceless Void has a mysterious connection with spacetime that causes him to be unaffected by the sphere. Casting range increases per level.

Level 1 - 3 seconds.
Level 2 - 4 seconds.
Level 3 - 5 seconds.

No screenshot for chronosphere because of some wierd bug that photobucket doesnt let me upload the screenshot

JASS:
scope Chronosphere initializer Init

//***********************************************//
//**************** CONFIGURATION ****************//
//***********************************************//

globals
    // CHRONOSPHERE ABILITY ID //
    private constant integer SPELL_ID = 'A004'
    
    // CHRONOSPHERE BUFF ID //
    private constant integer BUFF_ID = 'B003'
    
    // CHRONOSPHERE CHECKER ID //
    private constant integer CHECKER_ID = 'A007'
    
    // CHRONOSPHERE CHECKER ORDER STRING //
    private constant string ORDER_ID = "cloudoffog"
    
    // FACELESS VOID ID //
    private constant integer VOID_ID = 'E000'
    
    // CHRONOSPHERE DUMMY UNIT ID //
    private constant integer DUMMY_ID = 'u003'
    
    // ANIMATION OF THE DUMMY UPON CREATION //
    private constant string ANIM = "birth"
    
    // LOCUST ABILITY ID //
    private constant integer LOCUST = 'Aloc'
endglobals

private function Duration takes integer lvl returns real
    // DURATION OF THE CHRONOSPHERE PER LEVEL //
    return 2.00 + ( lvl * 1.00 )
endfunction

private function AoE takes integer lvl returns real
    // AREA OF EFFECT OF THE SPELL PER LEVEL //
    return 425.00
    // DONT WORRY ABOUT THE SCALING OF THE DUMMY UNIT //
    //** THE SCALING OF THE DUMMY IS RELATIVE TO THE *//
    //********** AREA OF EFFECT OF THE SPELL *********//
endfunction

//***********************************************//
//************** SPELL STARTS HERE **************//
// DONT TOUCH IF YOU DONT KNOW WHAT YOU'RE DOING //
//***********************************************//

private function t2_Group_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) != VOID_ID and GetUnitAbilityLevel( GetFilterUnit(), BUFF_ID ) <= 0
endfunction

private function t2_Group_Action takes nothing returns nothing
    local unit u = GetEnumUnit()
    
    call PauseUnit( u, false )
    call UnitWakeUp( u )
    call SetUnitTimeScale( u, 1.00 )
    
    set u = null
endfunction

private function t2_Actions takes nothing returns nothing
    local trigger t2 = GetTriggeringTrigger()
    
    local string s = GetAttachmentTable(t2)

    local unit u = GetTriggerUnit()
    local real ux = GetUnitX(u)
    local real uy = GetUnitY(u)
    
    local real Area = GetTableReal(s, "Area")
    
    local real nArea = Area + 50.00
    
    local group g = CreateGroup()
    
    call GroupEnumUnitsInRange( g, ux, uy, nArea, Condition( function t2_Group_Conditions ) )

    call ForGroup( g, function t2_Group_Action )
    
    call DestroyGroup(g)
    set g = null
    
    set u = null
endfunction

private function t1_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) != VOID_ID
endfunction

private function t1_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    
    call PauseUnit( u, true )
    call SetUnitTimeScale( u, 0.00 )
    
    set u = null
endfunction

private function Group_Condition takes nothing returns boolean
    return GetUnitAbilityLevel( GetFilterUnit(), LOCUST ) != 0 and GetUnitTypeId(GetFilterUnit()) != VOID_ID
endfunction

private function Group_Action takes nothing returns nothing
    local unit u = GetEnumUnit()
    
    call PauseUnit( u, true )
    call UnitWakeUp( u )
    call SetUnitTimeScale( u, 0 )
    
    set u = null
endfunction

private function C_Actions takes nothing returns nothing
    local trigger t1 = CreateTrigger()
    local trigger t2 = CreateTrigger()
    
    local string s = GetAttachmentTable(t2)

    local unit caster = GetTriggerUnit()
    
    local location target = GetSpellTargetLoc()
    local real tx = GetLocationX(target)
    local real ty = GetLocationY(target)
    
    local real dur = Duration(GetUnitAbilityLevel( caster, SPELL_ID ) )
    
    local real Area = AoE(GetUnitAbilityLevel( caster, SPELL_ID ) )
    
    local real multiplier = 0.00823
    
    local real size = ( multiplier * Area )
    
    local unit dummy = CreateUnit( GetOwningPlayer(caster), DUMMY_ID, tx, ty, 270.00 )
    local real dx = GetUnitX(dummy)
    local real dy = GetUnitY(dummy)
    
    local group g = CreateGroup()
    
    call SetTableReal(s, "Area", Area)
    
    call TriggerRegisterUnitInRange( t1, dummy, Area, null )
    call TriggerAddCondition( t1, Condition( function t1_Conditions ) )
    call TriggerAddAction( t1, function t1_Actions )
    
    call TriggerRegisterUnitEvent( t2, dummy, EVENT_UNIT_DEATH )
    call TriggerAddAction( t2, function t2_Actions )
    
    call UnitApplyTimedLife( dummy, 'BTLF', dur )
    call UnitAddAbility( dummy, CHECKER_ID )
    call SetUnitAbilityLevel( dummy, CHECKER_ID, GetUnitAbilityLevel( caster, SPELL_ID ) )
    call IssuePointOrderLoc( dummy, ORDER_ID, target )
    call SetUnitAnimation( dummy, ANIM )
    
    call SetUnitScale( dummy, size, size, size )
    call SetUnitTimeScale( dummy, 0.65 )
    
    call GroupEnumUnitsInRange( g, dx, dy, Area, Condition( function Group_Condition ) )

    call ForGroup( g, function Group_Action )
     
    call RemoveLocation( target )
    set target = null
    
    call DestroyGroup( g )
    set g = null
    
    call TriggerSleepAction( 1.10 )
    
    call SetUnitTimeScale( dummy, 0 )
    
    set caster = null
    set dummy = null
    set t1 = null
    set t2 = null
endfunction

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

//===========================================================================
private function Init takes nothing returns nothing
    local trigger C = CreateTrigger(  )
    
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent( C, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        
        set i = i + 1
        exitwhen i == 16
    endloop
    
    call TriggerAddCondition( C, Condition( function C_Check_ID ) )
    call TriggerAddAction( C, function C_Actions )
    
    set C = null
endfunction

endscope

Time Walk
Quickly moves to a target location and slows the movement and attack of all units at the end of its path for 3 seconds.

Level 1 - 700 cast range. 10% slow.
Level 2 - 900 cast range. 20% slow.
Level 3 - 1100 cast range. 30% slow.
Level 4 - 1300 cast range. 40 % slow.

TimeW.jpg

JASS:
scope TimeWalk initializer Init

//***********************************************//
//**************** CONFIGURATION ****************//
//***********************************************//

globals
    // TIME WALK ABILITY ID //
    private constant integer SPELL_ID = 'A001'
    
    // DUMMY UNIT ID //
    private constant integer DUMMY_UNIT_ID = 'u001'
    
    // TIME WALK SLOW ABILITY ID //
    private constant integer TW_SLOW_ABIL_ID = 'A000'
    
    // TIME WALK SLOW ABILITY ORDER STRING //
    private constant string TW_SLOW_ABIL_ORDER = "thunderclap"
    
    // WHETHER YOU WILL TURN INVULNERABLE OR NOT //
    private constant boolean INVUL = true
    
    // THE ANIMATION OF THE SPELL //
    private constant string ANIM = "walk"
    
    // THE ANIMATION AFTER CASTING THE SPELL //
    private constant string AFTER_ANIM = "stand"
    
    // WHETHER WHEN YOU CAST THE SPELL YOU WILL TURN BLACK //
    private constant boolean BLACK = true
    
        // **** IGNORE IF BLACK IS EQUAL TO FALSE **** //
    
        // RED COLOR OF THE CASTER AFTER THE SPELL //
        private constant integer RED = 0
    
        // GREEN COLOR OF THE CASTER AFTER THE SPELL //
        private constant integer GREEN = 255
    
        // BLUE COLOR OF THE CASTER AFTER THE SPELL //
        private constant integer BLUE = 150
endglobals

private function Speed takes integer lvl returns real
    return 90.00 // SPEED OF THE TIME WALK SPELL PER LEVEL //
endfunction

//***********************************************//
//************** SPELL STARTS HERE **************//
// DONT TOUCH IF YOU DONT KNOW WHAT YOU'RE DOING //
//***********************************************//

private function TW_Move takes nothing returns nothing
    local timer time = GetExpiredTimer()
    local string s = GetAttachmentTable(time)
    
    local unit caster = GetTableUnit(s, "caster")
    local location caster_pos = GetUnitLoc(caster)
    local real cx = GetUnitX(caster)
    local real cy = GetUnitY(caster)
    
    local real SPEED = Speed(GetUnitAbilityLevel(caster, SPELL_ID ) )
    
    local real ntx = GetTableReal(s, "tx")
    local real nty = GetTableReal(s, "ty")
    
    local real angle = GetTableReal(s, "angle")
    
    local real dx = ntx - cx
    local real dy = nty - cy
    
    local real nd = SquareRoot(dx * dx + dy * dy)
    
    local unit dummy
    local real x
    local real y
    
    if nd < SPEED then
        set x = cx + nd * Cos(angle * bj_DEGTORAD)
        set y = cy + nd * Sin(angle * bj_DEGTORAD)
        call SetUnitPosition( caster, x , y )
    else
        set x = cx + SPEED * Cos(angle * bj_DEGTORAD)
        set y = cy + SPEED * Sin(angle * bj_DEGTORAD)
        call SetUnitPosition( caster, x , y )
    endif
    
    if nd == 0.00 then
        call SetUnitPathing( caster, true )
        
        if INVUL == true then
            call SetUnitInvulnerable( caster , false )
        endif
        
        if BLACK == true then
            call SetUnitVertexColor( caster, RED, GREEN, BLUE, 255 )
        endif
        
        set dummy = CreateUnit( GetOwningPlayer(caster), DUMMY_UNIT_ID, cx, cy, 270.00 )
        
        call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )
        call UnitAddAbility( dummy, TW_SLOW_ABIL_ID )
        call SetUnitAbilityLevel( dummy, TW_SLOW_ABIL_ID, GetUnitAbilityLevel(caster, SPELL_ID ) )
        call IssueImmediateOrder( dummy, TW_SLOW_ABIL_ORDER )
        
        call SetUnitAnimation( caster, AFTER_ANIM )
        call PauseUnit( caster, false )
        
        call PauseTimer(time)
        call DestroyTimer(time)
        
        set dummy = null
    endif
    
    call RemoveLocation(caster_pos)
    set caster_pos = null
    set caster = null
    set time = null
endfunction

private function TW_Actions takes nothing returns nothing
    local timer time = CreateTimer()
    local string s = GetAttachmentTable(time)
    
    local unit caster = GetTriggerUnit()
    local location target = GetSpellTargetLoc()
    
    local real cx = GetUnitX(caster)
    local real cy = GetUnitY(caster)
    
    local real tx = GetLocationX(target)
    local real ty = GetLocationY(target)
    
    local real dx = tx - cx
    local real dy = ty - cy
    
    local real angle = bj_RADTODEG * Atan2(ty - cy, tx - cx)
    local real distance  = SquareRoot(dx * dx + dy * dy)
    
    call SetTableObject(s, "caster", caster)
    
    call SetTableReal(s, "tx", tx)
    call SetTableReal(s, "ty", ty)
    call SetTableReal(s, "angle", angle)
    call SetTableReal(s, "distance", distance)
    call SetUnitPathing( caster, false )
    call PauseUnit( caster, true )
    
    if INVUL == true then
        call SetUnitInvulnerable( caster , true )
    endif
    
    call SetUnitAnimation( caster, ANIM )
    
    if BLACK == true then
        call SetUnitVertexColor( caster, 0, 0, 0, 255 )
    endif
    
    call TimerStart( time , 0.04 , true , function TW_Move )
    
    call RemoveLocation(target)
    set time = null
    set target = null
    set caster = null
endfunction

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

//===========================================================================
private function Init takes nothing returns nothing
    local trigger TW = CreateTrigger(  )
    
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent( TW, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        
        set i = i + 1
        exitwhen i == 16
    endloop
    
    call TriggerAddCondition( TW, Condition( function TW_Check_ID ) )
    call TriggerAddAction( TW, function TW_Actions )
    
    set TW = null
endfunction

endscope

Enjoy! :D:D:D

Thanks to:
Vexorian's AttachableVars
Tinki3's BARREN Spell Map Template
 

Attachments

  • DotA Spellpack 1.w3x
    84.7 KB · Views: 503

Jagan

New Member
Reaction score
30
I suggest you include some screenshots. NOT everyone plays DotA. Where did you get that idea?
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
In timewalk
JASS:
local real DEGTORAD = (3.14159/180.00)

Why? What's wrong with bj_DEGTORAD?

In chainfrost
JASS:
call IssueTargetOrder( dummy, "acidbomb", target )
[...]
call IssueTargetOrder( dummy, "frostnova", target )

Those strings should be in globals, in the configurables section.

In aphotic shield
JASS:
local effect e = AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACHMENT)
    call DestroyEffect(e)

--->
JASS:
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACHMENT))


JASS:
private function DamageAbsorbed takes integer lvl returns real
    if lvl == 1 then
        return 100.00 // DAMAGE ABSORBED AT LEVEL 1 //
    elseif lvl == 2 then
        return 125.00 // DAMAGE ABSORBED AT LEVEL 2 //
    elseif lvl == 3 then
        return 150.00 // DAMAGE ABSORBED AT LEVEL 3 //
    elseif lvl == 4 then
        return 175.00 // DAMAGE ABSORBED AT LEVEL 4 //
    endif
    return 0.00
endfunction

could be
JASS:
private function DamageAbsorbed takes integer lvl returns real
    return 75. + (25. * lvl)
endfunction
 

XeNiM666

I lurk for pizza
Reaction score
138
I suggest you include some screenshots.
im pposting the screenies now. <--- Done Apperantly all the spells are hard to capture because they cast very fast.
Why? What's wrong with bj_DEGTORAD?
its a BJ
Those strings should be in globals, in the configurables section.
ill get right on that <--- Done
In aphotic shield
well i think its merely the same but.... <--- Done
well i am trying to make the spells as more configurable as any spell.

NEED MORE COMMENTS.....:D:D:D
 

Artificial

Without Intelligence
Reaction score
326
> its a BJ
Do you know why BJs (to be more precise: BJ functions) are bad? :p It's because they normally just call a native function and do nothing else, and thus are slower than calling the native itself.

Stuff with the prefix "bj_", however, are variables, and thus cannot call any natives. And the ones where letters after the prefix are in caps, eg. bj_DEGTORAD, are constants. Making that a local is the same as you would make a local for each constant's value you're going to use, eg. like this:
JASS:
globals
    constant integer SPELL_ID = &#039;A000&#039;
endglobals

function heh takes nothing returns nothing
    local integer spellId = SPELL_ID
    // Do stuff
endfunction
But in this case it's even a bit worse, as now, when you're declaring the local, you're counting its value every time the function runs, whereas bj_DEGTORAD is only calculated once.

To sum it up, you should really think when a BJ actually is useless. I can't come up with any case where inlining the BJ variables would be necessary, but many cases where it is useful. The functions, though, are often useless (but some of them still ain't). ^_^
 

Trollvottel

never aging title
Reaction score
262
JASS:
private function TD_Group_Actions takes nothing returns nothing
    local string ss = GetAttachmentTable(gr)
    
    local unit caster = GetTableUnit(ss, &quot;caster&quot;)
    local unit picked = GetEnumUnit()
    
    local real damage = Damage(GetUnitAbilityLevel(caster, SPELL_ID))
    
    call DestroyEffect( AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACHMENT) )

    call UnitDamageTarget( caster, picked, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
    
    set caster = null
    set picked = null
endfunction

private function TD_Group_Conditions takes nothing returns boolean
    local string ss = GetAttachmentTable(gr)
    
    local unit caster = GetTableUnit(ss, &quot;caster&quot;)
    
    if IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(caster)) == true then
        set caster = null
        return true
    endif
    
    set caster = null
    return false
endfunction


do this in 1 condition-function which always returns false. so you dont have to call ForGroup(...). After that just clear the group and dont destroy it (means: dont create and destroy groups if you can have one global group which will just be cleared).


JASS:
        call DestroyBoolExpr(Condition(function TD_Group_Conditions))


thats senseless, just delete it. or use a boolexpr as a global which is set to Condition(....)
 
Reaction score
456
Aphotic Shield:

Indeed, you gotta change these:
JASS:
private function PercentageHealed takes integer lvl returns real
   if lvl == 1 then
        return 100.00 // PERCENTAGE OF DAMAGE HEALED AT LEVEL 1 //
    elseif lvl == 2 then
        return 100.00 // PERCENTAGE OF DAMAGE HEALED AT LEVEL 2 //
    elseif lvl == 3 then
        return 100.00 // PERCENTAGE OF DAMAGE HEALED AT LEVEL 3 //
    elseif lvl == 4 then
        return 100.00 // PERCENTAGE OF DAMAGE HEALED AT LEVEL 4 //
    endif
    return 0.00
endfunction

private function DamageAbsorbed takes integer lvl returns real
    if lvl == 1 then
        return 100.00 // DAMAGE ABSORBED AT LEVEL 1 //
    elseif lvl == 2 then
        return 125.00 // DAMAGE ABSORBED AT LEVEL 2 //
    elseif lvl == 3 then
        return 150.00 // DAMAGE ABSORBED AT LEVEL 3 //
    elseif lvl == 4 then
        return 175.00 // DAMAGE ABSORBED AT LEVEL 4 //
    endif
    return 0.00
endfunction

private function Damage takes integer lvl returns real
    if lvl == 1 then
        return 100.00 // DAMAGE AT LEVEL 1 //
    elseif lvl == 2 then
        return 125.00 // DAMAGE AT LEVEL 2 //
    elseif lvl == 3 then
        return 150.00 // DAMAGE AT LEVEL 3 //
    elseif lvl == 4 then
        return 175.00 // DAMAGE AT LEVEL 4 //
    endif
    return 0.00
endfunction

private function Area takes integer lvl returns real
    if lvl == 1 then
        return 700.00 // AREA OF EFFECT AT LEVEL 1 //
    elseif lvl == 2 then
        return 700.00 // AREA OF EFFECT AT LEVEL 2 //
    elseif lvl == 3 then
        return 700.00 // AREA OF EFFECT AT LEVEL 3 //
    elseif lvl == 4 then
        return 700.00 // AREA OF EFFECT AT LEVEL 4 //
    endif
    return 0.00
endfunction

To:
JASS:
private function PercentageHealed takes integer lvl returns real
    return 100.00
endfunction

private function DamageAbsorbed takes integer lvl returns real
    return 75.00 + 25.00 * lvl
endfunction

private function Damage takes integer lvl returns real
    return 75.00 + 25.00 * lvl
endfunction

private function Area takes integer lvl returns real
    return 700.00
endfunction


Rename the initialization function to something like "Init". No need for those InitTrig_<spell name> names, since we can make functions private.

You've actually inlined TriggerRegisterAnyUnitEventBJ(), and it still leaks. Just use TriggerRegisterAnyUnitEventBJ() function. Use more descriptive names for the locals, so we can actually read the code. And you don't have to null the local trigger.
JASS:
private function InitTrig_Aphotic_Shield takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(trig, Condition(function AS_Check_ID))
    call TriggerAddAction(AS, function TS_Actions)
endfunction


Some optimization here:
JASS:
private function TS_Actions takes nothing returns nothing
    local trigger TD = CreateTrigger()
    local string s = GetAttachmentTable(TD)
    local unit target = GetSpellTargetUnit()
    
    call SetTableReal(s, &quot;damage&quot;, 0.00)
    call SetTableObject(s, &quot;effect&quot;, AddSpecialEffectTarget( SHIELD_MODEL, target, SHIELD_ATTACHMENT))
    call SetTableObject(s, &quot;caster&quot;, GetTriggerUnit())
    call SetTableObject(s, &quot;target&quot;, target)
    
    call UnitRemoveBuffs(target, false, true)
    
    call TriggerRegisterUnitEvent(TD, target, EVENT_UNIT_DAMAGED)
    call TriggerAddAction(TD, function TD_Actions)

    set target = null
    set TD = null
endfunction


Instead of creating and destroying the gr (your global group), set it's initial value to CreateGroup(), and then clear it after you no longer need the units in it.

This could be done too. At least set GetFilterUnit() to a variable.
JASS:
private function TD_Group_Conditions takes nothing returns boolean
    local string ss = GetAttachmentTable(gr)
    
    local unit caster = GetTableUnit(ss, &quot;caster&quot;)
    local unit match = GetFilterUnit()
    local boolean flag = false
    
    if IsUnitType(match, UNIT_TYPE_STRUCTURE) == false and IsUnitType(match, UNIT_TYPE_MECHANICAL) == false and IsUnitType(match, UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitEnemy(match, GetOwningPlayer(caster)) == true then
        set flag = true
    endif
    
    set caster = null
    set match = null
    return flag
endfunction


Don't you think the timer's interval in TD_Actions is a bit too low? Maybe set it to 0.03 - 0.04. And instead of locations, use reals.

Chain Frost:

The constants...
JASS:
private function Bounce takes integer lvl returns integer
    if lvl == 1 then
        return 7 // NUMBER OF BOUNCES AT LEVEL 1 //
    elseif lvl == 2 then
        return 7 // NUMBER OF BOUNCES AT LEVEL 2 //
    elseif lvl == 3 then
        return 7 // NUMBER OF BOUNCES AT LEVEL 3 //
    endif
    return 0
endfunction

private function Range takes integer lvl returns real
    if lvl == 1 then
        return 800.00 // RANGE OF BOUNCE AT LEVEL 1 //
    elseif lvl == 2 then
        return 800.00 // RANGE OF BOUNCE AT LEVEL 2 //
    elseif lvl == 3 then
        return 800.00 // RANGE OF BOUNCE AT LEVEL 3 //
    endif
    return 0.00
endfunction

Ta-da!:
JASS:
private function Bounce takes integer lvl returns integer
    return 7
endfunction

private function Range takes integer lvl returns real
    return 800.00
endfunction


Again fix the initialization function.

Use reals instead of locations.

Initial value for global group to CreateGroup(), and clear it instead of destroying.

You use GetTriggerUnit() few times (when creating dummies), even though you've it in variable already.

The point variable does not need initial value.

Chronosphere:

Wee!:
JASS:
private function Duration takes integer lvl returns real
    if lvl == 1 then
        return 3.00 // DURATION OF CHRONOSPHERE AT LEVEL 1 //
    elseif lvl == 2 then
        return 4.00 // DURATION OF CHRONOSPHERE AT LEVEL 2 //
    elseif lvl == 3 then
        return 5.00 // DURATION OF CHRONOSPHERE AT LEVEL 3 //
    endif
    return 0.00
endfunction

private function AoE takes integer lvl returns real
    if lvl == 1 then
        return 425.00 // AREA OF EFFECT AT LEVEL 1 //
    elseif lvl == 2 then
        return 425.00 // AREA OF EFFECT AT LEVEL 2 //
    elseif lvl == 3 then
        return 425.00 // AREA OF EFFECT AT LEVEL 3 //
    endif
    return 0.00
    // DONT WORRY ABOUT THE SCALING OF THE DUMMY UNIT //
    //** THE SCALING OF THE DUMMY IS RELATIVE TO THE *//
    //********** AREA OF EFFECT OF THE SPELL *********//
endfunction

-->
JASS:
private function Duration takes integer lvl returns real
    return 2.00 + level * 1.00
endfunction

private function AoE takes integer lvl returns real
    return 425.00
endfunction


Fix the initialization function once again.

Location to reals in function t2_Actions.

Locust does not need a constant global I believe.

You can use variables when you need same values many times:
JASS:
private function t2_Group_Action takes nothing returns nothing
    local unit e = GetEnumUnit()
    call PauseUnit(e false)
    call UnitWakeUp(e)
    call SetUnitTimeScale(e, 1.00)
    set e = null
endfunction


You could use global group for t2_Actions, because you're able to do so, and it's safer.

Time Walk:

I'm not gonna write any code here.. I just tell you to change initialization function, and optimize the constant function.

call SetUnitVertexColor( caster, 0, 255, 150, 255 )
We should be able to configure RGBA.

local real angle = (180.00/3.14159) * Atan2(ty - cy, tx - cx)
Do not inline constants. You have ty - cy and tx - cx stored in variables already.
 

XeNiM666

I lurk for pizza
Reaction score
138
well... most of your comments you said was kinda did on purpose

i want the spells to be configurable at most.

also thanks for the tips about the bj's

but i still need more comments :D
 
Reaction score
456
The first thing you must do is to change the constant functions.

> but i still need more comments
You could already improve the codes drastically with the tips we gave you.
 

XeNiM666

I lurk for pizza
Reaction score
138
UPDATED:

Added a few configurations to Time Walk.
Changed a bit on the code.

P.S.
The configuration is still the same.
 
Reaction score
456
Why can't you just believe me?
JASS:


Person wants to have 20 levels for Aphotic Shield, he needs 19 elseifs. Now, if you do what I said, he needs one single line.

If you want your resources approved, listen to people who give you tips.

Which one, do you think, is more efficient:

1.
JASS:
return 25.00 + level * 25.00

2.
JASS:
if level == 1 then
    return 50.00
elseif level == 2 then
    return 75.00
elseif level ==3 then
    return 100.00
elseif level == 4 then
    return 125.00
elseif level == 5 then
    return 150.00
elseif level ==6 then
    return 175.00
elseif level == 7 then
    return 200.00
elseif level == 8 then
    return 225.00
elseif level == 9 then
    return 250.00
elseif level == 10 then
    return 275.00
elseif level == 11 then
    return 300.00
elseif level == 12 then
    return 325.00
elseif level == 13 then
    return 350.00
elseif level == 14 then
    return 375.00
elseif level == 15 then
    return 400.00
elseif level == 16 then
    return 425.00
elseif level == 17 then
    return 450.00
elseif level == 18 then
    return 475.00
elseif level == 19 then
    return 500.00
elseif level == 20 then
    return 525.00
elseif level == 21 then
    return 550.00
elseif level == 22 then
    return 575.00
elseif level == 23 then
    return 600.00
elseif level == 24 then
    return 625.00
elseif level == 25 then
    return 650.00
elseif level == 26 then
    return 675.00
elseif level == 27 then
    return 700.00
elseif level == 28 then
    return 725.00
elseif level == 29 then
    return 750.00
elseif level == 30 then
    return 775.00
endif
return 0.00
 

emjlr3

Change can be a good thing
Reaction score
395
im sorry I cant approve this using ancient handle vars - its just stupid
 

Viikuna

No Marlo no game.
Reaction score
265
It would be better to use struct and HandleVars to attach that struct to something, instead of playing with I2H.
 
A

Adamisk

Guest
So just how functional are these spells?



-------------
Im dyin to get the dota spells, but since the last dota map i was able to fully restore is a dirt-old 6.3-series one and thats kinda worthless yeah =P Might even be the 6.2 series
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top