Spellpack Nuke, Flame Storm, Blink Back, Fade Run

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Implementation instructions are within the map.

Credits: Uberplayer, Romek, Tinki3, Phyrex1an, Ghan, Varine, Trollvottel, azlier, Daxtreme, Flare

PUI
TT
CSData can be found @ bottom of this.

Nuke

Vid
http://www.xfire.com/video/a712c/

Code
JASS:
scope NukeBomb initializer Init
//Requires CSData
    globals
        //[Config Header]
        private constant integer ABID = 'A000'
            //The abilities ID.
        private constant integer DUMID = 'u001'
            //The ID of the dummy unit.
        private constant integer CROW = 'Amrf'
            //The ability ID for crow, leave alone unless you've changed it.
        private constant string BOOM = "war3mapImported\\NuclearExplosion.mdx"
            //The string file path for the explosion at the end. All \s become \\s.
        private constant real DMG = 100
            //How much base damage is done per level.
        private constant real AOE = 500
            //The AOE of the damage.
        private constant boolean REALISTIC = false
            //If set to true, the unit will damage everything in targeted area.
            //If set to false, the unit will only damage enemies in targeted area.
        //End [Config Header]
            
        private sound SOUND
        private player temp
    endglobals
    
    private constant function SPECDMG takes integer lvl returns real
        return DMG*lvl
        //This function multiplies the base damage (Variable: DMG) by the level of the ability.
    endfunction
    
    private function NukeCond takes nothing returns boolean
        return GetSpellAbilityId() == ABID
    endfunction
    
    private function IsEnemy takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(),temp)
    endfunction
    
    private struct Nuke
        unit u
        unit d
        group g
        location l
        location q
        integer lvl
        
        method onDestroy takes nothing returns nothing
            call DestroyGroup(.g)
            call RemoveLocation(.l)
            call RemoveLocation(.q)
        endmethod
        
        method DmgE takes group g, unit u returns nothing
            loop
            exitwhen FirstOfGroup(g) == null
                call UnitDamageTarget(u,FirstOfGroup(g),SPECDMG(GetUnitAbilityLevel(u,ABID)),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
                call GroupRemoveUnit(g,FirstOfGroup(g))
            endloop
        endmethod
        
        static method Nukes takes nothing returns nothing
            local Nuke this = Nuke(GetCSData(GetExpiredTimer()))
            
            call KillUnit(.d)
            if REALISTIC then
                call UnitDamagePoint(.u,0,AOE,GetLocationX(.l),GetLocationY(.l),SPECDMG(.lvl),false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
            else
                set temp = GetOwningPlayer(.u)
                call GroupEnumUnitsInRangeOfLoc(.g,.q,AOE,Condition(function IsEnemy))
                call .DmgE(.g,.u)
            endif
            call DestroyEffect(AddSpecialEffectLoc(BOOM,.l))
        endmethod
    endstruct
            
            
    private function NukeAct takes nothing returns nothing
        local Nuke this = Nuke.create()
        local timer t = CreateTimer()
        
        set this.u = GetTriggerUnit()
        set this.g = CreateGroup()
        set this.l = GetSpellTargetLoc()
        set this.q = GetUnitLoc(this.u)
        set this.lvl = GetUnitAbilityLevel(this.u,ABID)
        set this.d = CreateUnitAtLoc(GetOwningPlayer(this.u),DUMID,this.q,0)
        
        call StartSound(SOUND)
        
        call UnitAddAbility(this.d,CROW)
        call UnitRemoveAbility(this.d,CROW)
        
        call SetUnitFlyHeight(this.d,1,GetUnitFlyHeight(this.d)*GetUnitMoveSpeed(this.d)/DistanceBetweenPoints(this.q,this.l))
        call IssuePointOrder(this.d,"move",GetLocationX(this.l),GetLocationY(this.l))
        
        call TimerStart(t,DistanceBetweenPoints(this.q,this.l)/GetUnitMoveSpeed(this.d),false,function Nuke.Nukes)
            //Originally a wait, this makes sure the Nuke explodes in the correct spot.
        call SetCSData(t,this)
    endfunction
    
    private function SoundInit takes nothing returns nothing
        set SOUND = gg_snd_nuclear
        call DestroyTimer(GetExpiredTimer())
    endfunction
    
    public function FailSafe takes nothing returns boolean
        return true
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
        exitwhen i > 15
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function FailSafe))
            set i = i + 1
        endloop
        
        call TriggerAddAction(t,function NukeAct)
        call TriggerAddCondition(t, Condition(function NukeCond))
        
        call TimerStart(CreateTimer(),1,false,function SoundInit)
    endfunction
