Spell Lightning Totem

Sevion

The DIY Ninja
Reaction score
413
A quick spell I made in a few hours. Uses only like 66 lines plus lots of object editor stuff. I thought it was cool ;)

Plus, it's not super overpowered. (It seems like it is, but imagine holding the knights in the DoT field for as long as you can with 10000000 life :p

It may be a bit OP against summoned units because of the purge, but I haven't tested that so any input on that is welcome.

JASS:
/* Spell Information
===================================================================
Name: Lightning Totem
Version: 1.0
Author: Sevion

Requirements: NewGen v1.5d+

Installation:
 Copy Hero and Abilities over to your map adn the code.

Setup:
 Edit SPELL_ID, DUMMY_ID, MODEL_ID and DURATION.

Description:
------------------------------------------------------------------
 Creates a totem at the target area that spews lightning at enemies
 in the immediate area dealing damage, deals damage over time to
 enemies, and casts purge on all units in range. Issueing an order
 will cause the spell to disrupt and only the totem will be summoned,
 no damage over time or purge will ensue. The area damage disperses
 before the totem does and lasts only 3 seconds plus 1 for each level.
*/

scope LightningTotem initializer Ini
    globals
        constant integer SPELL_ID = 'AHfs'
        constant integer DUMMY_ID = 'ltdu'
        constant string  MODEL_ID = "units\\orc\\StasisTotem\\StasisTotem.mdl"
    endglobals
    
    private constant function DURATION takes integer lvl returns real
        return 10. + 5 * lvl
    endfunction
    
    private function PolledWaitCustom takes real duration returns nothing
        local timer t=CreateTimer()
        local real timeRemaining
        
        if(duration>0) then
            call TimerStart(t,duration,false,null)
            loop
                set timeRemaining=TimerGetRemaining(t)
                exitwhen timeRemaining<=0
                if(timeRemaining>bj_POLLED_WAIT_SKIP_THRESHOLD) then
                    call TriggerSleepAction(0.1*timeRemaining)
                else
                    call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
                endif
            endloop
        endif
        call DestroyTimer(t)
        set t=null
    endfunction
    
    private function onSpell takes nothing returns nothing
        local effect e
        local unit u
        if GetSpellAbilityId()==SPELL_ID then
            set e=AddSpecialEffect(MODEL_ID,GetSpellTargetX(),GetSpellTargetY())
            set u=CreateUnit(GetOwningPlayer(GetTriggerUnit()),DUMMY_ID,GetSpellTargetX(),GetSpellTargetY(),0)
            call PolledWaitCustom(DURATION(GetUnitAbilityLevel(GetTriggerUnit(),SPELL_ID)))
            call RemoveUnit(u)
            call DestroyEffect(e)
            set e=null
            set u=null
        endif
    endfunction
    
    private function Ini takes nothing returns nothing
        local trigger trig=CreateTrigger()
        local integer i=0x00
        
        call TriggerAddAction(trig,function onSpell)
        loop
            call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            set i=i+1
            exitwhen i==0x10
        endloop
        set trig=null
        call Preload(MODEL_ID)
        call PreloadEnd(.5)
    endfunction
endscope

scope Testing initializer Ini
    private function Ini takes nothing returns nothing
        call Cheat("iseedeadpeople")
        call Cheat("thereisnospoon")
        call CreateUnit(Player(0x00),'Hblm',0,0,0)
        call PanCameraTo(0,0)
    endfunction
endscope


And, I'm learning cJASS, so here's a cJASS version:

And yes, cJASS version has a lot more comments.

JASS:
/* Spell Information
===================================================================
Name: Lightning Totem
Version: 1.0
Author: Sevion

Requirements: NewGen v1.5d+, cJASS

Installation:
 Copy Hero and Abilities over to your map adn the code.

Setup:
 Edit SPELL_ID, DUMMY_ID, MODEL_ID and DURATION.

Description:
------------------------------------------------------------------
 Creates a totem at the target area that spews lightning at enemies
 in the immediate area dealing damage, deals damage over time to
 enemies, and casts purge on all units in range. Issueing an order
 will cause the spell to disrupt and only the totem will be summoned,
 no damage over time or purge will ensue. The area damage disperses
 before the totem does and lasts only 3 seconds plus 1 for each level.
*/

scope LightningTotem initializer Ini {
    //==============================
    // defines
    define {
        private void = nothing
        private int = integer
        private bool = boolean
        private float = real
        private DisplayText ( text ) = DisplayTextToPlayer(GetLocalPlayer(), 0, 0, text)
        private SPELL_ID = 'AHfs'
        private DUMMY_ID = 'ltdu'
        private MODEL_ID = "units\\orc\\StasisTotem\\StasisTotem.mdl"
        private DURATION ( hero ) = 10. + 5 * GetUnitAbilityLevel( hero, SPELL_ID )
    }
    
    //=============================
    // spell
    private void PolledWaitCustom ( real duration ) {
        timer t = CreateTimer() 
        float timeRemaining 
     
        if (duration > 0) {
            TimerStart(t, duration, false, null) 
            loop {
                timeRemaining = TimerGetRemaining(t) 
                exitwhen timeRemaining <= 0 
                 
                if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) {
                    TriggerSleepAction(0.1 * timeRemaining) 
                else 
                    TriggerSleepAction(bj_POLLED_WAIT_INTERVAL) 
                }
            }
        }
        DestroyTimer(t) 
        set t = null 
    }
    
    private void onSpell () {
        if GetSpellAbilityId() == SPELL_ID {
            effect e = AddSpecialEffect(MODEL_ID, GetSpellTargetX(), GetSpellTargetY())
            unit u = CreateUnit(GetOwningPlayer(GetTriggerUnit()), DUMMY_ID, GetSpellTargetX(), GetSpellTargetY(), 0)
            PolledWaitCustom(DURATION(GetTriggerUnit()))
            RemoveUnit(u)
            DestroyEffect(e)
            e = null
            u = null
        }
    }
    // end lightning totem spell
    //============================
    
    //============================
    // init    
    private void Ini () {
        trigger trig = CreateTrigger() ; TriggerAddAction(trig, function onSpell)
        int i = 0x00
        loop {
            TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            exitwhen ++i == 0x10
        }
        set trig = null
        Preload(MODEL_ID)
        PreloadEnd(.5)
    }
    // end init
    //============================================
}

