Zephyr Contest #11 - My aura, Your aura

Status
Not open for further replies.

Tank-Commander

Spell Reviewer
Level 27
Joined
May 26, 2009
Messages
1,839
This spell is inspired from Torchlight II's shock effect. It works just like TankCommander's entry.

I hope not exactly "just like" XD

Edit: Though I can't help but notice, if the ability creates a summoned unit, is it not a summon unit spell, rather than an aura spell? (seeing as the hero does not have it, which is unlike all wc3 auras on a base level) granted yes the unit has an AOE effect (think of the ability tornado), but by that definition over half my submitted spells would count as auras

SallyAnna, Looking really great, nice and original
 
Last edited:
Level 24
Joined
Jun 5, 2008
Messages
2,572
The clarification of "aura" is vague. Basically any AoE ability can qualify if you follow strictly the given guidelines.

At least i read it as:
passive/active/toggle ability which affects enemies or allies.

Edit:

I am considering to join given the time.
Ideas so far:

Luminosity

A burning aura creates scorched ground around the bearer (random patches of ground (algorithm will favor positions closer to enemy units to prevent total uselessness)). Units afflicted take X damage per second and lose Y armor.
Active: Intensify - Burns the life force of the caster to intensify the flame. Burns up to 33/44/55% of current hp as additional flame over 5 seconds. Unit's caught in intense flame keep on burning after moving away from the ground for additional 2 seconds. Units that die under this effect create scorched ground.

Desparation

An aura of decay surrounds the bearer causing up to X nearby enemies to rapidly decay. Decaying enemies lose Y% of their max hp per Z seconds and move and attack slower.
Active: Pestilence - Grants control over the decaying units if their current hp is under a certain threshold. Units controlled still decay uncontrollably but will spread decay to nearby units upon death.

I really cannot decide, feel like both are solid ideas.
 
Can I add a second ability? basically my aura has one passive and one activate effect, I know it states passive/active/toggle but I want confirmation so I don't create something that isn't allowed.

• The ability can be followed by a maximum of one (1) sub-ability, but the latter must not be more effective and/or powerful than the super-ability.

At least one of the abilities has to be the aura. Of course, you could summon something with the main ability and activate/deactivate its aura with the sub-ability. There are many possibilities.
 

Kazeon

Hosted Project: EC
Level 30
Joined
Oct 12, 2011
Messages
3,439
I hope not exactly "just like" XD

Edit: Though I can't help but notice, if the ability creates a summoned unit, is it not a summon unit spell, rather than an aura spell? (seeing as the hero does not have it, which is unlike all wc3 auras on a base level) granted yes the unit has an AOE effect (think of the ability tornado), but by that definition over half my submitted spells would count as auras

SallyAnna, Looking really great, nice and original

it's still counted as "aura" I guess. Just like yours, but the aura ability is on the summoned unit for mine :)
 
Level 12
Joined
Jun 20, 2014
Messages
479
I hope not exactly "just like" XD

Edit: Though I can't help but notice, if the ability creates a summoned unit, is it not a summon unit spell, rather than an aura spell? (seeing as the hero does not have it, which is unlike all wc3 auras on a base level) granted yes the unit has an AOE effect (think of the ability tornado), but by that definition over half my submitted spells would count as auras

SallyAnna, Looking really great, nice and original

Thank you.
 

Kyrbi0

Arena Moderator
Level 35
Joined
Jul 29, 2008
Messages
8,739
I see a lot of questions about the exact meaning of "Aura" and how to interpret it.

Before getting too excited about shoving all sorts of alternate/sidelong/inverted/summon-type effects into your spell, though, consider that we already drastically broadened the definition of "Aura" for the purposes of this contest, to keep things from being too boring (i.e. if we went with what we all normally called Auras (Devotion/Brilliance/Unholy/Vampirism/Endurance/Trueshot/Thorns/Command/War Drums/etc), the scope of the contest would be way too tight). Widening the scope to include examples such as Big Bad Voodoo, Starfall, Locust Swarm, Immolation... There's lots of room there. Or at least there should be.
 
I'm thinkng of changing my aura to;

Gives nearby units 20% movement speed and 20% attack damage bonus. When enemy heroes drop below 40% near the caster, the aura also provides 20% lifesteal.

Does it sound OP? It's an ultimate btw. Are ultimate auras allowed? Just checking, if I would get minus points for it. Imo my auras are too OP for a normal three level ability.
 

Chaosy

Tutorial Reviewer
Level 38
Joined
Jun 9, 2011
Messages
13,060
Uniqueness How creatively was the ability executed? /10
Coding Is the skill bug- and leak-free? Does it support multiple instances? Is there any documentation and are there any configurable variables to fit the needs of any user? Does it cause performance issues upon effect? /20
Visuals How does the skill look? Is it overloaded with special effects? How explanatory is the tooltip/description of its functionality?

nope.
 
Luminosity

A burning aura creates scorched ground around the bearer (random patches of ground (algorithm will favor positions closer to enemy units to prevent total uselessness)). Units afflicted take X damage per second and lose Y armor.
Active: Intensify - Burns the life force of the caster to intensify the flame. Burns up to 33/44/55% of current hp as additional flame over 5 seconds. Unit's caught in intense flame keep on burning after moving away from the ground for additional 2 seconds. Units that die under this effect create scorched ground.

Desparation

An aura of decay surrounds the bearer causing up to X nearby enemies to rapidly decay. Decaying enemies lose Y% of their max hp per Z seconds and move and attack slower.
Active: Pestilence - Grants control over the decaying units if their current hp is under a certain threshold. Units controlled still decay uncontrollably but will spread decay to nearby units upon death.

I really cannot decide, feel like both are solid ideas.

Both concepts sounds good to me! I especially like the idea of Luminosity's active, that dying units again will create scorched ground.

In Desparation, you have a slower effect. Speed manipulation will be used more often in the contest, but that decay aspect is new.

I think both sounds good, but if you need help to decide me intuitively would prefer Luminosity. :)

good luck everyone
Yes, good luck to everyone!
 
Aura Changed. Tooltip:

Nearby allies gain movement speed and attack damage. When an enemy hero within 700 range of the Marshal drops below 40% health, such enemy is marked and the aura also grants lifesteal.

Statistics
Area of Effect: 600
Attack Damage Bonus: 25%
Lifesteal: 15%
Movement Bonus: 25%


Credits:
Credits

- JesusHipster (Kingstride Buff Model)
- Nudl9 (Kingstride Icon)

The Kingstride Aura itself is a material change from the Thorns Aura.

attachment.php
 

Attachments

  • Kingstride - Zephyr 11.w3x
    90.7 KB · Views: 38
  • Kingstride.png
    Kingstride.png
    1 MB · Views: 248
Level 23
Joined
Jul 10, 2006
Messages
3,315
I've left my spell a little bit too long, now it's no longer fresh in my mind. Might have to remake it.

I need to make my own movement detection anyhow. Well that was easy. Back to debugging!

Nice auras so far.

EDIT: Imported it into a melee map (attached), seems to work well. I've managed to fix it so that you can attack move with the aura and still have units retain the speed when the do that mini-pause when acquiring a target.
 

Attachments

  • (3)Forestwalk RM TEST.w3x
    221 KB · Views: 58
Last edited:

Deleted member 219079

D

Deleted member 219079

I will do something for UD Lich, I think he need his own aura :D

Guess I make something simple, winning is not my thing anyway lol...
 
Level 23
Joined
Jul 10, 2006
Messages
3,315
Rigorous March
Tooltip:
attachment.php

Screenie:
attachment.php

