Spell Energy Field

Dinowc

don't expect anything, prepare for everything
Reaction score
223
Energy Field
+
Hellfire Ritual
v2.0

I got inspired by HoN's Energy Field and decided to make a Wc3 version of it (although I actually never played HoN, I've made the spell based on it's description xd).

It's:

-MUI
-Lagless (unless you spam)
-Leakless (I think, hard to find any leaks in such huge code :nuts:)
-Relatively easy configurable

this is the original description, but for the testing purposes, the cooldown, mana cost and cast time are set to 0
Deploying his patented Energy Field Double-Magnetic Modulator v3.0, the Engineer can guarantee that any enemies who enter or exit the active field are purged of all buffs and then silenced and perplexed for a short time.
Takes 5 hits to destroy the gadget.

Type: Magic
Radius: 475
Cast Time: 1.0 Seconds
Mana Cost: 200
Cooldown: 90.0 / 75.0 / 60.0 Seconds
Required Level: 6 / 11 / 16

Level 1 - Lasts 6 seconds, deals 3% of unit's max hp in damage.
Level 2 - Lasts 9 seconds, deals 5% of unit's max hp in damage.
Level 3 - Lasts 12 seconds, deals 7% of unit's max hp in damage.

Code (prepare to get thumped):
JASS:
scope field initializer init

// Energy Field v2.0, by Dinowc
//        Credits to HoN

// Requirements:
// NewGen, Timer Utils, Group Utils, AIDS, dummy.mdx (everything included in map)

//How to import:
// Simply create a new trigger, convert it to custom text and replace everything with this code bellow. There are 3 abilities, 1 that casts the EF itself and other 2 are dummy abilities (Purge, Soul Burn). You can find them in Object editor.

//Configurables
globals
    private constant integer SPELL_ID = 'A000'
    private constant integer DUMMY_SPELL_1_ID = 'A001' // this is default for purge
    private constant integer DUMMY_SPELL_2_ID = 'A002' // this is default for soul burn
    private constant string DUMMY_SPELL_1_ORDER = "purge"
    private constant string DUMMY_SPELL_2_ORDER = "soulburn"
    private constant integer DUMMY_CASTER = 'h002' // the dummy that casts Purge/Soul Burn
    private constant integer GADGET_DUMMY = 'h004' // self explanatory
    private constant integer TURRET_DUMMY = 'h001' // same as above
    private constant real TURRET_FACING = 180. // 180. degrees will make the turret face the gadget
    private constant integer ARRAY_SIZE = 200
    private constant real INTERVAL = 0.05 // make it a multiplier of 1
    
    //Lightning Settings
    private constant string LIGHTNING_EFFECT = "CLSB" // since Wc3 doesn't have any pretty lightning effects and I do not want to use imports, I've decided to use this one
    private constant real LIGHTNING_HEIGHT_BASE = 10.
    private constant real LIGHTNING_HEIGHT_INCREMENT = 40.
    private constant integer LIGHTNING_ROWS = 3
    private constant boolean LIGHTNING_DIRECTION = true // true for left, false for right
    private constant boolean VISIBILITY_CHECK = true // I'm not sure what this means, but I left it at true xd
    
    //Energy Field Settings
    private constant real GADGET_OFFSET = 120. // distance between the caster and the gadget
    private constant real BOUNDS_SIZE = 50. // // distance between the lightning and entering unit before he get's damaged; it's not really accurate since the field is Xangled, not round
    private constant real TREE_CUT_AOE = 130. // AOE around turret where the destructables are destroyed
    private constant real BASE_DAMAGE = 0.03 // in percent
    private constant real DAMAGE_PER_LEVEL = 0.02 // in percent
    private constant integer TURRET_COUNT = 8 // less than 3 and more than 20 is not really recommended
    private constant real BASE_DURATION = 6.
    private constant real DURATION_PER_LEVEL = 3.
    private constant real BASE_AOE = 475.
    private constant real AOE_PER_LEVEL = 0.
    private constant integer BASE_HITS = 5
    private constant integer HITS_PER_LEVEL = 0
    private constant string BUILD_EFFECT = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl" // the effect that appears when you create the gadget, set to "" to display no effect (reduces lag)
    private constant string TURRET_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" // the effect that appears on turrets (obelisks), set to "" to display no effect (reduces lag)
    
    private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
    private constant string DAMAGE_EFFECT_ATTACH = "chest"
    private constant string PERIODIC_DAMAGE_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
    private constant string PERIODIC_DAMAGE_EFFECT_ATTACH = "origin"
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
    
    private constant boolean TURRET_COLLISION = true //if turret has collision
