Spellpack Hero: Arcane Sorceror

DrinkSlurm

Eat Bachelor Chow!
Reaction score
50
Typo in title: mod please change to [Spellpack] Arcane Sorcerer

last updated: January 24, 2008
version 1.00: original submission


Shadow Banish
Spell type: unit target, ground/air/organic/non-immune targets
Description: Turns a non-mechanical unit ethereal and slows its movement speed for a short duration. Ethereal creatures cannot attack, but they can cast spells and certain spells cast upon them will have a greater effect. Shadow Banished units also attract the attention of dark energies in the vicinity. Nearby shadows from all organic units within 500 range will periodically form into hostile entities that attack the targeted unit. [100 mana cost; 15 second cooldown]
Level 1 - 30% slow for 5 seconds; shadows deal 5 damage each (8 damage if they strike while the target is ethereal).
Level 2 - 45% slow for 7 seconds; shadows deal 6 damage each (9 damage if they strike while the target is ethereal).
Level 3 - 60% slow for 9 seconds; shadows deal 7 damage each (11 damage if they strike while the target is ethereal).

Note: In order to see the shadows produced by this spell, the player must have Unit Shadows turned on in their WC3 video settings.

Coding: JASS; requires vJASS
Leaks: Leakless
Multi Instanceability: MUI
Lag-susceptibility: none
Import Difficulty: easy (instructions included)

Trigger:
JASS:
//===========================================================================
//========================== Shadow Banish v1.00 ============================
//============================== Instructions ===============================
//===========================================================================
// MUI; requires vJASS
//===========================================================================
// IMPORTANT NOTE: In order to see the shadows produced by this spell, the
// player must have Unit Shadows turned on in their WC3 video settings.
//===========================================================================
// 1. Go to the Object Editor, and copy + paste the following:
//    Units
//       * Shadow Dummy
//    Abilities
//       * Shadow Banish: Add this ability to the Hero; make sure the custom
//         "Shadow Banish" buff is properly referenced.
//       * Shadow Flood (for Shadow Dummy): This is the spell that does damage
//         everytime a Shadow approaches the target unit; make sure the custom
//         "Shadow Flood" buff is properly referenced.
//    Buffs
//       * Shadow Banish: Make sure this buff is properly referenced in the
//         "Shadow Banish" ability.
//       * Shadow Flood: Make sure this buff is properly referenced in the
//         "Shadow Flood (for Shadow Dummy) ability.
// 2. Copy the following triggers:
//       * this trigger: "ShadowBanish"
// 3. To adjust the balance of the skill, you can change some of the following
//    values in the Object Editor:
//    Abilities
//       * Shadow Banish: cooldown, mana cost, speed reduction, cast range
//       * Shadow Flood (for Shadow Dummy): Damage per shadow
// 4. Make sure that the rawcodes specified below reference the to proper units,
//    abilities, or buffs.
scope ShadowBanish
globals
    private constant integer SHBANISH = 'A007' //Ability ID of "Shadow Banish"
    private constant integer SHDUMMY  = 'h001' //Unit    ID of "Shadow Dummy"
    private constant integer SHFLOOD  = 'A008' //Ability ID of "Shadow Flood (for Shadow Dummy)"
    private constant integer SBBUFF   = 'B000' //Buff    ID of "Shadow Banish"
// 5. More Configuration Options
    private constant real INTERVAL  =   0.50 //timer interval, how often shadows are spawned; default 0.50
    private constant real MOVEMIN   = 150.00 //random min move speed of shadows; default 150.00
    private constant real MOVEMAX   = 400.00 //random max move speed of shadows; default 400.00
    private constant real RADIUS    = 500.00 //range in which affected targets will attract shadows; default 500.00
    private constant real DURADDEND =   3.00 //this and DURFACTOR determine the duration of the spell; default 3.00
    private constant real DURFACTOR =   2.00 //this and DURADDEND determine the druation of the spell; default 2.00
endglobals
//=========================== End of Instructions ===========================
//===========================================================================
private struct SB
    integer p //keeps track of player # of casting hero
    integer lvl //keeps track of the level of Shadow Banish that was cast
    unit targ //target unit
    integer ticks //iteration count
