1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. The member Kam is making HIVE coasters. Take a look. For every coaster you buy, Hive gets $1.
    Dismiss Notice
  3. Buy it, use it, break it, fix it, trash it, change it, mail - upgrade it. Join (Optionally) Paired Techtree Contest #11 - Techno Magic now!
    Dismiss Notice
  4. Dismiss Notice
  5. Hero Contest #8 is up and running! This time it's a joint contest between artists and coders. Go here for team matchmaking.
    Dismiss Notice
  6. The ninth Concept Art Contest has launched. Enter now!
    Dismiss Notice
  7. Our first StarCraft contest, The Galaxy Terraining Contest #1 - World Wonders has started. Enter to show off your Galaxy Editor skills and win a custom rank icon among other things.
    Dismiss Notice
  8. Ever wanted to get your sets ready for fast texturing while still having fun? Now it is possible with our newest Mini-Texturing Contest.
    The Skeleton Units need your dire help!
    Dismiss Notice

Fire Spiral 1.1.1 (vJass Version)

Submitted by Deaod
Host map Arrange game
This spell was inspired by Blaxor's Fire Spiral.

Changelog:
03/24/2009 - Version 1.0.0
- initial release

04/19/2009 - Version 1.1.0
- moved effects to xe
- removed DelFX (as i updated DelFX with an incompatible Version)
- the spiral can now have an initial radius

08/07/2009 - Version 1.1.1
- Compatibility with 1.24


Spell Code + Credits:
Code (vJASS):
//Credits:
//    - Blaxor for the inspiration
//    - cohadar for his PUI library
//    - Rising_Dusk for his GroupUtils library
//    - Vexorian for JassHelper and TimerUtils
//    - PipeDream for Grimoire and all his help with spirals
//    - PitzerMike for JassNewGenPack
//    - SFilip for TESH

// How to import:
//    - Copy the code into a trigger on your map, adjust the constants below (especially AID) and youre done.
//    - Note that you have to copy over the required libraries as well