The footman on the left is dealing his charge damage.
The footman on the right hasn't run long enough to gain the charge effect.
The paladin is charging, and will deal bonus damage to the peasant above.

Specification:
  • GUI.
  • Uses unit custom value.
  • MUI - Works for multiple units having the aura. If a unit is under the effect of two auras, it will pick the highest level aura for effects.

Configurables, constant:
  • Loop time, level detect time, aura detect time (for performance ~/ smoothness)
  • Damage buff duration
  • SFX for top speed, damage
  • Scale speed - whether or not march speed is affected by slows
  • Scale damage - damage bonus based on marching speed

Configurables, level-variable:
  • Acceleration, top speed
  • Turn loss, turn window. When you turn around too sharply, speed is lost.
  • Aura range
  • Damage
  • Damage speed threshold - how fast you must go to deal damage

Requirements:
  • Unit indexing system

Conflicts/issues:
  • Knockback will be detected as unit movement. Add your own conditions to check for knockback.
  • Custom move systems (e.g. that system that allows a higher max speed) will probably conflict.
  • Starts getting wonky at very high movement speeds (~1000). Units naturally auto-correct around corners, which in this case will cause them to spin around like ballerinas.
  • Group speed auto-correct not yet implemented.
 

Attachments

  • RigorousMarch007.w3x
    47.7 KB · Views: 80
  • marchpreview.jpg
    marchpreview.jpg
    99.4 KB · Views: 521
  • tooltip.jpg
    tooltip.jpg
    53.6 KB · Views: 490
Last edited:
Indeed! That is why Orcs + Night Elves make a good 2v2 team :)

@ judge: I haven't seen any ruling explicitly allowing or disallowing the use of unit indexing systems. Are they allowed?

Any system is allowed, as I said, as long as it doesn't make most of the job for you. If minimal effort is invested, it's downgrading.
 
New Ability Idea

I'm thinking of changing my aura.
New Tooltip (State 1)
Aspect of Thunder
Active: Purges all nearby enemy units, removing all buffs from them and immobilizing them for 3 seconds. Deals 300 damage to summoned units.
Passive: Periodically hurls bolts of lightning at nearby enemy units dealing 25 damage.
Rick-click to empower the aura.
New Tooltip (State 2)
Aspect of Thunder
Active: Purges all nearby enemy units, removing all buffs from them and immobilizing them for 3 seconds. Deals 300 damage to summoned units.
Passive: Periodically hurls bolts of lightning at nearby enemy units dealing 25 damage.
Empowered: Bolts of lightning bounce to two additional targets, but drains 50 mana each time. Automatically unempowers when out of mana.
Rick-click to unempower the aura.
 

Deleted member 219079

D

Deleted member 219079

Don't worry. Tank Commander automatically wins so it's the same for all of us. :p
Lol :p

The Lich gains frosty accumulation onto his mana. Each hit on Lich himself or nearby allies causes infuriated accumulation of mana. Once the growth is enough, The Lich can release it once casting Frost Nova again.

Level 1 - Max 200 frosty and 100 fury, 20% of enemy attacks converted to fury
Level 2 - Max 400 frosty and 200 fury, 40% of enemy attacks converted to fury
Level 3 - Max 600 frosty and 300 fury, 60% of enemy attacks converted to fury

As I said, nothing special, it's something I can use myself for my future projects :) Frost Nova causes land to cover up in snow tiles for a while, then melting away. Haven't done that part yet, but beside that I'm doing fine.

Once I post the code and stuff, does it mean it's final submission, or can I edit it afterwards?

Edit: just realized 900 AoE damage is way too much, need a bit of rework on that ^^'
 
Once I post the code and stuff, does it mean it's final submission, or can I edit it afterwards?
You have time until the contest ends. And it's also a rule to show a WIP. So feel free to post your unfinished result.

In the end you should create a new post with your final entry.
The contest shall begin on 1st of July and conclude on 1st of August.
 
Level 12
Joined
Jun 20, 2014
Messages
479
hi, i chose a different model for my aura, have a look hehe.

can i ask, is it allowed if i add something like if the bearer of the aura's life or mana reaches certain amount something will happen? or if the bearer of the aura dies something will happen?
 

Attachments

  • new look.png
    new look.png
    515.2 KB · Views: 132
Will we be required to have a fitting icon/models for our auras? Required means not having it causes a loss of points.

It's part of the visuals actually (I know, its not explicitly stated, I should have included it), but no, it's almost pointless to care. I'd do it for the sake of harmony (especially if the ability was part of a skillset of 4, it would be easier to remember the effect of the spell by its icon). Imagine having a holy effect and an icon of two eyes in pitch black - no relation.
 
Official Work in Progress for Aspect of Thunder

So, at least try to get a good looking model/icon, but don't stress it? Got it. ~ Edit ~As lame of a work in progress post as it is, here is my work in progress post, map is attached. ~ Note ~I reference the aura's name as Aspect of Thunder or Aspect of Lightning as that was my original name for it. The final submission will all be using the same name.
 

Attachments

  • (Spell) Aspect of Lightning.w3x
    28.1 KB · Views: 49
Last edited:

Deleted member 219079

D

Deleted member 219079

You have time until the contest ends. And it's also a rule to show a WIP. So feel free to post your unfinished result.
Okay. Here's a WIP:
This resource uses vJASS syntax:
http://blizzardmodding.info/4263/the-jass-newgen-pack-jngp-2-0/

This resource uses PUI:
http://www.thehelper.net/threads/pui-perfect-unit-indexing.65470/

This resource uses TimerUtils:
http://www.wc3c.net/showthread.php?p=1020244

This resource uses Table:
http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/

This resource uses StructuredDD:
http://www.hiveworkshop.com/forums/...uctureddd-structured-damage-detection-216968/

Ability Chilling Aura:
JASS:
scope ChillingAura // v1.0.0 // requires PUI, TimerUtils, Table, StructuredDD, StillDummy, UnitTextTag
//===========================================================================

    // GLOBALS DECLARATION

//===========================================================================
    globals
        private constant integer MAX_TILE = 3
        private constant boolean USE_TEXTTAG = true
            private constant string TT_COLOR = "|c0000ffff"
            private constant string TT_COLOR_RAGE = "|c00ff3300"
        private constant integer ABILITY_ID = 'AHab'
        private constant real INTERVAL = 0.05 // alt. 0.03125
        private constant real AURA_INTERVAL = 0.5
        private constant real TICK = 2.
        private constant real FULL_TICK = 6.
        private constant player EFFECT_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
        private constant string EFFECT_HIT = "Abilities\\Spells\\Undead\\CarrionSwarm\\CarrionSwarmDamage.mdl"
        private constant string EFFECT_BUFF = "Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl"
        private constant string EFFECT_READY_ORIGIN = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
        private constant string EFFECT_READY_OVERHEAD = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
        private constant string EFFECT_MAX_1 = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
        private constant string EFFECT_MAX_2 = "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl"
        private constant string EFFECT_MAX_3 = "Abilities\\Spells\\Human\\Feedback\\SpellBreakerAttack.mdl"
        private effect array EFFECT
        private group SWITCH_GROUP
        private group TEMP_GROUP = CreateGroup()
    endglobals
//===========================================================================

    // USEFUL FUNCTIONS

//===========================================================================
    private constant function GetSmaller takes real r1, real r2 returns real
        if r1 < r2 then
            return r1
        endif
        return r2
    endfunction
    private constant function GetBigger takes real r1, real r2 returns real
        if r1 > r2 then
            return r1
        endif
        return r2
    endfunction
//===========================================================================

    // USEFUL STRUCTS