endscope

Flame Storm


Vid
http://www.xfire.com/video/a715e/

Code
JASS:
scope FlameStorm initializer Init
//Requires TT
    globals
        //[Config Header]
        private constant integer ABID = 'A002'
            //The ability ID of the spell.
        private constant integer DUMID = 'u000'
            //The unit ID of the dummy that is created.
        private constant real TIME = 20
            //The length of time that the spell lasts, in seconds
        private constant real MINLENG = 20
            //The minimum length the flame is from the caster.
        private constant real MAXLENG = 400
            //The maximum length the flame is from the caster.
        private constant real DMG = 50
            //The base damage done.
        private constant string FX = "war3mapImported\\NuclearExplosion.mdx"
            //The ending effect, AKA those big booms.
        private constant boolean REALISTIC = false
            //If set to true, the unit will damage everything around him.
            //If set to false, the unit will only damage enemies.
        //End [Config Header]
        private unit tempUnit
        private player tempPlayer
    endglobals
    
    private function SPECDMG takes integer lvl returns real
        return DMG*lvl
        //This function multiplies the base damage (Variable: DMG) by the level of the ability.
    endfunction
    
    struct flamemove
        unit base
        unit array flames[4]
        group g = CreateGroup()
        real ticker = 0
        real curleng = 20
        real array angles[4]
        location array uni[4]
        boolean uord = true
        
        method onDestroy takes nothing returns nothing
            call DestroyGroup(.g)
            call RemoveLocation(.uni[0])
            call RemoveLocation(.uni[1])
            call RemoveLocation(.uni[2])
            call RemoveLocation(.uni[3])
        endmethod
    endstruct
    
    private function IsEnemy takes nothing returns boolean
        if IsUnitEnemy(GetFilterUnit(),tempPlayer) then
            call UnitDamageTarget(tempUnit,GetFilterUnit(),SPECDMG(GetUnitAbilityLevel(tempUnit,ABID)),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
        endif
        return false
    endfunction
    
    private function move takes nothing returns boolean
        local flamemove a = TT_GetData()
        local integer i = 0
        local location l = GetUnitLoc(a.base)
        set a.ticker = a.ticker + TT_PERIOD * 100
        if a.ticker == TIME * 100 then
            call DestroyEffect(AddSpecialEffectLoc(FX,l))
            loop
            exitwhen i > 3
                call KillUnit(a.flames<i>)
                call DestroyEffect(AddSpecialEffectLoc(FX,a.uni<i>))
            if REALISTIC == true then
                call UnitDamagePoint(a.base,0,a.curleng,GetLocationX(l),GetLocationY(l),SPECDMG(GetUnitAbilityLevel(GetTriggerUnit(),ABID)),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
            else
                set tempUnit = a.base
                set tempPlayer = GetOwningPlayer(a.base)
                call GroupEnumUnitsInRangeOfLoc(a.g,l,a.curleng,Condition(function IsEnemy))
            endif
                set i = i + 1
            endloop
            return true
        endif
        loop
        exitwhen i &gt; 3
            set a.angles<i> = a.angles<i>+10
            if a.uord then
                set a.curleng = a.curleng + 5
                if a.curleng == MAXLENG then
                    set a.uord = false
                endif
            else
                set a.curleng = a.curleng - 5
                if a.curleng == MINLENG then
                    set a.uord = true
                endif
            endif
            set a.uni<i> = PolarProjectionBJ(l,a.curleng,a.angles<i>)
            call SetUnitPositionLoc(a.flames<i>,a.uni<i>)
            call SetUnitFacing(a.flames<i>,GetUnitFacing(a.flames<i>)+1)
            set i = i + 1
        endloop
        return false
    endfunction
    
   private function FSC takes nothing returns boolean
        return GetSpellAbilityId() == ABID
    endfunction
    
    private function FSA takes nothing returns nothing
        local flamemove a = flamemove.create()
        local integer i = 0
        set a.base = GetTriggerUnit()
        loop
        exitwhen i &gt; 3
            set a.angles<i> = i*90
            set a.uni<i> = PolarProjectionBJ(GetUnitLoc(a.base),a.curleng,a.angles)
            set a.flames<i> = CreateUnitAtLoc(GetOwningPlayer(a.base),DUMID,a.uni<i>,0)
            set i = i + 1
        endloop
        call TT_Start(function move,a)
    endfunction
    
    private function FailSafe takes nothing returns boolean
        return true
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
        exitwhen i &gt; 15
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function FailSafe))
            set i = i + 1
        endloop
        
        call TriggerAddAction(t,function FSA)
        call TriggerAddCondition(t,Condition(function FSC))
    endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i>