endglobals

//Don't touch
globals
    private rect R
    private rect TestRect
    private unit DUMMY
    private group G = CreateGroup()
    private trigger Tr = CreateTrigger()
    private real RADIANS = 0.0174
endglobals

private function PolarX takes real dist, real angle returns real
    return dist * Cos(angle * RADIANS)
endfunction

private function PolarY takes real dist, real angle returns real
    return dist * Sin(angle * RADIANS)
endfunction

private function distance takes real x1, real y1, real x2, real y2 returns real
    local real dx = x2 - x1
    local real dy = y2 - y1
    return SquareRoot(dx * dx + dy * dy)
endfunction

private function LevelIncrease takes real a, real b, integer level returns real
    return a + ((I2R(level - 1)) * b)
endfunction

private function GroupClean takes nothing returns nothing
    local unit picked = GetEnumUnit()
    local real x = GetUnitX(picked)
    local real y = GetUnitY(picked)
    
    call SetTerrainPathable(x, y, PATHING_TYPE_WALKABILITY, true)
    call KillUnit(picked)
    
    set picked = null
endfunction

private function destructableFilter takes nothing returns boolean
    local destructable d = GetFilterDestructable()
    
    if GetDestructableLife(d) > 0 then
        call KillDestructable(d)
    endif
    
    set d = null
    return false
endfunction

private function damage takes unit target, real amount returns real
    return GetUnitState(target, UNIT_STATE_MAX_LIFE) * amount
endfunction