endstruct
globals
    private SB array ALLDATA
    private timer ALLTIMER = CreateTimer()
    private integer TOTAL = 0
    private boolexpr FILTER
    private unit TARG
    private integer P
    private integer LVL
endglobals
//===========================================================================
private function Cond takes nothing returns boolean
    return GetSpellAbilityId() == SHFLOOD or GetSpellAbilityId() == SHBANISH
endfunction
//===========================================================================
private function RemoveShadows takes nothing returns nothing
    if GetUnitCurrentOrder(GetEnumUnit()) != OrderId("acidbomb") then
        call UnitApplyTimedLife(GetEnumUnit(), 'BTLF', 0.50)
    endif
endfunction

private function GroupFilter takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 0.406 and GetFilterUnit() != TARG and IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false
endfunction

private function GroupActions takes nothing returns nothing
    local real x = GetUnitX(GetEnumUnit())
    local real y = GetUnitY(GetEnumUnit())
    local unit u = CreateUnit(Player(P), SHDUMMY, x, y, 0)
    call SetUnitMoveSpeed(u, GetRandomReal(MOVEMIN, MOVEMAX))
    call UnitAddAbility(u, SHFLOOD)
    call SetUnitAbilityLevel(u, SHFLOOD, LVL)
    call IssueTargetOrder(u, "acidbomb", TARG)
    set u = null
endfunction

private function TimerActions takes nothing returns nothing
    local SB data
    local group g = CreateGroup()
    local real x
    local real y
    local integer i = 1
    loop
        exitwhen i > TOTAL
        set data = ALLDATA<i>
        set x = GetUnitX(data.targ)
        set y = GetUnitY(data.targ)
        set P = data.p
        set LVL = data.lvl
        set TARG = data.targ
        call GroupEnumUnitsInRange(g, x, y, RADIUS, FILTER)
        call ForGroup(g, function GroupActions)
        call GroupClear(g)
        if GetWidgetLife(TARG) &lt; 0.406 then
            set data.ticks = 0
        endif
        set data.ticks = data.ticks -1
        if data.ticks &lt;= 0 then
            call UnitRemoveAbility(TARG, SBBUFF)
            set bj_groupEnumTypeId = SHDUMMY
            call GroupEnumUnitsOfPlayer(g, Player(P), filterGetUnitsOfTypeIdAll)
            call ForGroup(g, function RemoveShadows)
            call data.destroy()
            set ALLDATA<i> = ALLDATA[TOTAL]
            set TOTAL = TOTAL - 1
            set i = i - 1
            if TOTAL == 0 then
                call PauseTimer(ALLTIMER)
            endif
        endif
        set i = i + 1
    endloop
    call DestroyGroup(g)
    set g = null
endfunction

private function SBCast takes nothing returns nothing
    local SB data = SB.create()
    if GetSpellAbilityId() == SHBANISH then
        set data.p = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
        set data.lvl = GetUnitAbilityLevel(GetTriggerUnit(), SHBANISH)
        set data.targ = GetSpellTargetUnit()
        set data.ticks = R2I((DURFACTOR * data.lvl + DURADDEND) / INTERVAL)
        set TOTAL = TOTAL + 1
        set ALLDATA[TOTAL] = data
        if TOTAL == 1 then
            call TimerStart(ALLTIMER, INTERVAL, true, function TimerActions)
        endif
    endif
endfunction
//===========================================================================
private function SFCast takes nothing returns nothing
    if GetSpellAbilityId() == SHFLOOD then
        call UnitApplyTimedLife(GetTriggerUnit(), &#039;BTLF&#039;, 0.50)
    endif
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
    local unit u = CreateUnit(Player(0), SHDUMMY, 0, 0, 0)
    call UnitAddAbility(u, SHFLOOD)
    call RemoveUnit(u)
    set gg_trg_ShadowBanish = CreateTrigger()
    set FILTER = Condition(function GroupFilter)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_ShadowBanish, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_ShadowBanish, Condition(function Cond))
    call TriggerAddAction(gg_trg_ShadowBanish, function SBCast)
    call TriggerAddAction(gg_trg_ShadowBanish, function SFCast)
    set u = null
endfunction
endscope</i></i>


Screenshot:



Backlash
Spell type: unit target, chain-type, hero/non-immune targets only
Description: A chain spell that bounces among multiple enemy Heroes and punishes them according to their own Strength, Agility, and Intelligence stats. [75 mana cost; 12 second cooldown]
Level 1 - deals damage equal to [target's Strength x 1.00]; destroys mana equal to [target's Intelligence x 1.00]; slows by 20% for duration equal to [target's Agility / 10] seconds. Strikes up to 3 Heroes.
Level 2 - deals damage equal to target's [Strength x 1.50]; destroys mana equal to [target's Intelligence x 1.50]; slows by 30% for duration equal to [target's Agility / 10] seconds. Strikes up to 4 Heroes.
Level 3 - deals damage equal to target's [Strength x 2.00]; destroys mana equal to [target's Intelligence x 2.00]; slows by 40% for duration equal to [target's Agility / 10] seconds. Strikes up to 5 Heroes.

Coding: JASS; requires vJASS
Leaks: Leakless
Multi Instanceability: MUI
Lag-susceptibility: none
Import Difficulty: easy (instructions included)

Trigger:
JASS:
//===========================================================================
//============================= Backlash v1.00 ==============================
//============================== Instructions ===============================
//===========================================================================
// MUI; requires vJASS
//===========================================================================
// 1. Go to the Object Editor, and copy + paste the following:
//    Units
//       * Dummy Caster
//    Abilities
//       * Backlash: Add this ability to the Hero
//       * Chain Lightning (for Dummy)
//       * Slow 1 (for Dummy)
//       * Slow 2 (for Dummy)
//       * Slow 3 (for Dummy)
// 2. Copy the following triggers:
//    Triggers
//       * this trigger: &quot;Backlash&quot;
// 3. To adjust the balance of the skill, you can change some of the following
//    values in the Object Editor:
//    Abilities
//       * Backlash: Cooldown, Mana Cost. Cast Range
//       * Slow 1/2/3: Amount and duration of slow; increase the levels of these
//         abilities if necessary (if your map has Heroes with more than 200
//         Agility); if you want Backlash to have more than 3 levels, create more
//         slow abilities and make sure they are properly referenced (including below
//         in the InitTrig function).
// 4. Make sure that the rawcodes specified below reference the to proper units,
//    abilities, or buffs.
scope Backlash
globals
    private constant integer BACKLASH = &#039;A00A&#039; //Ability ID of &quot;Backlash&quot;
    private constant integer DUMMY    = &#039;h000&#039; //Unit    ID of &quot;Dummy Caster&quot;
    private constant integer CHAINLIT = &#039;A003&#039; //Ability ID of &quot;Chain Lightning (for Dummy)&quot;
    private constant integer SLOW1    = &#039;A004&#039; //Ability ID of &quot;Slow 1 (for Dummy)&quot;
    private constant integer SLOW2    = &#039;A005&#039; //Ability ID of &quot;Slow 2 (for Dummy)&quot;
    private constant integer SLOW3    = &#039;A006&#039; //Ability ID of &quot;Slow 3 (for Dummy)&quot;
// 5. More Configuration Options
    private constant integer JUMPADDEND =   2    //this and JUMPFACTOR determine total max number of chain targets; default 2
    private constant integer JUMPFACTOR =   1    //this and JUMPADDEND determine total max number of chain targets; default 1
    private constant real INTERVAL      =   0.15 //timer interval how fast next chain target is hit; default 0.15
    private constant real RADIUS        = 600.00 //range in which next chain target is chosen; default 600.00
    private constant real STRADDEND     =   1.00 //this and STRDIVISOR help determine the damage to target&#039;s HP; default 1.00
    private constant real STRDIVISOR    =   2.00 //this and STRADDEND help determine the damage to target&#039;s HP; default 2.00
    private constant real INTADDEND     =   1.00 //this and INTDIVISOR help determine the amount of target&#039;s Mana loss; default 1.00
    private constant real INTDIVISOR    =   2.00 //this and INTADDEND help determine the amount of target&#039;s Mana loss; default 2.00
    private constant real AGIFACTOR     =   0.10 //multiplier for Agility that determines the level (duration) of slow; default 0.10
endglobals
//=========================== End of Instructions ===========================
//===========================================================================
private struct BL
    group g = CreateGroup() //keeps track of units already struck
    unit targ //current target unit
    unit hero //casting Hero
    integer ticks //# of bounce targets remaining
endstruct
globals
    private BL array ALLDATA
    private timer ALLTIMER = CreateTimer()
    private integer TOTAL = 0
    private boolexpr FILTER
    private group TEMPGROUP = CreateGroup()
    private unit TEMPHERO
    private integer array SLOW
endglobals
//===========================================================================
private function Cond takes nothing returns boolean
    return GetSpellAbilityId() == BACKLASH
endfunction
//===========================================================================
private function GroupFilter takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.406 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(TEMPHERO)) == true and IsUnitInGroup(GetFilterUnit(), TEMPGROUP) == false 
endfunction