//===========================================================================
    private struct UnitScale extends array
        private real goal
        private real current
        private real speed
        private unit u
        private boolean active
        boolean flushOnFinish
        method flush takes nothing returns nothing
            set active = false
            set current = 1
            set goal = 1
            set u = null
        endmethod
        private static method onLoop takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype s = GetTimerData(t)
            if s.current < s.goal then
                set s.current = GetSmaller(s.current + s.speed, s.goal)
                call SetUnitScale(s.u, s.current, s.current, s.current)
            elseif s.current > s.goal then
                set s.current = GetBigger(s.current - s.speed, s.goal)
                call SetUnitScale(s.u, s.current, s.current, s.current)
            endif
            if s.current == s.goal then
                call ReleaseTimer(t)
                set s.active = false
                if s.flushOnFinish then
                    call s.flush()
                endif
            endif
            set t = null
        endmethod
        method setScale takes real r, real rate returns nothing
            local timer t
            set goal = r
            set speed = rate
            set flushOnFinish = false
            if u != GetIndexUnit(this) then
                set u = GetIndexUnit(this)
                set current = 1
            endif
            if not active then
                set active = true
                set t = NewTimer()
                call SetTimerData(t, this)
                call TimerStart(t, INTERVAL, true, function thistype.onLoop)
                set t = null
            endif
        endmethod
    endstruct
    private struct currentPool extends array
        readonly integer size
        readonly Table table
        method add takes integer which returns nothing
            if size == 0 then
                set table = Table.create()
                set size = 0
            endif
            set size = size + 1
            set table [size] = which
        endmethod
        method flush takes nothing returns nothing
            if size != 0 then
                set size = 0
                call table.destroy()
            endif
        endmethod
        private method flushIndex takes integer index returns nothing
            local integer i = size
            loop
                set i = i - 1
                set table [i] = table [i+1]
                exitwhen i == 1 or i == index
            endloop
            set size = size - 1
        endmethod
        method remove takes integer which returns nothing
            local integer i = 0
            loop
                set i = i + 1
                if table [i] == which then
                    if size > 1 then
                        call flushIndex(i)
                    else
                        set size = size - 1
                    endif
                    exitwhen true
                endif
                exitwhen i >= size
            endloop
            if size == 0 then
                call table.destroy()
            endif
        endmethod
    endstruct
//===========================================================================

    // EFFECT STRUCT

//===========================================================================
    private struct EffectReady
        private unit target
        private effect ef1
        private effect ef2
        boolean max
        method destroy takes nothing returns nothing
            call UnitScale[GetUnitIndex(target)].setScale(1,INTERVAL*2)
            set UnitScale[GetUnitIndex(target)].flushOnFinish = true
            call DestroyEffect(ef1)
            call DestroyEffect(ef2)
            if max then
                call Tile_RemoveProducer(target)
            endif
            set max = false
            set ef1 = null
            set ef2 = null
            set target = null
        endmethod
        static method create takes unit u returns thistype
            local thistype s = thistype.allocate()
            set s.target = u
            set s.max = false
            set s.ef1 = AddSpecialEffectTarget(EFFECT_READY_ORIGIN, u, "origin")
            set s.ef2 = AddSpecialEffectTarget(EFFECT_READY_OVERHEAD, u, "overhead")
            call UnitScale[GetUnitIndex(u)].setScale(1.4,INTERVAL)
            return s
        endmethod
        method stateMax takes Table tiles returns nothing
            local unit u = StillDummy_Create(EFFECT_OWNER, GetUnitX(target), GetUnitY(target), GetUnitFlyHeight(target), .8)
            set max = true
            call BJDebugMsg("asd")
            call SetUnitScale(u, 1.7, 1.7, 1.7)
            call DestroyEffect(AddSpecialEffectTarget(EFFECT_MAX_1, u, "origin"))
            call DestroyEffect(AddSpecialEffectTarget(EFFECT_MAX_2, u, "origin"))
            call DestroyEffect(AddSpecialEffectTarget(EFFECT_MAX_3, u, "origin"))
            call Tile_Spawn(GetUnitX(target),GetUnitY(target),tiles,MAX_TILE,400,5)
            call Tile_AddProducer(target, tiles, MAX_TILE, 250)
            call UnitScale[GetUnitIndex(target)].setScale(1.7,INTERVAL)
            set u = null
        endmethod
    endstruct
//===========================================================================

    // AURA STRUCT