private struct data
    unit caster
    unit gadget
    
    lightning array sfx[ARRAY_SIZE]
    integer index
    
    group g
    group g2
    
    real damagePercent
    real duration
    real ticks
    integer hits
    
    timer t
    
    static data D
    
    static method AddUnits takes nothing returns boolean
        local unit picked = GetFilterUnit()
        local player p = GetOwningPlayer(D.caster)

        if IsUnitEnemy(picked, p) == true and IsUnitInGroup(picked, D.g2) == false and IsUnitType(picked, UNIT_TYPE_DEAD) == false and GetUnitTypeId(picked) != GADGET_DUMMY and IsUnitType(picked, UNIT_TYPE_STRUCTURE) == false then
            call GroupAddUnit(D.g2, picked)
        endif
        
        set picked = null
        set p = null
        return false
    endmethod
    
    static method create takes unit whichUnit, real x, real y returns data
        local data d = data.allocate()
        local player p = GetOwningPlayer(whichUnit)
        local real angle = GetUnitFacing(whichUnit)
        local real x1 = x + PolarX(GADGET_OFFSET, angle)
        local real y1 = y + PolarY(GADGET_OFFSET, angle)
        local real x2
        local real y2
        local real angleInc = 360. / TURRET_COUNT
        local integer i = 0
        local integer level = GetUnitAbilityLevel(whichUnit, SPELL_ID)
        local real AOE = LevelIncrease(BASE_AOE, AOE_PER_LEVEL, level)
        local unit dummy
        local unit turret
        local real height1
        local real height2
        local location l
        local integer a = 0
        local real z1
        local real z2
        
        set d.caster = whichUnit
        set d.damagePercent = LevelIncrease(BASE_DAMAGE, DAMAGE_PER_LEVEL, level)
        set d.duration = LevelIncrease(BASE_DURATION, DURATION_PER_LEVEL, level)
        
        call MoveRectTo(R, x1, y1)
        call EnumDestructablesInRect(R, Filter(function destructableFilter), null)
        
        if BUILD_EFFECT != "" then
            set dummy = CreateUnit(p, DUMMY_CASTER, x1, y1, angle) // this dummy is used only as an effect for more eye candy, it's ok if you delete these 3 lines to reduce lag
            call DestroyEffect(AddSpecialEffectTarget(BUILD_EFFECT, dummy, "origin"))
            call KillUnit(dummy)
        endif
        
        set d.gadget = CreateUnit(p, GADGET_DUMMY, x1, y1, angle)
        set d.g = NewGroup()
        set d.g2 = NewGroup()
        
        set x = GetUnitX(d.gadget)
        set y = GetUnitY(d.gadget)
        
        loop
            set x1 = x + PolarX(AOE, angle)
            set y1 = y + PolarY(AOE, angle)
            
            call MoveRectTo(R, x1, y1)
            call EnumDestructablesInRect(R, Filter(function destructableFilter), null)
            
            if TURRET_EFFECT != "" then
                set dummy = CreateUnit(p, DUMMY_CASTER, x1, y1, angle) // this dummy is used only as an effect for more eye candy, it's ok if you delete these 3 lines to reduce lag
                call DestroyEffect(AddSpecialEffectTarget(TURRET_EFFECT, dummy, "origin"))
                call KillUnit(dummy)
            endif
            
            set turret = CreateUnit(p, TURRET_DUMMY, x1, y1, angle + TURRET_FACING)
            
            if TURRET_COLLISION then
                call SetTerrainPathable(x1, y1, PATHING_TYPE_WALKABILITY, false)
            endif
            
            call GroupAddUnit(d.g, turret)
            
            set l = Location(x1, y1)
            set height1 = GetLocationZ(l)
            call RemoveLocation(l)
            
            set x2 = x + PolarX(AOE, angle + angleInc)
            set y2 = y + PolarY(AOE, angle + angleInc)
            
            set l = Location(x2, y2)
            set height2 = GetLocationZ(l)
            call RemoveLocation(l)
            
            loop
                set z1 = (LIGHTNING_HEIGHT_BASE + a * LIGHTNING_HEIGHT_INCREMENT) + height1
                set z2 = (LIGHTNING_HEIGHT_BASE + a * LIGHTNING_HEIGHT_INCREMENT) + height2
                
                static if LIGHTNING_DIRECTION then
                    set d.sfx[d.index] = AddLightningEx(LIGHTNING_EFFECT, VISIBILITY_CHECK, x1, y1, z1, x2, y2, z2)
                    set d.index = d.index + 1
                else 
                    set d.sfx[d.index] = AddLightningEx(LIGHTNING_EFFECT, VISIBILITY_CHECK, x2, y2, z1, x1, y1, z2)
                    set d.index = d.index + 1
                endif
                
                set a = a + 1
                exitwhen a >= LIGHTNING_ROWS
            endloop
            
            set a = 0
            
            set angle = angle + angleInc
            set i = i + 1
            
            exitwhen i >= TURRET_COUNT
        endloop
        
        set D = d
        call GroupEnumUnitsInRange(G, x, y, AOE - BOUNDS_SIZE, Filter(function data.AddUnits))
        call TriggerRegisterUnitEvent(Tr, d.gadget, EVENT_UNIT_DAMAGED)
        
        set d.ticks = 0.
        set d.hits = 0
        set d.t = NewTimer()
        
        set turret = null
        set dummy = null
        set p = null
        set l = null
        return d
    endmethod
    
    static method damageExiters takes nothing returns boolean
        local unit picked = GetFilterUnit()
        local player p = GetOwningPlayer(D.caster)
        local real x = GetUnitX(picked)
        local real y = GetUnitY(picked)
        local real dist = distance(x, y, GetUnitX(D.gadget), GetUnitY(D.gadget))
        local integer level = GetUnitAbilityLevel(D.caster, SPELL_ID)
        local real AOE = LevelIncrease(BASE_AOE, AOE_PER_LEVEL, level)
        
        if IsUnitEnemy(picked, p) == true and IsUnitInGroup(picked, D.g2) == true and IsUnitType(picked, UNIT_TYPE_DEAD) == false and IsUnitType(picked, UNIT_TYPE_MAGIC_IMMUNE) == false and GetUnitTypeId(picked) != GADGET_DUMMY and IsUnitType(picked, UNIT_TYPE_STRUCTURE) == false and dist + BOUNDS_SIZE > AOE then
            call SetUnitOwner(DUMMY, p, false)
            call SetUnitX(DUMMY, x)
            call SetUnitY(DUMMY, y)
            
            call SetUnitAbilityLevel(DUMMY, DUMMY_SPELL_1_ID, level)
            call SetUnitAbilityLevel(DUMMY, DUMMY_SPELL_2_ID, level)
            call IssueTargetOrder(DUMMY, DUMMY_SPELL_1_ORDER, picked)
            call IssueTargetOrder(DUMMY, DUMMY_SPELL_2_ORDER, picked)
            call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACH))
            
            call GroupRemoveUnit(D.g2, picked)
        endif
    
        set picked = null
        set p = null
        return false
    endmethod
    
    static method filterFunc takes nothing returns boolean
        local unit picked = GetFilterUnit()
        local player p = GetOwningPlayer(D.caster)
        local integer level
        
        if IsUnitEnemy(picked, p) == true and IsUnitType(picked, UNIT_TYPE_DEAD) == false and IsUnitType(picked, UNIT_TYPE_MAGIC_IMMUNE) == false and GetUnitTypeId(picked) != GADGET_DUMMY and IsUnitType(picked, UNIT_TYPE_STRUCTURE) == false then
            if IsUnitInGroup(picked, D.g2) == false then
                set level = GetUnitAbilityLevel(D.caster, SPELL_ID)
                
                call SetUnitOwner(DUMMY, p, false)
                call SetUnitX(DUMMY, GetUnitX(picked))
                call SetUnitY(DUMMY, GetUnitY(picked))
                
                call SetUnitAbilityLevel(DUMMY, DUMMY_SPELL_1_ID, level)
                call SetUnitAbilityLevel(DUMMY, DUMMY_SPELL_2_ID, level)
                call IssueTargetOrder(DUMMY, DUMMY_SPELL_1_ORDER, picked)
                call IssueTargetOrder(DUMMY, DUMMY_SPELL_2_ORDER, picked)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, picked, DAMAGE_EFFECT_ATTACH))
                
                call GroupAddUnit(D.g2, picked)
            endif
            
            if ModuloReal(D.ticks, 1) == 1 then
                call UnitDamageTarget(D.caster, picked, damage(picked, D.damagePercent), false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
                if TURRET_EFFECT != "" then
                    call DestroyEffect(AddSpecialEffectTarget(PERIODIC_DAMAGE_EFFECT, picked, PERIODIC_DAMAGE_EFFECT_ATTACH))
                endif
            endif
        endif
    
        set p = null
        set picked = null
        return false
    endmethod
    
    private method onDestroy takes nothing returns nothing
        local integer a = 0
        
        call ForGroup(.g, function GroupClean)
        call ReleaseGroup(.g)
        
        loop
            call DestroyLightning(.sfx[a])
            set .sfx[a] = null
            set a = a + 1
            exitwhen a > .index
        endloop
        set .index = 0
        
        call ReleaseGroup(.g2)
        call KillUnit(.gadget)
        call ReleaseTimer(.t)
    endmethod
endstruct

globals
    private data array STORE
endglobals

private function callback takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local data d = GetTimerData(t)
    local integer a = 0
    local real AOE = LevelIncrease(BASE_AOE, AOE_PER_LEVEL, (GetUnitAbilityLevel(d.caster, SPELL_ID)))
    set d.ticks = d.ticks + INTERVAL
    
    if d.ticks >= d.duration then
        call d.destroy()
    else
        set data.D = d
        call GroupEnumUnitsInRange(G, GetUnitX(d.gadget), GetUnitY(d.gadget), AOE - BOUNDS_SIZE, function data.filterFunc)
        call GroupEnumUnitsInRange(G, GetUnitX(d.gadget), GetUnitY(d.gadget), AOE + BOUNDS_SIZE, function data.damageExiters)
    endif
    
    set t = null
endfunction

private function actions takes nothing returns boolean
    local unit caster
    local data d
    if GetSpellAbilityId() == SPELL_ID then
        set caster = GetTriggerUnit()
        set d = data.create(caster, GetUnitX(caster), GetUnitY(caster))
        set STORE[GetUnitIndex(d.gadget)] = d
        call SetTimerData(d.t, d)
        call TimerStart(d.t, INTERVAL, true, function callback)
        
        set caster = null
    endif
    return false
endfunction

private function act takes nothing returns boolean
    local unit attacked = GetTriggerUnit()
    local data d
    local integer a
    local integer HITS
    set d = STORE[GetUnitIndex(attacked)]
        
    if d != null then
        set HITS = BASE_HITS + ((GetUnitAbilityLevel(d.caster, SPELL_ID) - 1) * HITS_PER_LEVEL)
        set d.hits = d.hits + 1
        
        if d.hits >= HITS then
            call d.destroy()
        else
            set STORE[GetUnitIndex(attacked)] = d
        endif
    endif
    
    set attacked = null
    return false
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local real aoe = TREE_CUT_AOE / 2
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function actions))
    call TriggerAddCondition(Tr, Condition(function act))
    
    set R = Rect(-1 * aoe, -1 * aoe, aoe, aoe)
    set TestRect = Rect(-25., -25., 25, 25)
    
    //Preload
    call RemoveUnit(CreateUnit(Player(13), GADGET_DUMMY, 0., 0., 0.))
    call RemoveUnit(CreateUnit(Player(13), TURRET_DUMMY, 0., 0., 0.))
    set DUMMY = CreateUnit(Player(13), DUMMY_CASTER, 0., 0., 0.)
    
    set t = null
