Spellpack Nevermore, the Shadowfiend

Discussion in 'Spells' started by Ayanami, Jan 1, 2011.

  1. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Introduction
    Decided to make Shadowfiend's spell in vJASS for fun.

    Requirements
    - Timer32
    - GroupUtils

    The spells:
    • Shadowraze [Active]
    • Necromastery [Passive]
    • Presence of the Dark Lord [Passive]
    • Requiem of Souls [Active]


    Details
    - The spells are vJASS
    - They should be leak-less and lag-less
    - It is MUI, meaning can be cast many times at the same instance
    - Shadowfiend from DoTA


    Implementation
    JASS:
    
    //==============================================================================
    //                      SHADOW FIELD SPELLPACK v1.2                       
    //                            BY Ayanami                            
    //==============================================================================
    
    //==============================================================================
    //                            REQUIREMENTS                                      
    //==============================================================================
    //
    // - vJASS Compiler (NewGen)
    // - Timer32                                                              
    // - GroupUtils                                                                  
    //                                                            
    //==============================================================================
    
    //==============================================================================
    //                           IMPLEMENTATION                                     
    //==============================================================================
    //
    // 1) Copy the whole "Required Systems" Trigger folder & paste in map
    // 2) Save the map, it will take a bit longer than usual
    // 3) After saving, close the map and re-open it
    // 4) Delete or disable the trigger "Objects"
    // 5) Copy all 8 abilities under "Undead" & paste in map
    // 6) Copy the single buff under "Undead" & paste in map
    // 7) Ensure that the following abilities have their buff set properly:
    //      Presence of the Dark Lord - Presence of the Dark Lord
    // 8) Copy the whole "Shadowfiend" Trigger folder
    // 9) Go through all the spell Configurations
    //
    //==============================================================================



    Spells

    Shadowraze

    Description:
    Gives the Shadow Fiend the power to desecrate regions in front of him at varying distances (200/450/700).

    Level 1 - 75 damage.
    Level 2 - 150 damage.
    Level 3 - 225 damage.
    Level 4 - 300 damage.

    Cast Range: Varies
    Target Type: Instant
    Cooldown: 10 seconds

    Screenshot:

    [​IMG]

    Code:
    JASS:
    
    scope Shadowraze initializer OnInit // requires GroupUtils
    
    //===========================================================================
    //                           CONFIGURABLES                        
    //===========================================================================
    
    globals
        private constant integer ABILID = 'ABSR' // raw code of ability "Shadowraze"
        private constant integer ABILIDZ = 'ASR0' // raw code of ability "Shadowraze (Z)"
        private constant integer ABILIDX = 'ASR1' // raw code of ability "Shadowraze (X)"
        private constant integer ABILIDC = 'ASR2' // raw code of ability "Shadowraze (C)"
        private constant integer PRELOADID = 'prel' // raw code of unit "Preloader"
        
        private constant integer DUMMYID = 'sHAD' // raw code of unit "Shadowraze Dummy", acts as the visual effect itself
        private constant real ANIMDUR = 2.0 // duration of DUMMYID
        private constant integer RED = 0 // red vertex color of DUMMYID
        private constant integer GREEN = 0 // green vertex color of DUMMYID
        private constant integer BLUE = 0 // blue vertex color of DUMMYID
        private constant integer TRANS = 255 // transparency of DUMMYID, where 0 is fully transparent
        private constant real SCALE = 1.2 // scale size of DUMMYID
        
        private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type of damage
        private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type of damage
        private constant weapontype WEP = WEAPON_TYPE_WHOKNOWS // weapon type of damage
    endglobals
    
    private function GetDamage takes integer level returns real
        return 75.0 * level // damage dealt
    endfunction
    
    private function GetArea takes integer level returns real
        return 250.0 // area of effect
    endfunction
    
    private function GetRangeZ takes integer level returns real
        return 200.0 // range of "Shadowraze (Z)"
    endfunction
    
    private function GetRangeX takes integer level returns real
        return 450.0 // range of "Shadowraze (X)"
    endfunction
    
    private function GetRangeC takes integer level returns real
        return 700.0 // range of "Shadowraze (C)"
    endfunction
    
    //===========================================================================
    //                          END CONFIGURABLES                        
    //===========================================================================
    
    native UnitAlive takes unit id returns boolean
    
    globals
        private unit Caster
        private real Damage
    endglobals
    
    private function OnRemove takes nothing returns boolean
        local trigger t = GetTriggeringTrigger()
        
        call RemoveUnit(GetTriggerUnit())
        call TriggerClearConditions(t)
        call DestroyTrigger(t)
        set t = null
        return false
    endfunction
    
    private function FilterFunc takes nothing returns boolean
        local unit u = GetFilterUnit()
        
        if IsUnitEnemy(u, GetOwningPlayer(Caster)) and UnitAlive(u) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
            call UnitDamageTarget(Caster, u, Damage, true, false, ATK, DMG, WEP)
        endif
        set u = null
        return false
    endfunction
    
    private function Actions takes nothing returns boolean
        local trigger t
        local unit u
        local integer spellid = GetSpellAbilityId()
        local integer level
        local real range
        local real a
        local real x
        local real y
        
        if spellid == ABILIDZ or spellid == ABILIDX or spellid == ABILIDC then
            set Caster = GetTriggerUnit()
            set level = GetUnitAbilityLevel(Caster, ABILID)
            set Damage = GetDamage(level)
            
            if spellid == ABILIDZ then
                set range = GetRangeZ(level)
            elseif spellid == ABILIDX then
                set range = GetRangeX(level)
            else
                set range = GetRangeC(level)
            endif
            
            set a = GetUnitFacing(Caster) * bj_DEGTORAD
            set x = GetUnitX(Caster) + range * Cos(a)
            set y = GetUnitY(Caster) + range * Sin(a)
            set u = CreateUnit(GetOwningPlayer(Caster), DUMMYID, x, y, a * bj_RADTODEG)
            call SetUnitVertexColor(u, RED, GREEN, BLUE, TRANS)
            call SetUnitScale(u, SCALE, SCALE, SCALE)
            call UnitApplyTimedLife(u, 'BTLF', ANIMDUR)
            set t = CreateTrigger()
            call TriggerRegisterDeathEvent(t, u)
            call TriggerAddCondition(t, Condition(function OnRemove))
            call GroupEnumUnitsInArea(ENUM_GROUP, x, y, GetArea(level), Filter(function FilterFunc))
        endif
        set t = null
        set u = null
        return false
    endfunction
    
    private function Learn takes nothing returns boolean
        local unit u
        local integer level
        
        if GetLearnedSkill() == ABILID then
            set u = GetTriggerUnit()
            set level = GetUnitAbilityLevel(u, ABILID)
            if level == 1 then
                call UnitAddAbility(u, ABILIDZ)
                call UnitAddAbility(u, ABILIDX)
                call UnitAddAbility(u, ABILIDC)
            else
                call SetUnitAbilityLevel(u, ABILIDZ, level)
                call SetUnitAbilityLevel(u, ABILIDX, level)
                call SetUnitAbilityLevel(u, ABILIDC, level)
            endif
        endif
        set u = null
        return false
    endfunction
    
    private function OnInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit(Player(13), PRELOADID, 0, 0, 0)
        
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Actions))
        set t = null
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
        call TriggerAddCondition(t, Condition(function Learn))
        set t = null
        
        //preload
        call UnitAddAbility(u, ABILIDZ)
        call UnitAddAbility(u, ABILIDX)
        call UnitAddAbility(u, ABILIDC)
        call RemoveUnit(CreateUnit(Player(13), DUMMYID, 0, 0, 0))
        call RemoveUnit(u)
        set u = null
    endfunction
    
    endscope


    Necromastery

    Description:
    Whenever the Shadow Fiend kills a target, he stores the unfortunate soul inside of him. For each stored soul he gains 2 bonus damage until his own death releases half of them from bondage.

    Level 1 - 16 damage limit.
    Level 2 - 30 damage limit.
    Level 3 - 46 damage limit.
    Level 4 - 60 damage limit.

    Passive

    Note: The souls (black projectile) must reach the hero in before providing its bonus damage.

    Screenshot:
    [​IMG]

    Code:
    JASS:
    
    scope Necromastery initializer SetUp // requires Timer32
    
    globals
        private integer array DAMAGEID[4]
    endglobals
    
    //===========================================================================
    //                           CONFIGURABLES                        
    //===========================================================================
    
    globals
        private constant integer ABILID = 'ABNe' // raw code of ability "Necromastery"
        public constant integer DUMABILID = 'ANe0' // raw code of ability "Necromastery (Display)"
        private constant integer DUMMYID = 'nECD' // raw code of unit "Necromastery Dummy"
        private constant integer PRELOADID = 'prel' // raw code of unit "Preloader"
        
        private constant integer DAMAGE = 2 // damage bonus per soul
        
        private constant real COL = 50.0 // collision size of the soul
        private constant real SPEED = 500.0 // distance traveled by the soul per second
        private constant real TRUESPEED = SPEED * T32_PERIOD // distance traveled by the soul per period
        private constant string DEATHART = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl" // death art used upon soul expiration
        private constant string DEATHARTPOINT = "chest" // attachment point of DEATHART
    endglobals
    
    private function SetUp takes nothing returns nothing
        local integer i = 0
        local unit u = CreateUnit(Player(13), PRELOADID, 0, 0, 0)
    
        set DAMAGEID[0] = 'dmg0' // raw code of ability "Damage (10000's) (Necromastery)"
        set DAMAGEID[1] = 'dmg1' // raw code of ability "Damage (1000's) (Necromastery)"
        set DAMAGEID[2] = 'dmg2' // raw code of ability "Damage (100's) (Necromastery)"
        set DAMAGEID[3] = 'dmg3' // raw code of ability "Damage (10's) (Necromastery)"
        set DAMAGEID[4] = 'dmg4' // raw code of ability "Damage (1's) (Necromastery)"
        
        //preload
        loop
            exitwhen i > 4
            call UnitAddAbility(u, DAMAGEID[i])
            set i = i + 1
        endloop
        call UnitAddAbility(u, DUMABILID)
        call RemoveUnit(CreateUnit(Player(13), DUMMYID, 0, 0, 0))
        call RemoveUnit(u)
        set u = null
    endfunction
    
    private function GetMaxSoul takes integer level returns integer // maximum number of souls
        if level == 1 then
            return 8
        elseif level == 2 then
            return 15
        elseif level == 3 then
            return 23
        elseif level == 4 then
            return 30
        endif
        return 0
    endfunction
    
    private function GetSoulLost takes integer level returns real
        return 0.50 // amount of souls lost on death, where 1.0 = 100%
    endfunction
    
    //===========================================================================
    //                          END CONFIGURABLES                        
    //===========================================================================
    
    private struct Data
        unit killer
        unit dummy
    
        private static method setDamage takes unit u returns nothing
            local integer damage = DAMAGE * (GetUnitAbilityLevel(u, DUMABILID) - 1)
            local integer factor = 10000
            local integer level
            local integer i = 0
            
            loop
                exitwhen i > 4
                set level = damage / factor
                call SetUnitAbilityLevel(u, DAMAGEID[i], level + 1)
                set damage = damage - (level * factor)
                set factor = factor / 10
                set i = i + 1
            endloop
        endmethod
        
        private method periodic takes nothing returns nothing
            local integer level
            local real x = GetUnitX(this.dummy)
            local real y = GetUnitY(this.dummy)
            local real dx = GetUnitX(this.killer) - x
            local real dy = GetUnitY(this.killer) - y
            local real a
            local real height
            local real dist = SquareRoot(dx * dx + dy * dy)
            
            if dist <= 50.0 then
                set level = GetUnitAbilityLevel(this.killer, DUMABILID)
                if level < GetMaxSoul(GetUnitAbilityLevel(this.killer, ABILID)) + 1 then
                    call UnitRemoveAbility(this.killer, DUMABILID)
                    call UnitAddAbility(this.killer, DUMABILID)
                    call SetUnitAbilityLevel(this.killer, DUMABILID, level + 1)
                    call setDamage(this.killer)
                endif
                call DestroyEffect(AddSpecialEffectTarget(DEATHART, this.killer, DEATHARTPOINT))
                call RemoveUnit(this.dummy)
                call this.stopPeriodic()
                call this.deallocate()
            else
                set a = Atan2(dy, dx)
                call SetUnitX(this.dummy, x + TRUESPEED * Cos(a))
                call SetUnitY(this.dummy, y + TRUESPEED * Sin(a))
                set height = GetUnitFlyHeight(this.dummy)
                call SetUnitFlyHeight(this.dummy, height + ((GetUnitFlyHeight(this.killer) + 100) - height) / (dist / TRUESPEED), 0)
            endif
        endmethod
        implement T32x
    
        private static method actions takes nothing returns boolean
            local thistype this
            local unit u = GetTriggerUnit()
            local unit killer = GetKillingUnit()
            local integer ulevel = GetUnitAbilityLevel(u, ABILID)
            local integer klevel = GetUnitAbilityLevel(killer, ABILID)
            local integer i
            local real x
            local real y
            
            if ulevel > 0 then
                set i = R2I((GetUnitAbilityLevel(u, DUMABILID) - 1) * GetSoulLost(ulevel))
                call UnitRemoveAbility(u, DUMABILID)
                call UnitAddAbility(u, DUMABILID)
                call SetUnitAbilityLevel(u, DUMABILID, i + 1)
                call thistype.setDamage(u)
            elseif klevel > 0 then
                set this = this.allocate()
                set x = GetUnitX(u)
                set y = GetUnitY(u)
                set this.killer = killer
                set this.dummy = CreateUnit(Player(13), DUMMYID, x, y, Atan2(GetUnitY(this.killer) - y, GetUnitX(this.killer) - x) * bj_RADTODEG)
                
                call this.startPeriodic()
            endif
            set u = null
            set killer = null
            return false
        endmethod
    
        private static method learn takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local integer i
            
            if GetLearnedSkill() == ABILID and GetUnitAbilityLevel(u, DUMABILID) == 0 then
                call UnitAddAbility(u, DUMABILID)
                
                set i = 0
                loop
                    exitwhen i > 4
                    call UnitAddAbility(u, DAMAGEID[i])
                    set i = i + 1
                endloop
            endif
            set u = null
            return false
        endmethod
        
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.actions))
            set t = null
            
            set t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
            call TriggerAddCondition(t, Condition(function thistype.learn))
            set t = null
        endmethod
    endstruct
    
    endscope


    Presence of the Dark Lord

    Description:
    The presence of such a horrible creature terrifies nearby enemies, reducing their armor.

    Level 1 - 2 armor reduction.
    Level 2 - 3 armor reduction.
    Level 3 - 4 armor reduction.
    Level 4 - 5 armor reduction.

    Passive

    Screenshot:
    [​IMG]


    Requiem of Souls

    Description:
    Summons evil spirits around you dealing damage to units in the area. Number of spirits is related to the number of souls stored and the movement/damage reduction is related to the distance from the Shadow Fiend. Lowers movement speed and damage of nearby units. The closer the units are the greater the effect. Reduction lasts 5 seconds.

    Level 1 - 80 damage for each line, 15% reduction.
    Level 2 - 120 damage for each line, 20% reduction.
    Level 3 - 160 damage for each line, 25% reduction.

    Cast Range: Self
    Target Type: Instant
    Cast Time: 1 second
    Cooldown: 120/110/100 seconds

    Note: I believe DoTA actually uses multiple carrion swarms for Requiem of Souls. However, for configuration purposes and better visual effects, I did not.

    Screenshot:
    [​IMG]

    Code:
    JASS:
    
    scope RequiemOfSouls // requires Timer32, GroupUtils
    
    //===========================================================================
    //                           CONFIGURABLES                        
    //===========================================================================
    
    globals
        private constant integer ABILID = 'ABRS' // raw code of ability "Requiem of Souls"
        private constant integer DUMABILID = 'ARS0' // raw code of ability "Requiem of Souls (Reduction)"
        private constant integer DUMMYID = 'rOSD' // raw code of unit "Requiem of Souls Dummy"
        private constant integer CASTERID = 'cAST' // raw code of unit "Caster Dummy"
        
        private constant integer SOULCOUNT = 2 // number of souls required to create a "line"
        private constant real SOULAOE = 150.0 // area of effect of each "line"
        private constant real SPEED = 1000.0 // distance travelled by "line" per second
        private constant real TRUESPEED = SPEED * T32_PERIOD // distance travelled by "line" per period
        
        private constant real REDUCTIONAOE = 675.0 // area of effect where units will be affected by damage and move speed reduction
        
        private constant real INTERVAL = 200.0 // distance interval where effect is spawned
        private constant string EFFECT = "Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl" // effect spawned every interval
        
        private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type of damage
        private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type of damage
        private constant weapontype WEP = WEAPON_TYPE_WHOKNOWS // weapon type of damage
    endglobals
    
    private function GetDamage takes integer level returns real
        return 40.0 + (40.0 * level) // damage dealt per line of soul
    endfunction
    
    private function GetArea takes integer level returns real
        return 1350.0 + (25.0 * level) // area of effect
    endfunction
    
    //===========================================================================
    //                          END CONFIGURABLES                        
    //===========================================================================
    
    native UnitAlive takes unit id returns boolean
    
    private struct Data
        unit caster
        unit dummy
        group damagedgroup
        real damage
        real dist
        real angle
        real interval = INTERVAL
        static thistype tempData
        static unit tempUnit
        
        private static method reductionFilter takes nothing returns boolean
            local unit u = GetFilterUnit()
            
            if IsUnitEnemy(u, GetOwningPlayer(tempUnit)) and UnitAlive(u) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
                call IssueTargetOrder(tempUnit, "cripple", u)
            endif
            set u = null
            return false
        endmethod
        
        private static method filterFunc takes nothing returns boolean
            local thistype this = tempData
            local unit u = GetFilterUnit()
            
            if IsUnitEnemy(u, GetOwningPlayer(this.caster)) and UnitAlive(u) and not IsUnitInGroup(u, this.damagedgroup) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
                call UnitDamageTarget(this.caster, u, this.damage, true, false, ATK, DMG, WEP)
                call GroupAddUnit(this.damagedgroup, u)
            endif
            set u = null
            return false
        endmethod
        
        private method periodic takes nothing returns nothing
            local real x = GetUnitX(this.dummy)
            local real y = GetUnitY(this.dummy)
            
            if this.dist <= 0 then
                call DestroyEffect(AddSpecialEffect(EFFECT, x, y))
                call RemoveUnit(this.dummy)
                call ReleaseGroup(this.damagedgroup)
                call this.stopPeriodic()
                call this.deallocate()
            else
                if this.interval <= 0 then
                    call DestroyEffect(AddSpecialEffect(EFFECT, x, y))
                    set this.interval = INTERVAL
                else
                    set this.interval = this.interval - TRUESPEED
                endif
                call SetUnitPosition(this.dummy, x + TRUESPEED * Cos(this.angle), y + TRUESPEED * Sin(this.angle))
                set tempData = this
                call GroupEnumUnitsInArea(ENUM_GROUP, x, y, SOULAOE, Filter(function thistype.filterFunc))
                set this.dist = this.dist - TRUESPEED
            endif
        endmethod
        implement T32x
        
        private static method actions takes nothing returns boolean
            local thistype this
            local unit u
            local integer level
            local integer i
            local real angle
            local real anglerate
            local real x
            local real y
        
            if GetSpellAbilityId() == ABILID then
                set u = GetTriggerUnit()
                set level = GetUnitAbilityLevel(u, ABILID)
                set i = (GetUnitAbilityLevel(u, Necromastery_DUMABILID) - 1) / SOULCOUNT
                set angle = 0
                if i != 0 then
                    set anglerate = (2 * bj_PI) / i
                endif
                set x = GetUnitX(u)
                set y = GetUnitY(u)
                
                loop
                    exitwhen i == 0
                    set this = thistype.allocate()
                    set this.caster = u
                    set this.damagedgroup = NewGroup()
                    set this.damage = GetDamage(level)
                    set this.dist = GetArea(level)
                    set this.angle = angle
                    set this.dummy = CreateUnit(GetOwningPlayer(this.caster), DUMMYID, x, y, angle)
                    
                    call this.startPeriodic()
                    set angle = angle + anglerate
                    set i = i - 1
                endloop
                
                set tempUnit = CreateUnit(GetOwningPlayer(u), CASTERID, x, y, 0)
                call UnitAddAbility(tempUnit, DUMABILID)
                call SetUnitAbilityLevel(tempUnit, DUMABILID, level)
                call GroupEnumUnitsInArea(ENUM_GROUP, x, y, REDUCTIONAOE, Filter(function thistype.reductionFilter))
                call RemoveUnit(tempUnit)
            endif
            set u = null
            return false
        endmethod
    
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function thistype.actions))
            set t = null
        endmethod
    endstruct
    
    endscope


    Credits
    Code:
    Jesus4Lyf - [URL="http://www.thehelper.net/forums/showthread.php/132538-Timer32?highlight=Timer32"]Timer32[/URL]
    Rising_Dusk - [URL="http://www.wc3c.net/showthread.php?t=104464"]GroupUtils[/URL]
    

    Changelogs
    Code:
    Version 1.0
    - Initial relase
    Version 1.1
    - Optimized code
    - Made Attack Type, Weapon Type and Damage Type configurable for Shadowraze and Requiem of Souls
    Version 1.2
    - Rewrote codes using Timer32 and GroupUtils, instead of KT2 and Recycle
    
    Feedback will be appreciated.
     

    Attached Files:

  2. BlackRose

    BlackRose Forum User

    Ratings:
    +239 / 0 / -0
    Shadowraze
    • I like how you name the variables relative to their hotkey in DotA. It's easy for people to modify.
    1. In the Learn function, variable u should be set after the if GetLearnedSkill() == ABILID then. Why? Incase the learned skill was not ABILID, then you save one GetTriggerUnit call.
    2. In the Actions function, variable a can be set as a = GetUnitFacing( u ) * bj_DEGTORAD to save one multiplication.
    3. In the GroupFunc function, you should make the attacktype, damagetype, and weapontypes configurable at the top.
     
  3. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Thanks for the feedback. Will make the necessary changes.

    EDIT
    Done.
     
  4. BlackRose

    BlackRose Forum User

    Ratings:
    +239 / 0 / -0
    Doesn't DotA use purge for Requiem of Souls?

    (By the way, it's DotA: Defence of the Ancients, not DoTA: Defence of The Ancients.)
     
  5. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    They use Purge? But Purge doesn't decrease attack damage o.o
     
  6. BlackRose

    BlackRose Forum User

    Ratings:
    +239 / 0 / -0
    I was wrong, I checked myself, it's all Cripple. Thinking from memory, I thought it used Purge :p

    Does your Requiem of Souls follow this though: The closer the units are the greater the effect.? The Cripple that is, I noticed DotA uses three Cripple abilities: "Far", "Moderate", and "Close".
     
  7. jrhetf4xb

    jrhetf4xb Member

    Ratings:
    +12 / 0 / -0
    nvm, misread
     
  8. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Well, nope. I guess I should do that though. Lol.
     
  9. Sim

    Sim Forum Administrator Staff Member

    Ratings:
    +531 / 0 / -0
    Is it done now? :p
     
  10. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Yep. Rewrote the code with Timer32 too. Will upload it soon. Need to get some sleep first @_@
     
  11. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Updated to version 1.2

    Code:
    [B]Version 1.2[/B]
    - Rewrote codes using Timer32 and GroupUtils, instead of KT2 and Recycle
    
     
  12. Sevion

    Sevion The DIY Ninja

    Ratings:
    +423 / 0 / -0
    Weird. I thought I posted this yesterday. Anyways. I think Recycle would be a better system to use than GroupUtils. Less overhead.
     
  13. chobibo

    chobibo Level 1 Crypt Lord

    Ratings:
    +48 / 0 / -0
    You did. Dunno why it's not there anymore though.
     
  14. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    You did, in a different thread. :p
     
  15. Ayanami

    Ayanami 칼리

    Ratings:
    +287 / 0 / -0
    Hmm, well GroupUtils does have that GroupEnumUnitsInArea function, so just might as well use it.
     
  16. Sevion

    Sevion The DIY Ninja

    Ratings:
    +423 / 0 / -0
    Oh, hey I did :D

    If you need the function you could always just write it in there :-/
     
  17. tooltiperror

    tooltiperror Super Moderator Staff Member

    Ratings:
    +233 / 0 / -0
    Why are you even using groups? I thought dynamic groups were considered bad now.

    >It is MUI, meaning can be cast many times at the same instance
    8190 to be precise.

    >function GetMaxSoul
    That could be I2R(R2I(- 0.333 * level * level * level + 2.5 * level * level + 1.75 * level + 4.083)) and comment in the values. The I2R/R2I should round it up (untested).
     
  18. tooltiperror

    tooltiperror Super Moderator Staff Member

    Ratings:
    +233 / 0 / -0
    GetMaxSoul change would probably slow down for more than it's worth.

    Approved.
     
  19. super_nova

    super_nova Member

    Ratings:
    +0 / 0 / -0
    Excuse me, i want to ask some question
    I'm trying to copy the necromastery skill you made here, and modify its name
    But it doesnt work and error when i save it to my map, i did what you said to copy step by step...
    Can you help me?
    lorokabeh.jpg
    I dont know how to upload a picture, so i just attach it..
     

Share This Page