//===========================================================================
    private struct Struct
            // member declaration
        private static Table tTable // tiles table
        private static TableArray vTable // value table
        private static thistype s
        private static thistype array current
        private static trigger array deathTrigger
        private integer level
        private EffectReady efR
        private trigger t
        private timer tick
        private timer aura
        static if USE_TEXTTAG then
            private real textCd
        endif
        private real step
        private real outPut
        private real rage
        private real rageMultiplier
        private real rageCap
        private real damageMin
        private real damage
        private real damagePerSecond
        private real damageMax
        private real damageAoE
        private real auraAoE
        private unit caster
        private group g
        private static method ungroupUnit takes unit u, thistype from returns nothing
            local integer i = GetUnitIndex(u)
            call currentPool[i].remove(from)
            if currentPool[i].size == 0 then
                call DestroyEffect(EFFECT[i])
                set EFFECT[i] = null
                call DestroyTrigger(deathTrigger[i])
                set deathTrigger[i] = null
            endif
        endmethod
        private static method clearGroupEnum takes nothing returns nothing
            call ungroupUnit(GetEnumUnit(), s)
        endmethod
        private method destroy takes nothing returns nothing
                // destroy method
            set current[GetUnitIndex(caster)] = 0
            set caster = null
            set s = this
            call ForGroup(g, function thistype.clearGroupEnum)
            call DestroyGroup(g)
            set g = null
            call ReleaseTimer(tick)
            set tick = null
            call ReleaseTimer(aura)
            set aura = null
            if efR != 0 then
                call efR.destroy()
                set efR = 0
            endif
            call DestroyTrigger(t)
            set t = null
        endmethod
        static if USE_TEXTTAG then
            private method displayRageText takes nothing returns nothing
                    // display text plus orange text
                set textCd = 1.
                call CreateTextTagUnit(caster, TT_COLOR+I2S(R2I(damage))+TT_COLOR_RAGE+" +"+I2S(R2I(rage)), TICK+0.5, 1.2, 0.8)
            endmethod
        endif
        private static method onAttack takes nothing returns nothing
                // attack event
            local integer i = 0
            local unit u = GetTriggerUnit()
            local unit u2
            local currentPool cp = currentPool[GetUnitUserData(u)]
            if cp.size > 0 and IsUnitEnemy(GetEventDamageSource(),GetOwningPlayer(u)) then
                loop
                    set i = i + 1
                    set s = cp.table [i]
                    set s.rage = GetSmaller(s.rage + GetEventDamage()*s.rageMultiplier, s.rageCap)
                    static if USE_TEXTTAG then
                        if s.textCd == 0 then
                            call s.displayRageText()
                        endif
                    endif
                    exitwhen i == cp.size
                endloop
                set u2 = StillDummy_Create(EFFECT_OWNER, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u), .8)
                call SetUnitScale(u2, 2, 2, 2)
                call DestroyEffect(AddSpecialEffectTarget(EFFECT_HIT, u2, "origin"))
                set u2 = null
            endif
            set u = null
        endmethod
        private static method auraFilter takes nothing returns boolean
                // valid aura targets
            return UnitAlive(GetFilterUnit()) and IsUnitAlly(GetFilterUnit(), GetOwningPlayer(s.caster)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)
        endmethod
        private static method onDeath takes nothing returns boolean
                // aura member death
            local unit u = GetTriggerUnit()
            call currentPool[GetUnitIndex(u)].flush()
            call DestroyEffect(EFFECT[GetUnitIndex(u)])
            set EFFECT[GetUnitIndex(u)] = null
            call DestroyTrigger(deathTrigger[GetUnitIndex(u)])
            set deathTrigger[GetUnitIndex(u)] = null
            set u = null
            return false
        endmethod
        private static method auraLoop takes nothing returns nothing
                // register units
            local group g = CreateGroup()
            local unit FoG
            set s = GetTimerData(GetExpiredTimer())
            call GroupEnumUnitsInRange(g, GetUnitX(s.caster), GetUnitY(s.caster), s.auraAoE, Filter(function thistype.auraFilter))
            loop
                set FoG = FirstOfGroup(s.g)
                exitwhen FoG == null
                if IsUnitInGroup(FoG, g) then
                    call GroupAddUnit(TEMP_GROUP, FoG)
                elseif UnitAlive(FoG) then
                    call ungroupUnit(FoG,s)
                endif
                call GroupRemoveUnit(s.g, FoG)
            endloop
            set SWITCH_GROUP = s.g
            set s.g = TEMP_GROUP
            set TEMP_GROUP = SWITCH_GROUP
            loop
                set FoG = FirstOfGroup(g)
                exitwhen FoG == null
                if not IsUnitInGroup(FoG, s.g) then
                    call GroupAddUnit(s.g, FoG)
                    call currentPool[GetUnitIndex(FoG)].add(s)
                    if EFFECT[GetUnitIndex(FoG)] == null and FoG != s.caster then
                        set EFFECT[GetUnitIndex(FoG)] = AddSpecialEffectTarget(EFFECT_BUFF, FoG, "origin")
                        set deathTrigger[GetUnitIndex(FoG)] = CreateTrigger()
                        call TriggerRegisterUnitEvent(deathTrigger[GetUnitIndex(FoG)], FoG, EVENT_UNIT_DEATH)
                        call TriggerRegisterUnitEvent(deathTrigger[GetUnitIndex(FoG)], FoG, EVENT_UNIT_DECAY)
                        call TriggerRegisterUnitEvent(deathTrigger[GetUnitIndex(FoG)], FoG, EVENT_UNIT_CHANGE_OWNER)
                        call TriggerAddCondition(deathTrigger[GetUnitIndex(FoG)], Condition(function thistype.onDeath))
                    endif
                endif
                call GroupRemoveUnit(g, FoG)
            endloop
            call DestroyGroup(g)
            set g = null
        endmethod
        private static method onLoop takes nothing returns nothing
                // spell loop
            set s = GetTimerData(GetExpiredTimer())
            static if USE_TEXTTAG then
                set s.textCd = GetBigger(s.textCd-INTERVAL, 0.)
            endif
            set s.step = s.step - INTERVAL
            if s.step <= 0. then
                set s.step = TICK
                if s.damage < s.damageMax then
                    set s.damage = GetSmaller(s.damage + s.damagePerSecond, s.damageMax)
                    if s.rage > 0 then
                        static if USE_TEXTTAG then
                            if s.textCd == 0 then
                                call s.displayRageText()
                            endif
                        endif
                    else
                        static if USE_TEXTTAG then
                            if s.textCd == 0 then
                                call CreateTextTagUnit(s.caster, TT_COLOR+I2S(R2I(s.damage)), TICK+0.5, 1.2, 0.8)
                                set s.textCd = 1
                            endif
                        endif
                    endif
                else
                    set s.step = FULL_TICK
                    static if USE_TEXTTAG then
                        if s.textCd == 0 then
                            call s.displayRageText()
                        endif
                    endif
                endif
                if Lich_EXTRA_DAMAGE[GetUnitIndex(s.caster)] != 0 then
                    // there is damage applied onto caster
                        // refresh the output value
                    set s.outPut = s.rage + s.damage
                    if s.outPut < s.damageMin then
                        set Lich_EXTRA_DAMAGE[GetUnitIndex(s.caster)] = 0
                        if s.efR != 0 then
                            call s.efR.destroy()
                            set s.efR = 0
                        endif
                    else
                        set Lich_EXTRA_DAMAGE[GetUnitIndex(s.caster)] = s.outPut
                        set Lich_EXTRA_DAMAGE_AOE[GetUnitIndex(s.caster)] = s.damageAoE
                        if s.damage == s.damageMax and not s.efR.max then
                            call s.efR.stateMax(tTable)
                        endif
                    endif
                endif
            endif
            if Lich_EXTRA_DAMAGE[GetUnitIndex(s.caster)] == 0 then
                    // there's no damage applied onto caster
                    if s.outPut == 0 then
                        // if there hasn't been any damage
                        if s.rage + s.damage >= s.damageMin then
                            set s.outPut = s.rage + s.damage
                            set Lich_EXTRA_DAMAGE[GetUnitIndex(s.caster)] = s.outPut
                            set Lich_EXTRA_DAMAGE_AOE[GetUnitIndex(s.caster)] = s.damageAoE
                            if s.efR == 0 then
                                set s.efR = EffectReady.create(s.caster)
                            endif
                        endif
                    else
                        // if there has been damage
                            // reduce the output amount from damage values
                        set s.rage = 0
                        set s.damage = 0
                        set s.outPut = 0
                            // remove possible effect applied
                        if s.efR != 0 then
                            call s.efR.destroy()
                            set s.efR = 0
                        endif
                    endif
                endif
        endmethod
        private method updateStats takes nothing returns nothing
                // update values
            set damagePerSecond   = vTable [1].real [level]
            set damageMax             = vTable [2].real [level]
            set auraAoE                    = vTable [3].real [level]
            set damageAoE              = vTable [4].real [level]
            set rageMultiplier          = vTable [5].real [level]
            set rageCap                    = vTable [6].real [level]
            set damageMin              = vTable [7].real [level]
        endmethod
        private static method casterDeath takes nothing returns boolean
            call current[GetUnitIndex(GetTriggerUnit())].destroy()
            return false
        endmethod
        private static method registerCaster takes unit u, integer i returns boolean
            if current[GetUnitIndex(u)] == 0 then
                set s = thistype.create()
                set Lich_EXTRA_DAMAGE[GetUnitIndex(u)] = 0
                set s.caster = u
                set s.level = i
                set s.outPut = 0
                set s.t = CreateTrigger()
                call TriggerRegisterUnitEvent(s.t, u, EVENT_UNIT_DEATH)
                call TriggerRegisterUnitEvent(s.t, u, EVENT_UNIT_CHANGE_OWNER)
                call TriggerRegisterUnitEvent(s.t, u, EVENT_UNIT_DECAY)
                call TriggerAddCondition(s.t, Condition(function thistype.casterDeath))
                set s.efR = 0
                set s.rage = 0
                static if USE_TEXTTAG then
                    set s.textCd = 0
                endif
                set s.g = CreateGroup()
                set current[GetUnitIndex(u)] = s
                set s.damage = vTable [0].real [i]
                call s.updateStats()
                set s.step = TICK
                set s.tick = NewTimer()
                set s.aura = NewTimer()
                call SetTimerData(s.tick, s)
                call SetTimerData(s.aura, s)
                call TimerStart(s.tick, INTERVAL, true, function thistype.onLoop)
                call TimerStart(s.aura, AURA_INTERVAL, true, function thistype.auraLoop)
                return true
            endif
            return false
        endmethod
        private static method onCast takes nothing returns boolean
                // spell learned / unit entered field
            local unit u = GetTriggerUnit()
            local integer i = GetUnitAbilityLevel(u, ABILITY_ID)
            call BJDebugMsg("asd")
            if i > 0 then
                if not registerCaster(u,i) and current[GetUnitIndex(u)].level != i then
                    set current[GetUnitIndex(u)].level = i
                    call current[GetUnitIndex(u)].updateStats()
                endif
            elseif current[GetUnitIndex(u)] != 0 then
                call current[GetUnitIndex(u)].destroy()
            endif
            set u = null
            return false
        endmethod
        private static method onInit takes nothing returns nothing
                // spell initialization
            local trigger t = CreateTrigger()
            set tTable = Table.create()
                // tiles
            set tTable [0] = 'Wsnw'
            set tTable [1] = 'Nsnw'
            set tTable [2] = 'Nsnr'
            set tTable [3] = 'Isnw'
            set vTable = TableArray [8]
                // index 0 = starting damage
            set vTable [0].real[1] = 20.
            set vTable [0].real[2] = 30.
            set vTable [0].real[3] = 40.
                // index 1 = damage per tick
            set vTable [1].real[1] = 4.
            set vTable [1].real[2] = 8.
            set vTable [1].real[3] = 12.
                // index 2 = max damage
            set vTable [2].real[1] = 200.
            set vTable [2].real[2] = 250.
            set vTable [2].real[3] = 300.
                // index 3 = aura AoE
            set vTable [3].real[1] = 800.
            set vTable [3].real[2] = 800.
            set vTable [3].real[3] = 800.
                // index 4 = damage AoE
            set vTable [4].real[1] = 250.
            set vTable [4].real[2] = 250.
            set vTable [4].real[3] = 250.
                // index 5 -rage mutliplier
            set vTable [5].real[1] = 0.2
            set vTable [5].real[2] = 0.4
            set vTable [5].real[3] = 0.6
                // index 6 - rage cap
            set vTable [6].real[1] = 100
            set vTable [6].real[2] = 200
            set vTable [6].real[3] = 300
                // index 7 - min damage
            set vTable [7].real[1] = 100
            set vTable [7].real[2] = 100
            set vTable [7].real[3] = 100
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
            call TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea)
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_REVIVE_FINISH)
            call TriggerAddCondition(t, Condition(function thistype.onCast))
            set t = null
            call StructuredDD.addHandler(function thistype.onAttack)
        endmethod
    endstruct