endfunction

endscope
Screenies:

23732090.jpg


after playing a bit with the configurables block (and minor code changes), I've made a spell called Hellfire Ritual
it's actually the same spell, just with different visuals, causes stun instead of purge/silence and it's a point target spell:

Opens a hole to hell itself and summons demons around it who begin a dark ritual. Any unit that enters or leaves the inner field will take damage and be stunned for 2 seconds. Units in the field burn with intense heat, taking damage.

Type: Magic
Radius: 475
Cast Time: 1.0 Seconds
Mana Cost: 200
Cooldown: 90.0 / 75.0 / 60.0 Seconds
Required Level: 6 / 11 / 16

Level 1 - Lasts 6 seconds, deals 3% of unit's max hp in damage, takes 4 hits to destroy the pit.
Level 2 - Lasts 9 seconds, deals 5% of unit's max hp in damage, takes 6 hits to destroy the pit.
Level 3 - Lasts 12 seconds, deals 7% of unit's max hp in damage, takes 8 hits to destroy the pit.
hellfireritual.jpg


it's to show you how editable this spell actually is

Changelog:
v2.0 - added a point target version of the spell (Hellfire Ritual); added some new configurables; code optimizations
v1.5 - fixed a major visual glitch when creating lightnings on different terrain heights
v1.4 - removed the usage of hashtable and replaced it with arrays instead; Purge and Soul burn effects can now be improved per Energy Field level by changing stats in Object Editor; made some code optimization; added a new configurable
v1.3b - removed some unnecessary lines of code; fixed a minor leak
v1.3 - further improved/optimized the code; the field no longer damages structures nor an enemy gadget; added Group Utils, making the field damage stackable (last thing that made it non-MUI removed); added some additional configurables
v1.2 - made a LOT of changes/improvements (code fixes and optimization, added unit indexing system, new configurables...)
v1.1 - some code fixes, the gadget is destroyed when hit exactly N times, not when attacked
v1.0 - initial post