Blink Back


Vid
http://www.xfire.com/video/a75ab/

Code
JASS:
scope BlinkBack initializer Init
//Requires PUI

//! runtextmacro PUI_PROPERTY(&quot;private&quot;, &quot;location&quot;, &quot;BKTOLOC&quot;, &quot;null&quot;)
//! runtextmacro PUI_PROPERTY(&quot;private&quot;, &quot;integer&quot;, &quot;NUMTELE&quot;, &quot;0&quot;)

    globals
        private constant integer ABID = &#039;A001&#039;
            //The ID of the main ability.
        private constant integer TELEBK = &#039;A004&#039;
            //The ID of the teleporting back spell.
        private constant integer NUMTELES = 3
            //The maximum number of teleports a player can do, per location.
        private constant real RANGE = 1000
            //The range that the unit can be called back.
        private constant string FX = &quot;Abilities\\Spells\\Demon\\ReviveDemon\\ReviveDemon.mdx&quot;
            //The string path of the effect.
    endglobals
    
    private function BBA takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local location l = GetUnitLoc(u)
        
        if GetSpellAbilityId() == ABID then
            if NUMTELE[GetTriggerUnit()] == 0 then
                set BKTOLOC[GetTriggerUnit()] = GetUnitLoc(u)
                call UnitAddAbility(u,TELEBK)
            else
                call RemoveLocation(BKTOLOC[GetTriggerUnit()])
                set BKTOLOC[GetTriggerUnit()] = GetUnitLoc(u)
                set NUMTELE[GetTriggerUnit()] = 0
            endif
        endif
        
        if GetSpellAbilityId() == TELEBK and IsUnitInRangeLoc(u,BKTOLOC[GetTriggerUnit()],RANGE) == true then
            call DestroyEffect(AddSpecialEffectLoc(FX,l))
            call DestroyEffect(AddSpecialEffectLoc(FX,BKTOLOC[GetTriggerUnit()]))
            call TriggerSleepAction(1)
            call SetUnitPositionLoc(u,BKTOLOC[GetTriggerUnit()])
            set NUMTELE[GetTriggerUnit()] = NUMTELE[GetTriggerUnit()] + 1
            if NUMTELE[GetTriggerUnit()] &gt;= NUMTELES then
                call UnitRemoveAbility(u,TELEBK)
                set NUMTELE[GetTriggerUnit()] = 0
                call RemoveLocation(BKTOLOC[GetTriggerUnit()])
            endif
        endif
        
        call RemoveLocation(l)
        set l = null
        set u = null
    endfunction
    
    private function FailSafe takes nothing returns boolean
        return true
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
        exitwhen i &gt; 15
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function FailSafe))
            set i = i + 1
        endloop
        
        call TriggerAddAction(t,function BBA)
    endfunction