endscope
//===========================================================================

    // OUTPUT

//===========================================================================
library Lich
    globals
        public real array EXTRA_DAMAGE
        public real array EXTRA_DAMAGE_AOE
    endglobals
endlibrary
//===========================================================================

    // USED BY SUB-ABILITIES (such as Frost nova) AND AURA

//===========================================================================
library Tile initializer init requires Table, TimerUtils
    globals
        private constant real INTERVAL = .08334
        private constant real DISTANCE = 128.
        private group PRODUCERS = CreateGroup()
        private real CHECK_DIST = 0.
        private constant trigger TRIGGER = CreateTrigger()
        private Table array TILES
        private integer array TILE_MAX
        private real array RADIUS
        private group SWITCH_GROUP
        private group TEMP_GROUP = CreateGroup()
    endglobals
    private constant function GetBigger takes real r1, real r2 returns real
        if r1 > r2 then
            return r1
        endif
        return r2
    endfunction
    private function Pythagoras takes real x, real y returns real
        return SquareRoot(x*x + y*y)
    endfunction
    private function round takes real r1, real r2 returns real
            if r1 > 0 then
                return I2R(R2I(r1/r2 + 0.5))*r2
            endif
            return I2R(R2I(r1/r2 - 0.5))*r2
    endfunction
    private function ProducerFilter takes nothing returns boolean
        return IsUnitInGroup(GetFilterUnit(), PRODUCERS)
    endfunction
    private struct Struct
        private integer original
        private integer tile
        private integer var
        private real time
        private real x
        private real y
        private static method onLoop takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype s = GetTimerData(t)
            local group g = CreateGroup()
            call GroupEnumUnitsInRange(g, s.x, s.y, CHECK_DIST, Filter(function ProducerFilter))
            if FirstOfGroup(g) == null then
                set s.time = s.time - INTERVAL
            endif
            if s.time <= 0 then
                if GetTerrainType(s.x, s.y) == s.tile and GetTerrainVariance(s.x, s.y) == s.var then
                    call SetTerrainType(s.x, s.y, s.original, -1, 1, 0)
                endif
                call ReleaseTimer(t)
            endif
            call DestroyGroup(g)
            set t = null
            set g = null
        endmethod
        static method create takes real x, real y, Table table, integer max, real duration returns thistype
            local thistype s
            local timer t
            local boolean b = true
            local integer i = GetTerrainType(x, y)
            local integer n = -1
            loop
                set n = n + 1
                if i == table[n] then
                    set b = false
                    exitwhen true
                endif
                exitwhen n == max
            endloop
            if b then
                set s = thistype.allocate()
                set t = NewTimer()
                set s.original = i
                set s.time = duration
                call SetTerrainType(x, y, table[GetRandomInt(0, max)], -1, 1, 0)
                set s.tile = GetTerrainType(x,y)
                set s.var = GetTerrainVariance(x,y)
                call SetTimerData(t, s)
                set s.x = x
                set s.y = y
                call TimerStart(t, INTERVAL, true, function thistype.onLoop)
                set t = null
            endif
            return s
        endmethod
    endstruct
    public function Spawn takes real x, real y, Table tiles,  integer maxTile, real radius, real time returns nothing
            // current coord
        local real cX = round(x - radius/2, DISTANCE)
        local real cY
        local real r
        loop
            set cX = cX + DISTANCE
            set cY = round(y - radius/2, DISTANCE)
            loop
                set cY = cY + DISTANCE
                set r = Pythagoras(x-cX,y-cY)
                if r <= radius then
                    call Struct.create(cX, cY, tiles, maxTile, GetBigger(0.5,time - r/DISTANCE))
                endif
                exitwhen cY >= y + radius/2
            endloop
            exitwhen cX >= x + radius/2
        endloop
    endfunction
    public function AddProducer takes unit u, Table tiles, integer maxTile, real radius returns nothing
        if FirstOfGroup(PRODUCERS) == null then
            set CHECK_DIST = 0
            call EnableTrigger(TRIGGER)
        endif
        if not IsUnitInGroup(u, PRODUCERS) then
            set CHECK_DIST = GetBigger(radius, CHECK_DIST)
            call GroupAddUnit(PRODUCERS, u)
            set TILES[GetUnitIndex(u)] = tiles
            set TILE_MAX[GetUnitIndex(u)] = maxTile
            set RADIUS[GetUnitIndex(u)] = radius
        endif
    endfunction
    public function RemoveProducer takes unit u returns nothing
        if IsUnitInGroup(u, PRODUCERS) then
            call GroupRemoveUnit(PRODUCERS, u)
        endif
    endfunction
    private function Cond takes nothing returns boolean
        local unit FoG
        local integer i
        if FirstOfGroup(PRODUCERS) == null then
            call DisableTrigger(TRIGGER)
        else
            loop
                set FoG = FirstOfGroup(PRODUCERS)
                exitwhen FoG == null
                set i = GetUnitIndex(FoG)
                call Spawn(GetUnitX(FoG),GetUnitY(FoG),TILES[i],TILE_MAX[i],RADIUS[i],1)
                call GroupRemoveUnit(PRODUCERS, FoG)
                call GroupAddUnit(TEMP_GROUP, FoG)
            endloop
            set SWITCH_GROUP = PRODUCERS
            set PRODUCERS = TEMP_GROUP
            set TEMP_GROUP = SWITCH_GROUP
        endif
        return false
    endfunction
    private function init takes nothing returns nothing
        call TriggerRegisterTimerEvent(TRIGGER, INTERVAL, true)
        call TriggerAddCondition(TRIGGER, Condition(function Cond))
        call DisableTrigger(TRIGGER)
    endfunction