private function TimerActions takes nothing returns nothing
    local BL data
    local integer lvl
    local real r 
    local integer int
    local group g = CreateGroup()
    local real x
    local real y
    local unit u
    local texttag tt = CreateTextTag()
    local integer i = 1
    loop
        exitwhen i &gt; TOTAL
        set data = ALLDATA<i>
        set lvl = GetUnitAbilityLevel(data.hero, BACKLASH)
        set int = R2I(GetHeroAgi(data.targ, true) * AGIFACTOR + 0.50)
        set x = GetUnitX(data.targ)
        set y = GetUnitY(data.targ)
//damage per strength
        set r = GetHeroStr(data.targ, true) * (lvl + STRADDEND) / STRDIVISOR
        call UnitDamageTarget(data.hero, data.targ, r, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
        call SetTextTagText(tt, &quot;-&quot; + I2S(R2I(r)), 0.023)
        call SetTextTagPosUnit(tt, data.targ, 0)
        call SetTextTagColor(tt, 255, 0, 0, 255)
        call SetTextTagPermanent(tt, false)
        call SetTextTagFadepoint(tt, 2.00)
        call SetTextTagVelocity(tt, -0.0251, 0.0251)
        call SetTextTagLifespan(tt, 3.00)
//mana loss per intelligence
        set r = GetHeroInt(data.targ, true) * (lvl + INTADDEND) / INTDIVISOR
        call SetUnitState(data.targ, UNIT_STATE_MANA, RMaxBJ(0, GetUnitState(data.targ, UNIT_STATE_MANA) - r))
        set tt = CreateTextTag()
        call SetTextTagText(tt, &quot;-&quot; + I2S(R2I(r)), 0.023)
        call SetTextTagPosUnit(tt, data.targ, 0)
        call SetTextTagColor(tt, 0, 0, 255, 255)
        call SetTextTagPermanent(tt, false)
        call SetTextTagFadepoint(tt, 2.00)
        call SetTextTagVelocity(tt, 0.0251, 0.0251)
        call SetTextTagLifespan(tt, 3.00)
//slow per agility
        set u = CreateUnit(GetOwningPlayer(data.hero), DUMMY, x, y, 0)
        call UnitApplyTimedLife(u, &#039;BTLF&#039;, 1.00)
        call UnitAddAbility(u, SLOW[lvl])
        call SetUnitAbilityLevel(u, SLOW[lvl], int)
        call IssueTargetOrder(u, &quot;slow&quot;, data.targ)
//chain to next target
        set TEMPHERO = data.hero
        call GroupAddGroup(data.g, TEMPGROUP)
        call GroupEnumUnitsInRange(g, x, y, RADIUS, FILTER)
        set data.targ = GroupPickRandomUnit(g)
        if data.targ == null then
            set data.ticks = 0
        else
            set u = CreateUnit(GetOwningPlayer(data.hero), DUMMY, x, y, 0)
            call UnitApplyTimedLife(u, &#039;BTLF&#039;, 1.00)
            call UnitAddAbility(u, CHAINLIT)
            call IssueTargetOrder(u, &quot;chainlightning&quot;, data.targ)
            call GroupAddUnit(data.g, data.targ)
        endif
        set data.ticks = data.ticks - 1
        if data.ticks &lt;= 0 then
            call data.destroy()
            set ALLDATA<i> = ALLDATA[TOTAL]
            set TOTAL = TOTAL - 1
            set i = i - 1
            if TOTAL == 0 then
                call PauseTimer(ALLTIMER)
            endif
        endif
        set i = i + 1
        call GroupClear(TEMPGROUP)
    endloop
    call DestroyGroup(g)
    set u = null
    set g = null
    set tt = null
endfunction

private function Actions takes nothing returns nothing
    local BL data = BL.create()
    set data.hero = GetTriggerUnit()
    set data.targ = GetSpellTargetUnit()
    set data.ticks = GetUnitAbilityLevel(GetTriggerUnit(), BACKLASH) * JUMPFACTOR + JUMPADDEND
    call GroupAddUnit(data.g, data.targ)
    set TOTAL = TOTAL + 1
    set ALLDATA[TOTAL] = data
    if TOTAL == 1 then
        call TimerStart(ALLTIMER, INTERVAL, true, function TimerActions)
    endif
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
    local unit u = CreateUnit(Player(0), DUMMY, 0, 0, 0)
    call UnitAddAbility(u, CHAINLIT)
    call UnitAddAbility(u, SLOW1)
    call UnitAddAbility(u, SLOW2)
    call UnitAddAbility(u, SLOW3)
    call RemoveUnit(u)
    set gg_trg_Backlash = CreateTrigger()
    set FILTER = Condition(function GroupFilter)
    set SLOW[1] = SLOW1
    set SLOW[2] = SLOW2
    set SLOW[3] = SLOW3
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Backlash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Backlash, Condition(function Cond))
    call TriggerAddAction(gg_trg_Backlash, function Actions)
    set u = null
endfunction
endscope</i></i>


Screenshot:



Multi Life Grip
Spell type: channelling, instant cast, ground/organic/non-immune targets only
Description: A quick channeling spell that drains life from several nearby enemy organic ground units within 600 range. The targets are lifted up into the air and are helpless for the duration of the spell. Life that is drained is given to the Hero. (This spell does NOT allow the health to exceed maximum.) [150 mana cost; 60 second cooldown]
Level 1 - drains up to 10 life per second from up to 6 units for 6 seconds.
Level 2 - drains up to 11 life per second from up to 7 units for 7 seconds.
Level 3 - drains up to 12 life per second from up to 8 units for 8 seconds.

Coding: JASS; requires vJASS
Leaks: Leakless
Multi Instanceability: MUI
Lag-susceptibility: none
Import Difficulty: easy (instructions included)

Trigger:
JASS:
//===========================================================================
//========================= Multi Life Grip v1.00 ===========================
//============================== Instructions ===============================
//===========================================================================
// MUI; requires vJASS
//===========================================================================
// 1. Go to the Object Editor, and copy + paste the following:
//    Units
//       * Dummy Caster: Note that for this spell the dummy caster must have no life
//         regeneration. When the dummy is created, the life set to 1.00 by the
//         trigger, and life that it drains is periodically given to the Hero caster.
//    Abilities
//       * Multi Life Grip: Add this ability to the Hero. Make sure the Base Order ID
//         does not conflict with any other spell on the Hero.
//       * Life Drain (for Dummy)
// 2. Copy the following trigger and variables:
//    Triggers
//       * this trigger: &quot;MultiLifeGrip&quot;
//    Variables
//       * udg_SimError: global sound variable used in Vexorian&#039;s SimError snippet
// 3. To adjust the balance of the skill, you can change some of the following
//    values in the Object Editor:
//    Abilities
//       * Multi Life Grip: duration, mana cost, cooldown
//       * Life Drain (for Dummy): hit points drained, drain interval
// 4. Make sure that the rawcodes specified below reference the to proper units,
//    abilities, or buffs.
scope MultiLifeGrip
globals
    private constant integer MLGRIP  = &#039;A000&#039; //Ability ID of &quot;Multi Life Grip&quot;
    private constant integer DUMMY   = &#039;h000&#039; //Unit    ID of &quot;Dummy Caster&quot;
    private constant integer LFDRAIN = &#039;A001&#039; //Ability ID of &quot;Life Drain (for Dummy)&quot;
// 5. More Configuration Options
    private constant real RADIUS      = 600.00 //range in which targets will be affected; default 600.00
    private constant real INTERVAL    =   0.25 //timer interval, how often targets are spun and life is drained; default 0.25
    private constant real DURADDEND   =   5.00 //this and DURFACTOR help to determine the duration of the spell; default 5.00
    private constant real DURFACTOR   =   1.00 //this and DURADDEND help to determine the duration of the spell; default 1.00
    private constant integer MTADDEND =   5    //this and MTFACTOR help to determine the max number of targets; default 5
    private constant integer MTFACTOR =   1    //this and MTADDEND help to determine the max number of targets; default 1
    private constant real FLYHTFACTOR =  37.50 //this and FLYHTBASE determine the max flying height of targets; default 37.50
    private constant real FLYHTBASE   = 187.50 //this and FLYHTFACTOR determine the max flying height of targets; default 187.50
    private constant string ORDER = &quot;absorb&quot; //this must match the Base Order ID for the &quot;Multi Life Grip&quot; ability; change this only if necessary
endglobals
//=========================== End of Instructions ===========================
//===========================================================================
//###########################################################################
//####################### SimError system by Vexorian #######################
function SimError takes player ForPlayer, string msg returns nothing
    if udg_SimError==null then
        set udg_SimError = CreateSoundFromLabel(&quot;InterfaceError&quot;, false, false, false, 10, 10)
    endif
    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, -1.00, 2.00, &quot;|c00FFCC00&quot; + msg + &quot;|r&quot;)
        call StartSound(udg_SimError)
    endif
endfunction
//########################### end of the SimError ###########################
//###########################################################################
private struct MLG
    unit hero //triggering unit
    group tg = CreateGroup() //target group
    group dg = CreateGroup() //dummy group
    real rate //fly height change rate
    integer ticks //iteration count
    integer ticks2 //iteration half-count
endstruct
globals
    private MLG array ALLDATA
    private timer ALLTIMER = CreateTimer()
    private integer TOTAL = 0
    private boolexpr FILTER
    private unit TEMPHERO
    private real RATE
    private group TEMPGROUP = CreateGroup()
endglobals
//===========================================================================
private function Cond takes nothing returns boolean
    return GetSpellAbilityId() == MLGRIP
endfunction
//===========================================================================
private function GroupFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and GetUnitAbilityLevel(GetFilterUnit(), &#039;Bdtl&#039;) == 0
endfunction

private function TGStopActions takes nothing returns nothing
    call PauseUnit(GetEnumUnit(), false)
    call SetUnitTimeScale(GetEnumUnit(), 1.00)
    call SetUnitFlyHeight(GetEnumUnit(), 0.00, RATE)
endfunction

private function DGStopActions takes nothing returns nothing
    call RemoveUnit(GetEnumUnit())
endfunction

private function TGDownActions takes nothing returns nothing
    call SetUnitFlyHeight(GetEnumUnit(), 0.00, RATE)
endfunction

private function TGActions takes nothing returns nothing
    call SetUnitFacingTimed(GetEnumUnit(), GetUnitFacing(GetEnumUnit()) + 90.00, 0.66)
    if GetWidgetLife(GetEnumUnit()) &lt; 0.406 then
        call GroupRemoveUnit(TEMPGROUP, GetEnumUnit())
        call PauseUnit(GetEnumUnit(), false)
        call SetUnitTimeScale(GetEnumUnit(), 1.00)
        call SetUnitFlyHeight(GetEnumUnit(), 0.00, RATE)
    endif
endfunction

private function DGActions takes nothing returns nothing
    local real r = GetWidgetLife(GetEnumUnit()) - 1
    call SetWidgetLife(GetEnumUnit(), 1.00)
    call SetWidgetLife(TEMPHERO, GetWidgetLife(TEMPHERO) + r)
endfunction

private function TimerActions takes nothing returns nothing
    local MLG data
    local integer i = 1
    loop
        exitwhen i &gt; TOTAL
        set data = ALLDATA<i>
        set TEMPHERO = data.hero
        set RATE = data.rate
        call GroupAddGroup(data.tg, TEMPGROUP)
        call ForGroup(TEMPGROUP, function TGActions)
        set data.ticks2 = data.ticks2 - 1
        if data.ticks2 == 0 then
            call ForGroup(TEMPGROUP, function TGDownActions)
        endif
        call GroupClear(data.tg)
        call GroupAddGroup(TEMPGROUP, data.tg)
        call ForGroup(data.dg, function DGActions)
        if CountUnitsInGroup(data.tg) == 0 or GetUnitCurrentOrder(data.hero) != OrderId(ORDER) then
            set data.ticks = 0
        endif
        set data.ticks = data.ticks - 1
        if data.ticks &lt;= 0 then
            call IssueImmediateOrder(TEMPHERO, &quot;stop&quot;)
            call ForGroup(data.dg, function DGStopActions)
            call GroupClear(data.dg)
            call ForGroup(TEMPGROUP, function TGStopActions)
            call GroupClear(TEMPGROUP)
            call data.destroy()
            set ALLDATA<i> = ALLDATA[TOTAL]
            set TOTAL = TOTAL - 1
            set i = i - 1
            if TOTAL == 0 then
                call PauseTimer(ALLTIMER)
            endif
        endif
        set i = i + 1
    endloop
    call GroupClear(TEMPGROUP)
endfunction

private function Cast takes nothing returns nothing
    local MLG data = MLG.create()
    local integer lvl = GetUnitAbilityLevel(GetTriggerUnit(), MLGRIP)
    local real dur = lvl * DURFACTOR + DURADDEND
    local integer mt = lvl * MTFACTOR + MTADDEND
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local group g = CreateGroup()
    local unit targ
    local unit u
    local real height = lvl * FLYHTFACTOR + FLYHTBASE
    set data.hero = GetTriggerUnit()
    set data.ticks = R2I(dur / INTERVAL)
    set data.ticks2 = data.ticks / 2
    set data.rate = height * 2 / dur
    call GroupEnumUnitsInRange(data.tg, x, y, RADIUS, FILTER)
    if CountUnitsInGroup(data.tg) &gt; mt then
        loop
            exitwhen CountUnitsInGroup(data.tg) == mt
            call GroupRemoveUnit(data.tg, GroupPickRandomUnit(data.tg))
        endloop
    endif
    if CountUnitsInGroup(data.tg) &gt; 0 then
        call GroupAddGroup(data.tg, g)
        loop
            set targ = FirstOfGroup(g)
            exitwhen targ == null
            set u = CreateUnit(GetOwningPlayer(data.hero), DUMMY, x, y, 0) 
            call UnitApplyTimedLife(u, &#039;BTLF&#039;, dur + 1)
            call SetWidgetLife(u, 1.00)
            call UnitAddAbility(u, LFDRAIN)
            call SetUnitAbilityLevel(u, LFDRAIN, lvl)
            call IssueTargetOrder(u, &quot;drain&quot;, targ)
            call GroupAddUnit(data.dg, u)
            call PauseUnit(targ, true)
            call UnitAddAbility(targ, &#039;Amrf&#039;)
            call UnitRemoveAbility(targ, &#039;Amrf&#039;)
            call SetUnitTimeScale(targ, 0.00)
            call SetUnitFlyHeight(targ, height, data.rate)
            call GroupRemoveUnit(g, targ)
        endloop
        set TOTAL = TOTAL + 1
        set ALLDATA[TOTAL] = data
        if TOTAL == 1 then
            call TimerStart(ALLTIMER, INTERVAL, true, function TimerActions)
        endif
    else
        call TriggerSleepAction(0.00)
        call IssueImmediateOrder(GetTriggerUnit(), &quot;stop&quot;)
        call SimError(GetOwningPlayer(GetTriggerUnit()), &quot;No valid targets within range.&quot;)
    endif
    call DestroyGroup(g)
    set g = null
    set targ = null
    set u = null
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
    local unit u = CreateUnit(Player(0), DUMMY, 0, 0, 0)
    call UnitAddAbility(u, LFDRAIN)
    call RemoveUnit(u)
    set gg_trg_MultiLifeGrip = CreateTrigger()
    set FILTER = Condition(function GroupFilter)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_MultiLifeGrip, EVENT_PLAYER_UNIT_SPELL_CHANNEL)
    call TriggerAddCondition(gg_trg_MultiLifeGrip, Condition(function Cond))
    call TriggerAddAction(gg_trg_MultiLifeGrip, function Cast)
    set u = null
endfunction
endscope</i></i>


Screenshot:
 

Attachments

  • [Spellpack] Arcane Sorcerer v1.00.w3x
    64.7 KB · Views: 271
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top