library FireSpiral uses TimerUtils, GroupUtils, PUI, xefx
   
    globals
        private constant    integer                 AID                     = 'A000' // rawcode of the triggering abiltiy (press Ctrl+D to display the rawcode of objects, in the object editor)
        private constant    real                    FX_INTERVAL             = 0.15 // effects are spawned in this interval
        private constant    string                  FIRE_FX                 = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeEmbers.mdl" // this is the effect the spiral consits of
        private constant    real                    FIRE_FX_RADIUS          = 24. // collision size of the beforementioned effect
        private constant    real                    FIRE_FX_SCALE           = 1. // scale of beforementioned effect
        private             real            array   FIRE_DMG                // Units receive this much damage per second
        private constant    real                    FIRE_DMG_RADIUS         = 64 // this is the radius in which units around the effects get receive damage
        private constant    real                    FIRE_DMG_TICK           = 1./32 // this is the granulation of damage
        private constant    string                  FIRE_DMG_FX             = "Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl" // this is the effect spawned on units receiving damage by the spiral
        private constant    string                  FIRE_DMG_FX_ATTPT       = "head" // this is the attachmentpoint where the beforementioned effect gets attached to
        private constant    real                    FIRE_DMG_FX_STAY        = 2. // the beforementioned effect stays on units this long after they receive no more damage
        private constant    attacktype              FIRE_DMG_ATTACKTYPE     = ATTACK_TYPE_MAGIC // attacktype of the damage units receive
        private constant    damagetype              FIRE_DMG_DAMAGETYPE     = DAMAGE_TYPE_MAGIC // damagetype of the damage units receive
        private             real            array   SPIRAL_INITIAL_RADIUS   // initial radius of the spiral
        private             real            array   SPIRAL_END_RADIUS       // radius of the spiral
        private             real            array   SPIRAL_CIRCLES          // how often does a spiral reach ((angle) modulo (2*PI))==0
        private             integer         array   SPIRAL_ENDINGS          // number of spirals spawned
        private             real            array   DURATION                // Duration of the spiral after all effects have been spawned
       
        private constant    integer                 MAX_FIRE_FX_PER_INSTANCE = 255
    endglobals
   
    private function SetUpFIRE_DMG takes nothing returns nothing
        set FIRE_DMG[1]=50.
        set FIRE_DMG[2]=75.
        set FIRE_DMG[3]=100.
    endfunction
   
    private function SetUpSPIRAL_INITIAL_RADIUS takes nothing returns nothing
        set SPIRAL_INITIAL_RADIUS[1]=200
        set SPIRAL_INITIAL_RADIUS[2]=200
        set SPIRAL_INITIAL_RADIUS[3]=200
    endfunction
   
    private function SetUpSPIRAL_END_RADIUS takes nothing returns nothing
        set SPIRAL_END_RADIUS[1]=400.
        set SPIRAL_END_RADIUS[2]=500.
        set SPIRAL_END_RADIUS[3]=600.
    endfunction
   
    private function SetUpSPIRAL_CIRCLES takes nothing returns nothing
        set SPIRAL_CIRCLES[1]=0.6
        set SPIRAL_CIRCLES[2]=0.8
        set SPIRAL_CIRCLES[3]=1.0
    endfunction
   
    private function SetUpSPIRAL_ENDINGS takes nothing returns nothing
        set SPIRAL_ENDINGS[1]=3
        set SPIRAL_ENDINGS[2]=3
        set SPIRAL_ENDINGS[3]=3
    endfunction
   
    private function SetUpDURATION takes nothing returns nothing
        set DURATION[1]=5.
        set DURATION[2]=7.
        set DURATION[3]=9.
    endfunction
   
    // proxy functions
    // if you want to use formulae, edit these
   
    private function Fire_Dmg takes integer level returns real
        return FIRE_DMG[level]
    endfunction
   
    private function Spiral_Initial_Radius takes integer level returns real
        return SPIRAL_INITIAL_RADIUS[level]
    endfunction
   
    private function Spiral_End_Radius takes integer level returns real
        return SPIRAL_END_RADIUS[level]
    endfunction
   
    private function Spiral_Circles takes integer level returns real
        return SPIRAL_CIRCLES[level]
    endfunction
   
    private function Spiral_Endings takes integer level returns integer
        return SPIRAL_ENDINGS[level]
    endfunction
   
    private function Duration takes integer level returns real
        return DURATION[level]
    endfunction
   
    // I wouldnt edit anything below this line, if i were you
   
    private struct Data
        unit c
        integer level
        integer i
        timer t
        real x
        real y
        real a
        real b
        real f
        real d
        integer fxcount
        xefx array FX[MAX_FIRE_FX_PER_INSTANCE]
        real array FXX[MAX_FIRE_FX_PER_INSTANCE]
        real array FXY[MAX_FIRE_FX_PER_INSTANCE]
       
        static Data array Structs
        static integer Count=0
        static timer T=CreateTimer()
        static Data tmps
        static boolexpr FireDmg
       
        static timer array ImmoT
        static effect array ImmoFX
       
        static method ImmoCallback takes nothing returns nothing
        local timer t=GetExpiredTimer()
        local integer i=GetTimerData(t)
            call DestroyEffect(Data.ImmoFX[i])
            set Data.ImmoFX[i]=null
            call ReleaseTimer(t)
        endmethod
       
        static method FireDmgFunc takes nothing returns boolean
        local unit u=GetFilterUnit()
        local integer i
        local timer t
            if IsUnitEnemy(u, GetOwningPlayer(Data.tmps.c)) and (not IsUnitInGroup(u, ENUM_GROUP)) and IsUnitType(u, UNIT_TYPE_DEAD)==false and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false then
                call UnitDamageTarget(Data.tmps.c, u, Fire_Dmg(Data.tmps.level)*FIRE_DMG_TICK, false, false, FIRE_DMG_ATTACKTYPE, FIRE_DMG_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS)
                set i=GetUnitIndex(u)
                if Data.ImmoFX[i]==null then
                    set Data.ImmoFX[i]=AddSpecialEffectTarget(FIRE_DMG_FX, u, FIRE_DMG_FX_ATTPT)
                    set t=NewTimer()
                    call SetTimerData(t, i)
                    call TimerStart(t, FIRE_DMG_FX_STAY, false, function Data.ImmoCallback)
                    set Data.ImmoT[i]=t
                else
                    call TimerStart(Data.ImmoT[i], FIRE_DMG_FX_STAY, false, function Data.ImmoCallback)
                endif
                set u=null
                return true
            endif
            set u=null
            return false
        endmethod
       
        method onDestroy takes nothing returns nothing
            set .c=null
            call ReleaseTimer(.t)
            set Data.Count=Data.Count-1
            set Data.Structs[.i]=Data.Structs[Data.Count]
            set Data.Structs[.i].i=.i
            if Data.Count==0 then
                call PauseTimer(Data.T)
            endif
        endmethod
       
        static method EndingCB takes nothing returns nothing
        local Data s=GetTimerData(GetExpiredTimer())
        local integer i=0
            loop
                exitwhen i>=Spiral_Endings(s.level)
                set s.fxcount=s.fxcount-1
                call s.FX[s.fxcount].destroy()
                set i=i+1
            endloop
            if s.fxcount<=0 then
                call s.destroy()
            endif
        endmethod
       
        static method Ending takes nothing returns nothing
            call TimerStart(GetExpiredTimer(), FX_INTERVAL, true, function Data.EndingCB)
        endmethod
       
        static method SpawnCB takes nothing returns nothing
        local Data s=GetTimerData(GetExpiredTimer())
        local integer i=0
        local real d=2*bj_PI/Spiral_Endings(s.level)
        local real f=s.a+(bj_PI/2)
            loop
                exitwhen i>=Spiral_Endings(s.level)
                debug if s.fxcount>=MAX_FIRE_FX_PER_INSTANCE then
                debug     call BJDebugMsg("FireSpiral: Array overflow! Try increasing MAX_FIRE_FX_PER_INSTANCE!")
                debug     exitwhen true
                debug endif
                set s.FXX[s.fxcount]=s.x+(s.d*Cos(s.f+s.a+(i*d)))
                set s.FXY[s.fxcount]=s.y+(s.d*Sin(s.f+s.a+(i*d)))
                set s.FX[s.fxcount]=xefx.create(s.FXX[s.fxcount], s.FXY[s.fxcount], f)
                set s.FX[s.fxcount].fxpath=FIRE_FX
                set s.FX[s.fxcount].scale=FIRE_FX_SCALE
                set s.fxcount=s.fxcount+1
                set i=i+1
            endloop
            set s.a=2*Asin((2*FIRE_FX_RADIUS)/(2*s.d))+s.a
            set s.d=s.b*s.a
            if s.d>Spiral_End_Radius(s.level) then
                call TimerStart(s.t, Duration(s.level), false, function Data.Ending)
            endif
        endmethod
       
        static method Callback takes nothing returns nothing
        local Data s
        local integer i=0
        local integer j=0
            loop
                exitwhen i>=Data.Count
                set s=Data.Structs[i]
                loop
                    exitwhen j>=s.fxcount
                    set Data.tmps=s
                    call GroupEnumUnitsInRange(ENUM_GROUP, s.FXX[j], s.FXY[j], FIRE_DMG_RADIUS, Data.FireDmg)
                    set j=j+1
                endloop
                call GroupClear(ENUM_GROUP)
                set i=i+1
            endloop
        endmethod
       
        static method Cond takes nothing returns boolean
            return GetSpellAbilityId()==AID
        endmethod
       
        static method Create takes nothing returns nothing
        local Data s=Data.allocate()
        local real d
        local integer i=0
        local real f
            set s.c=GetTriggerUnit()
            set s.level=GetUnitAbilityLevel(s.c, AID)
            set s.t=NewTimer()
            set s.f=GetUnitFacing(s.c)*bj_DEGTORAD
            set s.x=GetUnitX(s.c)
            set s.y=GetUnitY(s.c)
            set s.b=(Spiral_End_Radius(s.level)-Spiral_Initial_Radius(s.level))/(2*bj_PI*Spiral_Circles(s.level))
            set s.d=Spiral_Initial_Radius(s.level)
            set s.a=s.d/s.b
            set d=2*bj_PI/Spiral_Endings(s.level)
            set f=s.a+(bj_PI/2)
            loop
                exitwhen i>=Spiral_Endings(s.level)
                set s.FXX[s.fxcount]=s.x+(s.d*Cos(s.f+s.a+(i*d)))
                set s.FXY[s.fxcount]=s.y+(s.d*Sin(s.f+s.a+(i*d)))
                set s.FX[s.fxcount]=xefx.create(s.FXX[s.fxcount], s.FXY[s.fxcount], f)
                set s.FX[s.fxcount].fxpath=FIRE_FX
                set s.FX[s.fxcount].scale=FIRE_FX_SCALE
                set s.fxcount=s.fxcount+1
                set i=i+1
            endloop
            if s.d==0 then
                set s.a=2*FIRE_FX_RADIUS/s.b
            else
                set s.a=2*Asin((2*FIRE_FX_RADIUS)/(2*s.d))+s.a
            endif
            set s.d=s.b*s.a
            call SetTimerData(s.t, s)
            call TimerStart(s.t, FX_INTERVAL, true, function Data.SpawnCB)
            set Data.Structs[Data.Count]=s
            set s.i=Data.Count
            if Data.Count==0 then
                call TimerStart(Data.T, FIRE_DMG_TICK, true, function Data.Callback)
            endif
            set Data.Count=Data.Count+1
        endmethod
       
        static method onInit takes nothing returns nothing
        local trigger t=CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddAction(t, function Data.Create)
            call TriggerAddCondition(t, Condition(function Data.Cond))
           
            set Data.FireDmg=Condition(function Data.FireDmgFunc)
           
            call SetUpFIRE_DMG()
            call SetUpSPIRAL_INITIAL_RADIUS()
            call SetUpSPIRAL_END_RADIUS()
            call SetUpSPIRAL_CIRCLES()
            call SetUpSPIRAL_ENDINGS()
            call SetUpDURATION()
        endmethod
    endstruct
   