endlibrary

Changelog:
Update 8.7.2014:
-Added snow tiles beneath fully charged hero
-Bug fixes
-More comments
-Added a couple of effects

Posted 7.7.2014​

I didn't include StillDummy and UnitTextTag yet. Also I haven't finished the Frost Nova effect and the aura itself lacks in effects.

And I read something about adding comments to explain stuff in the code so that's in the works too, but this is a good start :)
 
Last edited by a moderator:
Nice you post a WIP. Code is most important here, but you also should present the idea and the basic concept in some short statements.
And I read something about adding comments to explain stuff in the code so that's in the works too, but this is a good start :)
Yes, comments are very important in big codes. Else it may be just a pain to fully understand what is going on in detail.

@all, please think about commenting your code! But try to keep it simple and don't comment each obvious part.
 
Level 24
Joined
Jun 5, 2008
Messages
2,572
Meh i am gonna go with my Luminosity idea unless i get a better one.
Tho actual work is gonna be delayed until 11th.

Decided on the icon so far:
icons_11874_btn.jpg


I think it reflects well how the caster can burn his life force and how enemies can burn.

Was thinking of maybe doing an ice/water theme but would need a really good idea for it.
 
Update.

Nearby allies gain movement speed and attack damage. When an enemy hero within 750 range of the Marshal drops below 40% health, such enemy is marked with true sight and the aura also grants lifesteal.

Lifesteal increases for every enemy hero after the first marked.

Statistics
Area of Effect: 600
Attack Damage Bonus: 25%
Lifesteal: 15%
Lifesteal Per Hero After First: 10%
Movement Bonus: 25%

Credits:
Credits

- JesusHipster (Kingstride Buff Model)
- Nudl9 (Kingstride Icon)

The Kingstride Aura itself is a material change from the Thorns Aura.
  • Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- -------------------------------------------- --------
      • -------- Lifesteal percentage in decimal --------
      • Set Config_KS_Lifesteal = 0.15
      • -------- Lifesteal increase per hero marked after the first - in decimal --------
      • Set Config_KS_LifestealIncrease = 0.10
      • -------- Trigger Fire Rate in seconds --------
      • -------- Detection Range --------
      • Set Config_KS_Range = 750.00
      • -------- Trigger Fire Rate in seconds --------
      • Set Config_KS_Rate = 0.75
      • -------- Special Effect for Lifesteal --------
      • Set Config_KS_StealFX = Abilities\Spells\Undead\VampiricAura\VampiricAuraTarget.mdl
      • -------- Threshold of enemy max hp in decimal --------
      • Set Config_KS_Threshold = 0.40
      • -------- Do not touch. --------
      • Custom script: call TriggerRegisterTimerEvent(gg_trg_Kingstride, udg_Config_KS_Rate, true)
      • -------- ----------------------- --------
      • -------- Variable Creator --------
      • -------- !Delete actions below after copying! --------
      • -------- ----------------------- --------
      • Set KS_Caster[KS_Index] = (Triggering unit)
      • Set KS_Dummy = (Triggering unit)
      • Set KS_Lifesteal[A] = True
      • Set KS_Group[A] = (Last created unit group)
      • Set KS_Player[A] = (Picked player)
      • Set KS_Enumerated[A] = 0
JASS:
//////////////////////////////////////////////////////////////////////////////
//    _  __  ___    _                                                       //
//   | |/ // ___|  /_\                                                      //
//   |   | \___ \ / _ \                                                     //
//   |_|\_\|____//_/ \_\                                                    //
//                                                                          //
//    Kingstride Aura v 1.2                                                 //
//               by CakeMaster                                              //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

function KS_RadarCondition takes nothing returns boolean
    return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405 and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) < (GetUnitState(GetFilterUnit(), UNIT_STATE_MAX_LIFE) * udg_Config_KS_Threshold) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == true and IsUnitEnemy(GetFilterUnit(), udg_KS_Player[udg_A]) == true
endfunction

function KS_GatherCondition takes nothing returns boolean
    return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405 and IsUnitAlly(GetFilterUnit(), udg_KS_Player[udg_A]) == true
endfunction

function KS_Setup takes nothing returns boolean
    //On init
    local integer i = -1
    loop
        set i = i + 1
        exitwhen i == 15
        call SetPlayerAbilityAvailable(Player(i), 'A001', false)
    endloop
    set udg_KS_Dummy = CreateUnit(Player(0), 'h001', 0., 0., 0.)
    call UnitAddAbility(udg_KS_Dummy, 'A003')
    return false
endfunction

function KS_LearnedCache takes nothing returns boolean
    //After a hero learns, cache his data
    if GetLearnedSkill() == 'A000' then
        set udg_KS_Index = ( udg_KS_Index + 1 )
        set udg_KS_Caster[udg_KS_Index] = GetTriggerUnit()
        set udg_KS_Enumerated[udg_KS_Index] = 0
        set udg_KS_Group[udg_KS_Index] = CreateGroup()
        set udg_KS_Lifesteal[udg_KS_Index] = false
        set udg_KS_Player[udg_KS_Index] = GetOwningPlayer(udg_KS_Caster[udg_KS_Index])
        call UnitAddAbility(udg_KS_Caster[udg_KS_Index], 'A001')
        if udg_KS_Index == 1 then
            call EnableTrigger(gg_trg_Kingstride)
        endif
    endif
    return false
endfunction

function KS_Lifesteal takes nothing returns boolean
    //Lifesteal, the only part that stacks with other Kingstride Auras
    local integer a = 0
    local real f = 0
    local real r = 0.
    if GetUnitAbilityLevel(udg_source, 'B000') > 0 then
        loop
            set a = a + 1
            exitwhen a > udg_KS_Index
            if udg_KS_Lifesteal[a] == true and IsUnitInGroup(udg_source, udg_KS_Group[a]) == true then
                set f = udg_Config_KS_Lifesteal + (udg_Config_KS_LifestealIncrease * udg_KS_Enumerated[a])
                set r = r + (udg_amount * f)
            endif
        endloop
        if r > 0. then 
            call SetUnitState(udg_source, UNIT_STATE_LIFE, (GetUnitState(udg_source, UNIT_STATE_LIFE) + r))
            call DestroyEffect(AddSpecialEffect(udg_Config_KS_StealFX, GetUnitX(udg_source), GetUnitY(udg_source)))
        endif
    endif
    return false
endfunction