Any comment appreciated :eek:
 

Attachments

  • Energy Field v2.0.w3x
    73.9 KB · Views: 548

Laiev

Hey Listen!!
Reaction score
188
Unconfigurate thing?
JASS:
if GetUnitTypeId(attacked) == 'h000' then



Also Why 90%? lol or is mui or don't

What make this spell -10% non-mui?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
1) Use GroupUtils/Recycle.
2) Remove Maths Function, use direct calculation in spell's scope.
3) ARRAY_SIZE, the readme for this is wrong. The lower the array size, the more the instances it can use. Set it to proper number is better for it.
4) Use DummyCaster instead of creating dummy massly.
5) Remove the usage of hashtable, use Unit Indexing/Table instead.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
Unconfigurate thing?

lol didn't see that

Also Why 90%? lol or is mui or don't

What make this spell -10% non-mui?

nothing will bug if you cast it multiple times at once, but if you create field inside another field the enemy wont get damaged by both fields (doesn't stack)

1) Use GroupUtils/Recycle.

dunno anything about that system (never used it)

2) Remove Maths Function, use direct calculation in spell's scope.

I made Math Functions myself and use it as a universal "system" for polar projections, distance counting, getting angles etc. in every spell

but I'll take your advice

3) ARRAY_SIZE, the readme for this is wrong. The lower the array size, the more the instances it can use. Set it to proper number is better for it.