endscope


Fade Run


Vid
http://www.xfire.com/video/a7170/

Code
JASS:
scope FadeRun initializer Init
//Requires TT and CSData
    globals
        private constant integer ABID = &#039;A005&#039;
            //The ID of the ability.
        private constant integer LOKUST = &#039;Aloc&#039;
            //The ID of the ability to make the trail unselectable.
        private constant integer ACTK = &#039;Aatk&#039;
            //ID for removing the attack of the clone.
        private constant integer TRAIL = 5
            //This controls the trail. It&#039;s really damn weird.
            //Use 1 for a really thick trail, I suggest testing different numbers.
            //The TT inteverval affects this.
        private constant real TIME = 20
            //The length it will last in seconds.
    endglobals
    
    private struct Fade
        unit anchor
        real ticks
        integer fadetick = 255
        unit d
        
        static method fade takes nothing returns nothing
            local Fade this = GetCSData(GetExpiredTimer())
            set .fadetick = .fadetick - 5
            call SetUnitVertexColor(.d,255,255,255,.fadetick)
            if .fadetick == 0 then
                call RemoveUnit(.d)
                call DestroyTimer(GetExpiredTimer())
            endif
        endmethod
        
        static method Do takes nothing returns boolean
            local Fade this = TT_GetData()
            local timer t = CreateTimer()
            if ModuloReal(.ticks,TRAIL) == 0 then
                set .d = CreateUnit(GetOwningPlayer(.anchor),GetUnitTypeId(.anchor),GetUnitX(.anchor),GetUnitY(.anchor),GetUnitFacing(.anchor))
                call UnitAddAbility(.d,LOKUST)
                call UnitRemoveAbility(.d,ACTK)
                call SetUnitTimeScale(.d,0)
                call PauseUnit(.d,true)
                call SetUnitOwner(.d,Player(15),false)
                call TimerStart(t,0.01,true,function Fade.fade)
                call SetCSData(t,this)
            endif
            set .ticks = .ticks + TT_PERIOD * 100
            if .ticks &gt;= TIME*100 then
                return true
            endif
            return false
        endmethod
    endstruct
    
    private function FRC takes nothing returns boolean
        return GetSpellAbilityId() == ABID
    endfunction
    
    private function FRA takes nothing returns nothing
        local Fade a = Fade.create()
        set a.anchor = GetTriggerUnit()
        set a.ticks = 0
        call TT_Start(function Fade.Do,a)
    endfunction
    
    private function FailSafe takes nothing returns boolean
        return true
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
        exitwhen i &gt; 15
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function FailSafe))
            set i = i + 1
        endloop
        
        call TriggerAddAction(t,function FRA)
        call TriggerAddCondition(t,Condition(function FRC))
    endfunction
endscope

CSData
JASS:

library CSData

    //****************************************************************************************************
    // CSData 15.2
    // ¯¯¯¯¯¯¯¯¯¯¯
    // CSDatas are like UserData in units and items, they are faster than gamecache unless you have more
    // than 8191 handles in your map. In that case it would be a little slower but only for those
    // handles. And if you have more than 8191 handles your map is too slow already anyways.
    //
    // Notice that for public spells or systems to be distributed you should only use these
    // for private objects (those who the mapper would never have access to) If you are making something
    // for your map you can use them wherever you want.
    //
    // Best to be used in conjunction to CSArrays so you just specify an array id for a handle.
    //
    // DO NOT USE THIS ON THESE HANDLE TYPES: -lightning, -ubersplat, -image, -texttag,
    //                                        -any &#039;argument&#039; handle (like playerstate, damagetype, etc)
    //
    //****************************************************************************************************

    //====================================================================================================
    globals
        private constant integer MAX_HANDLE_ID_COUNT = 50000
        // values lower than 8191: very fast, but very unsafe.
        // values bigger than 8191: not that fast, the bigger the number is the slower the function gets
        // Most maps don&#039;t really need a value bigger than 50000 here, but if you are unsure, leave it
        // as the rather inflated value of 408000
    endglobals

    //=================================================================================================
    // a.k.a H2I, changed name to CS_H2I to prevent conflicts with other systems, it then stayed that
    // instead of changing to a private or public function since many outside spells use it.
    //
    function CS_H2I takes handle h returns integer
        return h
        return 0
    endfunction

    //==================================================================================================
    globals
        private integer array csdata[MAX_HANDLE_ID_COUNT]
        private constant integer MIN_HANDLE_ID=0x100000
    endglobals

    //It is dependent on jasshelper&#039;s recent inlining optimization in order to perform correctly.
    function SetCSData takes handle h, integer v returns nothing
        debug if(CS_H2I(h)-MIN_HANDLE_ID&gt;=MAX_HANDLE_ID_COUNT) then
        debug     call BJDebugMsg(&quot;SetCSData: Handle id too big, increase the max handle id count or use gamecache instead&quot;)
        debug endif
        set csdata[CS_H2I(h)-MIN_HANDLE_ID]=v
    endfunction

    function GetCSData takes handle h returns integer
        debug if(CS_H2I(h)-MIN_HANDLE_ID&gt;=MAX_HANDLE_ID_COUNT) then
        debug     call BJDebugMsg(&quot;SetCSData: Handle id too big, increase the max handle id count or use gamecache instead&quot;)
        debug endif
        return csdata[CS_H2I(h)-MIN_HANDLE_ID]
    endfunction

endlibrary
JASS:
 

Attachments

  • Spell Test Map Template - GRASSY.w3x
    144.3 KB · Views: 285

Varine

And as the moon rises, we shall prepare for war
Reaction score
805
Blink Back and Flame Storm are the same videos.
 

Sim

Forum Administrator
Staff member
Reaction score
534
Upload an example map featuring the spells.
 

Romek

Super Moderator
Reaction score
963
Did you have to align the text to the right? It makes it awfully annoying to read.
All of the spell triggers are registered for players 0-11. What if a computer player wanted to use the spell?

I'll have a better look once you've uploaded a demo map.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Corrected.

Sorry about forgetting to post map, wanted to get it up before I went to sleep and rushed it. :)
 

Trollvottel

never aging title
Reaction score
262
From nuke:

call IssuePointOrder(d,"move",GetLocationX(l),GetLocationY(l))
call TriggerSleepAction(DistanceBetweenPoints(q,l)/GetUnitMoveSpeed(d))

>.< use timers and and SetUnitX/Y please.


oh and you used UnitDamagePoint which Desyncs on Macs i think.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Why use a timer when I have absolutely no need to?

And I used UnitDamagePoint for a good reason.
 

Trollvottel

never aging title
Reaction score
262
>Why use a timer when I have absolutely no need to?

waits are inaccurate...



>And I used UnitDamagePoint for a good reason.

So you want to Desync mac users? ;)
 

Romek

Super Moderator
Reaction score
963
> No...
Yes...

> I hate Macs with a passion.
That doesn't matter. Your spells need to 'work' for macs too.
 

Romek

Super Moderator
Reaction score
963
Well, you tend to not notice the difference when the waits are quite long anyway.
But TSAs are inaccurate by about 0.1 to 0.3 seconds. So they're completely useless for periodic movements.

Using them is fine if it doesn't need to be super-precise, or a very short time.
 

Azlier

Old World Ghost
Reaction score
461
Waits also keep ticking while the lag window is up. Some spells that depend on waits can become very rigged with a laggy game :rolleyes:.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
I'll go ahead and implement a non-leaking PolledWait, will that sastify you guys?
 

Sim

Forum Administrator
Staff member
Reaction score
534
> I'll go ahead and implement a non-leaking PolledWait

PolledWait calls TriggerSleepAction.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
I thought it used a timer! What function uses a wait that isn't affected by lag?
 

Azlier

Old World Ghost
Reaction score
461
Well, there is none. Polled wait uses a timer that tries to correct TriggerSleepAction(). Timers are much, much better.
 
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