function Kingstride takes nothing returns boolean
    local real x
    local real y
    local group g
    local unit u
    local integer i
    local real tx
    local real ty
    set udg_A = 1
    loop
        exitwhen udg_A > udg_KS_Index
        set x = GetUnitX(udg_KS_Caster[udg_A])
        set y = GetUnitY(udg_KS_Caster[udg_A])
        set g = CreateGroup()
        //Group Enumeration
        call GroupEnumUnitsInRange(g, x, y, udg_Config_KS_Range, Condition(function KS_RadarCondition))
        set i = 0
        //Check for units to mark
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            call SetUnitOwner(udg_KS_Dummy, udg_KS_Player[udg_A], false)
            call UnitShareVision(u, udg_KS_Player[udg_A], true)
            call IssueTargetOrder(udg_KS_Dummy, "faeriefire", u)
            call UnitShareVision(u, udg_KS_Player[udg_A], false)
            set i = i + 1
            call GroupRemoveUnit(g, u)
        endloop
        //Radar Check
        if i <= 0 then
            // No weak enemies in range
            set udg_KS_Enumerated[udg_A] = 0
            set udg_KS_Lifesteal[udg_A] = false
            call GroupClear(udg_KS_Group[udg_A])
        else
            // Weak enemy/ies in range
            set udg_KS_Enumerated[udg_A] = i
            set udg_KS_Lifesteal[udg_A] = true
            //Add units to the group, auto-remove all units un-included
            call GroupEnumUnitsInRange(udg_KS_Group[udg_A], x, y, udg_Config_KS_Range, Condition(function KS_GatherCondition))
        endif
        call DestroyGroup(g)
        set udg_A = udg_A + 1
    endloop
    set g = null
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_Kingstride takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_HERO_SKILL)
    call TriggerAddCondition(t, Condition(function KS_LearnedCache))
    set t = CreateTrigger()
    call TriggerRegisterTimerEvent(t, 0., false)
    call TriggerAddCondition(t, Condition(function KS_Setup))
    set t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_damageEventTrigger", EQUAL, 1.)
    call TriggerAddCondition(t, Condition(function KS_Lifesteal))
    set t = null
    set gg_trg_Kingstride = CreateTrigger()
    call DisableTrigger(gg_trg_Kingstride)
    call TriggerAddCondition(gg_trg_Kingstride, Condition(function Kingstride))
endfunction
attachment.php
 

Attachments

  • Kingstride.png
    Kingstride.png
    1,023.7 KB · Views: 247
  • Kingstride - Zephyr 11.w3x
    92.8 KB · Views: 45
Level 12
Joined
Jul 16, 2012
Messages
681
My WIP - Dark Circle