endlibrary


Keywords:
Fire, Spiral, Archimedean, AOE
Contents

FireSpiral 1.1.1 (Map)

  1. 18:25, 15th Oct 2009
    The_Reborn_Devil:

    The triggering looks good, but the spell was kinda boring.
    Also, you need to fix the tooltip.
    It's Approved, but I won't give it a rating before you fix the tooltip and make a test map with some enemies and stuff. Also, some more interesting effects would be nice too, which could potentially increase the rating.
     
  2. Dynasti

    Dynasti
    Joined:
    Oct 18, 2007
    Messages:
    878
    Well, this was fast :D
     
  3. Deuterium

    Deuterium
    Joined:
    Mar 17, 2009
    Messages:
    1,325
    & nicely done :D
     
  4. aaron

    aaron
    Joined:
    Oct 18, 2008
    Messages:
    515
    I wanna know vjass :(
     
  5. calex3

    calex3
    Joined:
    Mar 2, 2009
    Messages:
    292
    nice just like my storm but yours have 3 spirals i will download it later to see it but the picture tells me all.......4/5
     
  6. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    you cant tell from looking at a picture. I suggest you actually TRY it (oh, yeah, you need JNGP to save a modified version of this spell (or some other Editor capable of running JassHelper on saving)).
     
  7. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.1.0
     
  8. Kingz

    Kingz
    Joined:
    Jun 5, 2008
    Messages:
    2,475
    Eh, why did you use so much libraries?
    I think it could have been done easier, but if all those provide maximum efficency i think it is okay...
     
  9. PurplePoot

    PurplePoot
    Joined:
    Dec 14, 2005
    Messages:
    11,151
    Because they are standards.
     
  10. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.1.1
     
  11. Spet

    Spet
    Joined:
    Jun 3, 2009
    Messages:
    457
    Very nice spell man ;)
    5/5
     
  12. X-OMG-X

    X-OMG-X
    Joined:
    Nov 10, 2008
    Messages:
    1,951
    Looks cool. Will download and test.