scope Testing initializer Ini {
    private nothing Ini () {
        Cheat("iseedeadpeople")
        Cheat("thereisnospoon")
        CreateUnit(Player(0x00), 'Hblm', 0, 0, 0)
        PanCameraTo(0, 0)
    }
}


Screenie:
WC3ScrnShot_082309_201723_02.jpg

NOTE: Test is just a plain JASS version.

Comments?

Suggestions?
 

Attachments

  • Spell.w3x
    21.2 KB · Views: 193

Flare

Stops copies me!
Reaction score
662
Quick glance so far, might take a more detailed look soon (I'm still sleepy :])

JASS:
        if i==0x41486673 then
            if i==SPELL_ID then
                call onCast()
            endif
        endif

The first if block is redundant. Since i must equal 0x41486673 and SPELL_ID for the spell to work, then they must be the same figure (in your demo map), right? In that case, you can get rid of the first if. Also, if the spell is copied to another map, the rawcode may not be 0x41486673 (because this figure won't change regardless of the value set for SPELL_ID) so the spell automatically doesn't work...

Requirements: (N/A)
NewGen perhaps?
 

Sevion

The DIY Ninja
Reaction score
413
Oh, right >_<

Yeah, I always forget about NewGen requirements because I don't really ever put NewGen XD
 

Steel

Software Engineer
Reaction score
109
+rep for cJASS usage

Only reason I don't do it is because even less people will understand what I'm writing.
 

Sevion

The DIY Ninja
Reaction score
413
Well, just start making cJASS versions ;D Hopefully it'd spread it around. :D

So, any comments or suggestions on the spell/code? :p

Edit: Oh, I just realized I could move the actions into the conditions ;o
 

Viikuna

No Marlo no game.
Reaction score
265
Thats useless.

Most of that code is just some badly coded custom polled wait that is inlined in your spell code where you use it once.

Even if you used some timer system, like you should do in situations like this, this would still do nothing but create one unit, one effect and then destroy them few seconds later which is not enough for submitted spell, but maybe for a demostration about usage of whatever timer system you use.

edit. Well, the spell itself might be cool. ( I admit that I didnt test it ) The code just aint.
 

Sevion

The DIY Ninja
Reaction score
413
It's not always about the code is it? :p

Most of the spell is done in the object editor.
 

Sevion

The DIY Ninja
Reaction score
413
So. Liek bump?

I really fail to see the need for a timer system when the polled wait is fine >_> It works as it's supposed to and accuracy (in terms of 0.01 second(s)) isn't really needed. Can't even tell anyways.
 

Jesus4Lyf

Good Idea™
Reaction score
397
JASS:
    private function PolledWaitCustom takes real duration returns nothing
        local timer t=CreateTimer()
        local real timeRemaining
        
        if(duration&gt;0) then
            call TimerStart(t,duration,false,null)
            loop
                set timeRemaining=TimerGetRemaining(t)
                exitwhen timeRemaining&lt;=0
                if(timeRemaining&gt;bj_POLLED_WAIT_SKIP_THRESHOLD) then
                    call TriggerSleepAction(0.1*timeRemaining)
                else
                    call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
                endif
            endloop
            call DestroyTimer(t)
            set t=null
        endif
    endfunction

-->
JASS:
    private function PolledWaitCustom takes real duration returns nothing
        local timer t=CreateTimer()
        local real timeRemaining
        
        if(duration&gt;0) then
            call TimerStart(t,duration,false,null)
            loop
                set timeRemaining=TimerGetRemaining(t)
                exitwhen timeRemaining&lt;=0
                if(timeRemaining&gt;bj_POLLED_WAIT_SKIP_THRESHOLD) then
                    call TriggerSleepAction(0.1*timeRemaining)
                else
                    call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
                endif
            endloop
        endif
        call DestroyTimer(t)
        set t=null
    endfunction

Or
JASS:
    private function PolledWaitCustom takes real duration returns nothing
        local timer t
        local real timeRemaining
        
        if(duration&gt;0) then
            set t=CreateTimer()
            call TimerStart(t,duration,false,null)
            loop
                set timeRemaining=TimerGetRemaining(t)
                exitwhen timeRemaining&lt;=0
                if(timeRemaining&gt;bj_POLLED_WAIT_SKIP_THRESHOLD) then
                    call TriggerSleepAction(0.1*timeRemaining)
                else
                    call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
                endif
            endloop
            call DestroyTimer(t)
            set t=null
        endif
    endfunction
At least. :)
 

Tru_Power22

You can change this now in User CP.
Reaction score
144
It looks cool. Not going to test it right now though seeing as I need to wake up early tomorrow to go register for school. Seems good though.


(Am I the only one thinking that it needs a different icon?)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      • Ghan
        Administrator - Servers are fun

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top