Triggers
    • DrkC Setup
      • Events
        • Map initialization
      • Conditions
      • Actions
        • -------- ======================== --------
        • -------- D A R K C I R C L E --------
        • -------- By GywGod133 --------
        • -------- ======================== --------
        • -------- Config Periodic Time --------
        • Custom script: local real DrkC_L = 0.03125
        • Custom script: call TriggerRegisterTimerEventPeriodic( gg_trg_DrkC_Loop, DrkC_L )
        • -------- ======================== --------
        • -------- Config Ability --------
        • -------- > Ability ID --------
        • Set DrkC_Ability = Dark Circle
        • -------- ------------------------------------------------ --------
        • -------- > Damage Per Second --------
        • Set DrkC_DPS[1] = 20.00
        • Set DrkC_DPS[2] = 30.00
        • Set DrkC_DPS[3] = 40.00
        • Set DrkC_DPS[4] = 50.00
        • -------- ------------------------------------------------ --------
        • -------- > Area of Effect --------
        • Set DrkC_AoE[1] = 400.00
        • Set DrkC_AoE[2] = 400.00
        • Set DrkC_AoE[3] = 400.00
        • Set DrkC_AoE[4] = 400.00
        • -------- ------------------------------------------------ --------
        • -------- > Duration --------
        • Set DrkC_Duration[1] = 5.00
        • Set DrkC_Duration[2] = 5.00
        • Set DrkC_Duration[3] = 5.00
        • Set DrkC_Duration[4] = 5.00
        • -------- ------------------------------------------------ --------
        • -------- > Attack / Damage Type --------
        • Set DrkC_AttackType = Spells
        • Set DrkC_DamageType = Normal
        • -------- ------------------------------------------------ --------
        • -------- > Special Effect --------
        • Set DrkC_SFX = Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
        • -------- ------------------------------------------------ --------
        • -------- > Dummy --------
        • Set DrkC_DummyTypes[1] = DrkC_Circle (Black)
        • -------- Randomed Runes --------
        • Set DrkC_DummyTypes[2] = DrkC_Circle (Red - 1)
        • Set DrkC_DummyTypes[3] = DrkC_Circle (Red - 2)
        • Set DrkC_DummyTypes[4] = DrkC_Circle (Red - 3)
        • Set DrkC_DummyTypes[5] = DrkC_Circle (Red - 4)
        • Set DrkC_RuneCount = 4
        • -------- ------------------------------------------------ --------
        • -------- > Sound --------
        • Set DrkC_Sound = GateEpicBash <gen>
        • -------- ======================== --------
        • -------- Configuration Finished --------
        • Custom script: call DestroyTrigger( GetTriggeringTrigger())
        • -------- ======================== --------
    • DrkC Start
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to DrkC_Ability
      • Actions
        • -------- ======================== --------
        • -------- > Turn On Trigger Loop --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • DrkC_Y Equal to 0
          • Then - Actions
            • Trigger - Turn on DrkC Loop <gen>
          • Else - Actions
        • -------- ======================== --------
        • -------- Indexing Function --------
        • Set DrkC_Y = (DrkC_Y + 1)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • DrkC_Y Greater than DrkC_Y_maxSize
          • Then - Actions
            • Set DrkC_Y_Index[DrkC_Y] = DrkC_Y
            • Set DrkC_Y_maxSize = DrkC_Y
          • Else - Actions
        • Set DrkC_TempInt = DrkC_Y_Index[DrkC_Y]
        • -------- ======================== --------
        • -------- Saving Data --------
        • -------- > Caster --------
        • Set DrkC_Caster[DrkC_TempInt] = (Triggering unit)
        • -------- ------------------------------------------------ --------
        • -------- > Player --------
        • Set DrkC_Player[DrkC_TempInt] = (Triggering player)
        • -------- ------------------------------------------------ --------
        • -------- > Current Level of Ability --------
        • Set DrkC_Level[DrkC_TempInt] = (Level of DrkC_Ability for DrkC_Caster[DrkC_TempInt])
        • -------- ------------------------------------------------ --------
        • -------- > Spell Duration Function --------
        • Set DrkC_Duration_Real[DrkC_TempInt] = DrkC_Duration[DrkC_Level[DrkC_TempInt]]
        • -------- ------------------------------------------------ --------
        • -------- > Per Sec Function --------
        • Set DrkC_PerSec[DrkC_TempInt] = 1.00
        • -------- ------------------------------------------------ --------
        • -------- > Create Dark Circle in Targeted Point --------
        • -------- Create Black Circle --------
        • Set DrkC_TempPoint[1] = (Target point of ability being cast)
        • Unit - Create 1 DrkC_DummyTypes[1] for Neutral Passive at DrkC_TempPoint[1] facing (Random angle) degrees
        • Set DrkC_CCircle[DrkC_TempInt] = (Last created unit)
        • Unit - Pause DrkC_CCircle[DrkC_TempInt]
        • -------- Create Randomed Rune --------
        • Set DrkC_TempPoint[2] = (Position of DrkC_CCircle[DrkC_TempInt])
        • Unit - Create 1 DrkC_DummyTypes[(Random integer number between 2 and (DrkC_RuneCount + 1))] for Neutral Passive at DrkC_TempPoint[2] facing (Random angle) degrees
        • Set DrkC_CRune[DrkC_TempInt] = (Last created unit)
        • Unit - Pause DrkC_CRune[DrkC_TempInt]
        • -------- Create Sound --------
        • Set DrkC_TempPoint[3] = (Position of DrkC_CCircle[DrkC_TempInt])
        • Sound - Play DrkC_Sound at 100.00% volume, located at DrkC_TempPoint[3] with Z offset 0.00
        • -------- ------------------------------------------------ --------
        • -------- > Transparent Function --------
        • Set DrkC_Boolean[DrkC_TempInt] = True
        • Set DrkC_Transparent[DrkC_TempInt] = 0.00
        • -------- ------------------------------------------------ --------
        • -------- > Visibility Modifier --------
        • Set DrkC_TempPoint[4] = (Position of DrkC_CRune[DrkC_TempInt])
        • Visibility - Create an initially Enabled visibility modifier for DrkC_Player[DrkC_TempInt] emitting Visibility from DrkC_TempPoint[4] to a radius of DrkC_AoE[DrkC_Level[DrkC_TempInt]]
        • Set DrkC_VisibilityModifier[DrkC_TempInt] = (Last created visibility modifier)
        • -------- ======================== --------
        • -------- Remove Leak/s --------
        • Custom script: call RemoveLocation( udg_DrkC_TempPoint[1])
        • Custom script: call RemoveLocation( udg_DrkC_TempPoint[2])
        • Custom script: call RemoveLocation( udg_DrkC_TempPoint[3])
        • Custom script: call RemoveLocation( udg_DrkC_TempPoint[4])
        • -------- ======================== --------
    • DrkC Loop
      • Events
      • Conditions
      • Actions
        • -------- ======================== -------- ======================== --------
        • -------- PLEASE DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING!! --------
        • -------- ======================== -------- ======================== --------
        • For each (Integer DrkC_X) from 1 to DrkC_Y, do (Actions)
          • Loop - Actions
            • Set DrkC_TempInt = DrkC_Y_Index[DrkC_X]
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • DrkC_Boolean[DrkC_TempInt] Equal to True
              • Then - Actions
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • DrkC_Duration_Real[DrkC_TempInt] Less than or equal to 0.00
                  • Then - Actions
                    • -------- ======================== --------
                    • -------- Transparent --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • DrkC_Transparent[DrkC_TempInt] Greater than or equal to 100.00
                      • Then - Actions
                        • Set DrkC_Boolean[DrkC_TempInt] = False
                      • Else - Actions
                        • Set DrkC_Transparent[DrkC_TempInt] = (DrkC_Transparent[DrkC_TempInt] + 1.00)
                        • Animation - Change DrkC_CCircle[DrkC_TempInt]'s vertex coloring to (100.00%, 100.00%, 100.00%) with DrkC_Transparent[DrkC_TempInt]% transparency
                        • Animation - Change DrkC_CRune[DrkC_TempInt]'s vertex coloring to (100.00%, 100.00%, 100.00%) with DrkC_Transparent[DrkC_TempInt]% transparency
                  • Else - Actions
                    • -------- ======================== --------
                    • -------- Spell Duration Function --------
                    • Custom script: set udg_DrkC_Duration_Real[ udg_DrkC_TempInt] = udg_DrkC_Duration_Real[ udg_DrkC_TempInt] - 0.03125
                    • -------- ======================== --------
                    • -------- Damage Per Sec Function --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • DrkC_PerSec[DrkC_TempInt] Less than or equal to 0.00
                      • Then - Actions
                        • -------- ------------------------------------------------ --------
                        • -------- > Unit Group --------
                        • Set DrkC_UnitGroup[DrkC_TempInt] = (Units within DrkC_AoE[DrkC_Level[DrkC_TempInt]] of (Position of DrkC_CCircle[DrkC_TempInt]))
                        • Unit Group - Pick every unit in DrkC_UnitGroup[DrkC_TempInt] and do (Actions)
                          • Loop - Actions
                            • Set DrkC_TempUnit = (Picked unit)
                            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                              • If - Conditions
                                • (DrkC_TempUnit is alive) Equal to True
                                • (DrkC_TempUnit belongs to an enemy of DrkC_Player[DrkC_TempInt]) Equal to True
                                • (DrkC_TempUnit is Magic Immune) Equal to False
                              • Then - Actions
                                • Set DrkC_TempPoint[1] = (Position of DrkC_TempUnit)
                                • -------- > SFX --------
                                • Special Effect - Create a special effect at DrkC_TempPoint[1] using DrkC_SFX
                                • Special Effect - Destroy (Last created special effect)
                                • -------- > Do Damage --------
                                • Unit - Cause DrkC_Caster[DrkC_TempInt] to damage DrkC_TempUnit, dealing DrkC_DPS[DrkC_Level[DrkC_TempInt]] damage of attack type DrkC_AttackType and damage type DrkC_DamageType
                                • -------- ======================== --------
                                • -------- Remove Leak/s --------
                                • Custom script: call RemoveLocation( udg_DrkC_TempPoint[1])
                                • -------- ======================== --------
                              • Else - Actions
                        • -------- ------------------------------------------------ --------
                        • -------- > Refill --------
                        • Set DrkC_PerSec[DrkC_TempInt] = 1.00
                        • -------- ======================== --------
                        • -------- Remove Leak/s --------
                        • Custom script: call DestroyGroup( udg_DrkC_UnitGroup[ udg_DrkC_TempInt])
                        • -------- ======================== --------
                      • Else - Actions
                        • -------- ------------------------------------------------ --------
                        • -------- > Duration Function --------
                        • Custom script: set udg_DrkC_PerSec[ udg_DrkC_TempInt] = udg_DrkC_PerSec[ udg_DrkC_TempInt] - 0.03125
                        • -------- ------------------------------------------------ --------
                • -------- ======================== --------
                • -------- Dummy Spin Function --------
                • Set DrkC_TempPoint[2] = (Position of DrkC_CCircle[DrkC_TempInt])
                • Set DrkC_TempPoint[3] = (Position of DrkC_CRune[DrkC_TempInt])
                • Unit - Move DrkC_CRune[DrkC_TempInt] instantly to DrkC_TempPoint[2], facing ((Facing of DrkC_CRune[DrkC_TempInt]) + 2.00) degrees
                • Unit - Move DrkC_CCircle[DrkC_TempInt] instantly to DrkC_TempPoint[3], facing ((Facing of DrkC_CCircle[DrkC_TempInt]) - 2.00) degrees
                • Custom script: call RemoveLocation( udg_DrkC_TempPoint[2])
                • Custom script: call RemoveLocation( udg_DrkC_TempPoint[3])
                • -------- ======================== --------
              • Else - Actions
                • -------- ======================== --------
                • -------- Destroy those handle --------
                • Visibility - Destroy DrkC_VisibilityModifier[DrkC_TempInt]
                • Unit - Remove DrkC_CCircle[DrkC_TempInt] from the game
                • Unit - Remove DrkC_CRune[DrkC_TempInt] from the game
                • -------- ======================== --------
                • -------- RecycleIndex --------
                • Set DrkC_Y_Index[DrkC_X] = DrkC_Y_Index[DrkC_Y]
                • Set DrkC_Y_Index[DrkC_Y] = DrkC_TempInt
                • Set DrkC_X = (DrkC_X - 1)
                • Set DrkC_Y = (DrkC_Y - 1)
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • DrkC_Y Equal to 0
                  • Then - Actions
                    • Trigger - Turn off (This trigger)
                  • Else - Actions

Screenshots

  • attachment.php
  • attachment.php
 

Attachments

  • CREATE.PNG
    CREATE.PNG
    307.7 KB · Views: 144
  • DO DAMAGE.PNG
    DO DAMAGE.PNG
    378.1 KB · Views: 175
  • [GUI] Dark Circle (Zephyr Contest).w3x
    35.4 KB · Views: 41
@Zeatherann,
Could you upload a version with code? The triggerset was not visible for me. (you import the script)

@AKA.GywGod133,
I can see some progress! Don't forget about the tooltip, it's also part of the visuals.

@CakeMaster,
The true sight and dynamic life steal looks interesting, keep going! Btw, is the life steal not indicated by purpose, or isn't it working yet? (haven't read the code in detail)
 
Last edited:
Status
Not open for further replies.
Top