true, but less the array size is, the higher chance that it will bug (some lightning effects wont get destroyed)

that's also the reason why I said 90% MUI (you can't really cast 20 times at once)

4) Use DummyCaster instead of creating dummy massly.

I am using a single dummy for casting Purge/Soul Burn, but the other dummies are created to show effects (you can't really do it with 1 single dummy)

5) Remove the usage of hashtable, use Unit Indexing/Table instead.

same as my first answer

EDIT: new version uploaded
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
bump

few dls and no comments

is the spell really that bad?
or the code is too ugly and inefficient?
or you just hate HoN?

:confused:
 

Laiev

Hey Listen!!
Reaction score
188
is the spell really that bad?
I don't think so, I like it :p

or the code is too ugly and inefficient?
Idk, I don't read all <no time to do this> :rolleyes:

or you just hate HoN?
I like HoN :)

Personal Comment: The idea is a bit original, most of guys come here and ask or make spell based on DotA, and you come and make based on HoN :p noone else has done one spell based on hon <no copy of dota, like the same heroes which hon got based on dota>, I like it :)
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
thanks for comment, it kinda motivated me :p

I think I may do some more HoN spells or finish the Engineer spellpack
 

Laiev

Hey Listen!!
Reaction score
188
very nice, Engineer is a very good and strategic hero, all the spells are a bit complex then others, example... the thirst skill has so much function based on the target, the first skill affect allies and enemies, but only deals damage to enemies and the second is really complex the calculate of the attack modifiers applied in that turret

OT: I make a hero based on hon too, the DeadWood, but is a bit different <obvious reason, I can't find a model to 'throw the tree'>
 

HeX.16

Isn't Trollin You Right Now
Reaction score
131
thanks for comment, it kinda motivated me :p

I think I may do some more HoN spells or finish the Engineer spellpack

This is a very late post (lil under a month) but i would love to see some more spells from HoN.
 

HeX.16

Isn't Trollin You Right Now
Reaction score
131
Hmmm i dont play HoN i have only seen some spells. From a short video.
xD So which ever you like or are easy to make. Also i added your paladin spells into my map, and gave credits in the quests =)
EDIT: Maybe make a HoN engineer Spellpack then i can add it in. Im very bad with coming up with spells.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
Hmmm i dont play HoN i have only seen some spells. From a short video.

90% of those spells are DotA's spells, just with different names

Energy Field isn't a DotA spell, so that's why I decided to make it
Maybe make a HoN engineer Spellpack then i can add it in. Im very bad with coming up with spells.

Energy Field is Engineer's ultimate, his other spells are pretty hard to make

I'll see what I can do about them when I get the time
 

HeX.16

Isn't Trollin You Right Now
Reaction score
131
I would rather not have you make the engineers spells.
I would like if you can make healing spells, summons and caster type spells. From the said hero types.
EDIT: Archer spells are also always cool.
 

Laiev

Hey Listen!!
Reaction score
188
Hex if you don't know what request, I suggest Electrician or Forsaken Archer or Zephyr, new spells, new concepts and a bit 'easy' :p
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
Use array/Table to store lightning instead of creating hashtable.
link?

what's wrong with hashtables anyway?

I avoid using arrays in structs since it causes the spell to bug quickly if casted multiple times at once (some lightning effects aren't destroyed since they are overwritten by next lightning)
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
what's wrong with hashtables anyway?
They have lame limit, 256. You will be doomed if your spells has a hashtable as storage.

I avoid using arrays in structs since it causes the spell to bug quickly if casted multiple times at once (some lightning effects aren't destroyed since they are overwritten by next lightning)
No... if you used it properly.

link?
http://www.wc3c.net/showthread.php?t=101246
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
No... if you used it properly.
ok...

I followed that link and I'm really stuck :confused:... I never used Table before and I don't know how to use it
 
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