System Stun System

Tukki

is Skeleton Pirate.
Reaction score
29
A rather simple stun system that allows the user to stun units for different durations with one ability.

Requirements:
  • vJass
  • A stun ability with 0 in duration time. (Included in map)
  • A custom buff for above spell. (Included in map)
  • A dummy unit. (Included in map)
  • Basic JASS knowledge.

Features:
  • User friendly.
  • Configurable options.
  • Uses an ability for stunning. Meaning no need for huge amounts of stun abilities.
  • Supports Custom Stun Protectors and Buff removing skills such as Dispel Magic.
  • Allows the user to stun the unit multiple times according to the WcIII stun (system?).

How to call the function: (Directly taken from the Read me Section inside the Documentation trigger)
JASS:

        call Stun_Unit( unit whichUnit, real whichDuration, boolean checkImmunity )
        
        unit whichUnit = The unit you want to stun for X duration.
        real whichDuration = The X amount of seconds you want to stun the unit.
        boolean checkImmunity = Whether the system will ignore Spell Immunity/Custom Stun Protectors or not.


System Code: (~220 lines)
JASS:
//! textmacro SetGlobals
    //-------------------------------------------------------------------------------
    // Configurable Values
    //
    set Interval           = 0.05          // Timer interval. 
    set AID_UNLIMITED_STUN = 'A000'        // Stormbolt with 0 duration.
    set BID_UNLIMITED_STUN = 'B000'        // Above spell buff.
    set UID_DUMMY_UNIT     = 'h000'        // Dummy unit, wich casts above spell.
    set OS_STORM_BOLT      = "thunderbolt" // Order string of Stormbolt.
    
    //set SpellsIds[0]     = 'SpellId'     // This is if you have custom stun protection abilities 
                                           // and want the system to ignore units with them. 
     set NSpells           = 0             // Number of your custom stun protectors.
     
    //
    // End of Configuration
    //-------------------------------------------------------------------------------
//! endtextmacro
library Stun initializer InitTrig

//-------------------------------------------------------------------------------
// Keyword used to use un-initialized stuff.
private keyword Stuns

//-------------------------------------------------------------------------------
// Globals
globals
    private real           Interval                     = 0.05
    private integer       AID_UNLIMITED_STUN  = 'A000'
    private integer       BID_UNLIMITED_STUN  = 'B000'
    private integer       UID_DUMMY_UNIT       = 'h000'
    private string        OS_STORM_BOLT         = "thunderbolt"

    private integer array SpellIds
    private integer       NSpells 
    
    private timer         Timer = null
    private trigger       Trigg = null
    private integer array Datas
    private unit    array Check
    private integer       Counter = 0
endglobals

//-------------------------------------------------------------------------------
// Main loop for managing stun duration.
private function Periodic takes nothing returns nothing
 local integer i = Counter - 1
 local Stuns s = 0
    loop
        exitwhen i < 0
        set s = Datas<i>
        if (s.Duration &lt;= 0 or GetUnitAbilityLevel(s.Target, BID_UNLIMITED_STUN) &lt; 1) then
            call s.destroy()
            set Counter = Counter - 1
            if (Counter &lt; 0) then
                set Counter = 0
                call PauseTimer(Timer)
            endif
            set Datas<i> = Datas[Counter]
            set Check<i> = Check[Counter]
        else
            set s.Duration = s.Duration - Interval
        endif
        set i = i - 1
    endloop
endfunction

//-------------------------------------------------------------------------------
// Struct containing all values we need.
private struct Stuns
    unit Target
    real Duration
    effect Effect
    
    static group Pivot
    
    //-------------------------------------------------------------------------------
    // Search for getting struct from unit.
    static method Get takes unit whichUnit returns Stuns
     local integer i = Counter - 1
     
        loop
            exitwhen i &lt; 0
            if (Check<i> == whichUnit) then    
                return Datas<i>
            endif
            set i = i - 1
        endloop
    return 0
    endmethod
    
    //-------------------------------------------------------------------------------
    // Main core, allocates struct.
    static method create takes unit whichUnit, real whichDuration, string whichEffect, string whichPos returns Stuns
     local Stuns s
     local boolean b = true
     
        if (whichUnit != null) then
            if (IsUnitInGroup(whichUnit, Stuns.Pivot)) then
                set s = Stuns.Get(whichUnit)
                set b = false
                if (whichDuration &gt; s.Duration) then // Like the normal WcIII stun: if new stun is longer than the current, the swap.
                    set s.Duration = whichDuration
                endif
            endif
            
            if (b) then
                set s = Stuns.allocate()
                set s.Target = whichUnit
                set s.Duration = whichDuration
                if (whichEffect != &quot;&quot; and whichPos != &quot;&quot;) then
                    set s.Effect = AddSpecialEffectTarget(whichEffect, whichUnit, whichPos)
                endif
                set Datas[Counter] = s
                set Check[Counter] = whichUnit
                set Counter = Counter + 1
                call GroupAddUnit(Stuns.Pivot, whichUnit)
            endif
        else
            debug call BJDebugMsg(&quot;Stun System Error: whichUnit has input as null!&quot;)
        endif
    return s
    endmethod
    
    //-------------------------------------------------------------------------------
    // Creates the stun group.
    static method onInit takes nothing returns nothing
        set Stuns.Pivot = CreateGroup()
    endmethod
    
    //-------------------------------------------------------------------------------
    // Removes the unit from the group and removes stun.
    private method onDestroy takes nothing returns nothing
        call GroupRemoveUnit(Stuns.Pivot, .Target)
        call UnitRemoveAbility(.Target, BID_UNLIMITED_STUN)
        call DestroyEffect(.Effect)
    endmethod
endstruct

//-------------------------------------------------------------------------------
// Stuns the unit here for better readability in the function below.
private function DummyStun takes unit target returns nothing
 local unit u = CreateUnit(Player(15), UID_DUMMY_UNIT, GetUnitX(target), GetUnitY(target), 0)
       
    call UnitAddAbility(u, AID_UNLIMITED_STUN)
    call IssueTargetOrder(u, OS_STORM_BOLT, target)
    call UnitRemoveAbility(u, AID_UNLIMITED_STUN) 
    
    call ShowUnit(u, false)
    call KillUnit(u)
    set u = null
endfunction

//-------------------------------------------------------------------------------
// call Stun_UnitEx(&lt;YourUnit&gt;, &lt;YourDuration&gt;, &lt;IfCheckImmunity&gt;, &lt;YourEffect&gt;, &lt;YourAttachmentPos&gt;)
public function UnitEx takes unit whichUnit, real whichDuration, boolean checkImmunity, string whichEffect, string whichPos returns nothing
 local integer i = NSpells 
 local boolean b = true
 local Stuns s
     
     if (checkImmunity) then //&lt;- Check for magic immunity stuff.
        loop  
            exitwhen i &lt; 0
            if (GetUnitAbilityLevel(whichUnit, SpellIds<i>) &gt; 0) then
                set b = false
            endif
            set i = i - 1
        endloop
        if (IsUnitType(whichUnit, UNIT_TYPE_MAGIC_IMMUNE) == true) then
            set b = false
        endif
    endif
    
    if (b) then
        if (Counter == 0) then
            call TimerStart(Timer, Interval, true, function Periodic)
        endif
        set s = Stuns.create(whichUnit, whichDuration, whichEffect, whichPos)
        call DummyStun(whichUnit)
    endif
endfunction

//-------------------------------------------------------------------------------
// call Stun_Unit(&lt;YourUnit&gt;, &lt;YourDuration&gt;, &lt;IfCheckImmunity&gt;)
public function Unit takes unit whichUnit, real whichDuration, boolean checkImmunity returns nothing
    call Stun_UnitEx(whichUnit, whichDuration, checkImmunity, &quot;&quot;, &quot;&quot;)
endfunction

//-------------------------------------------------------------------------------
// call Stun_GetRemaining(&lt;YourUnit&gt;) returns &lt;RemainingDuration&gt;
public function GetRemaining takes unit whichUnit returns real
 local Stuns d = Stuns.Get(whichUnit)
 
    if (d != 0) then
        return d.Duration
    else
        debug call BJDebugMsg(&quot;Stun System Error: &quot; + GetUnitName(whichUnit) + &quot; is not stunned or input is null!&quot;)
        return 0
    endif
    return 0.
endfunction

//-------------------------------------------------------------------------------
// call Stun_ModifyDuration(&lt;YourUnit&gt;, &lt;DurationModifier&gt;)
public function ModifyDuration takes unit whichUnit, real whichModifier returns nothing
 local Stuns d = Stuns.Get(whichUnit)
 
    if (d != 0) then
        set d.Duration = d.Duration + whichModifier
    else
        debug call BJDebugMsg(&quot;Stun System Error: &quot; + GetUnitName(whichUnit) + &quot; is not stunned or input is null!&quot;)
        return
    endif
endfunction

//-------------------------------------------------------------------------------
// Function that prints some information.
private function DisplayInfo takes nothing returns nothing
    debug call DisplayTextToPlayer(Player(0), 0, 0, &quot;Running Stuns: |cffffcc00&quot; + I2S(Counter) + &quot;|r&quot;)
endfunction

//-------------------------------------------------------------------------------
// Starts or system.
private function InitTrig takes nothing returns nothing
    //! runtextmacro SetGlobals()
    set Timer = CreateTimer()
    
    debug set  Trigg = CreateTrigger()
    debug call TriggerRegisterPlayerEvent(Trigg, Player(0), EVENT_PLAYER_END_CINEMATIC)
    debug call TriggerAddAction(Trigg, function DisplayInfo)
endfunction
endlibrary</i></i></i></i></i></i>


And the Documentation trigger:
JASS:
------------------------------------------------------------------------------------------------------------------------
[Stun System 1.1 - by Tukki]
------------------------------------------------------------------------------------------------------------------------

    Containes:
        Readme Section
            Some Info: 1.1
            Pros and Cons: 1.2
            User-provided functions: 1.3
            Using Stun Protectors: 1.4
        Implementation Section
            General: 1.1
            In Detail: 1.2
        Change Log
------------------------------------------------------------------------------------------------------------------------        
&#039;Readme Section&#039; 

    - Some Info - 1.1
------------------------------------------------------------------------------------------------------------------------
* This system has not only good sides. See cons and pros below.
* Uses an ability to stun units for unlimited duration. Then removes it after the specified duration.
* Is friendly for map makers as it suppors buff-removing skills such as Dispel Magic, and allows custom stun protectors.
------------------------------------------------------------------------------------------------------------------------
    - Pros and Cons - 1.2
------------------------------------------------------------------------------------------------------------------------
    Pros:
        + User friendly, Easy to use.
        + Some configurables.
        + Uses an ability for stunning.
        + No need for massive amounts of stun abilities anymore.
        + Support for custom-made stun protectors.
        + Supports buff-removing skills.
        
    Cons:
        - Uses an O(n) search in the Get method.
        - Uses an ability for stunning.
        - Not as instant as original WcIII stun.
        - Uses dummy units to cast the spell at your target.
------------------------------------------------------------------------------------------------------------------------
    - User-privided functions - 1.3
------------------------------------------------------------------------------------------------------------------------
    Functions provided to the user:
    
        * Stun_Unit( unit whichUnit, real whichDuration, boolean checkImmunity ) -&gt; nothing
        * Stun_UnitEx( unit whichUnit, real whichDuration, boolean checkImmunity, string whichEffect, string whichPos ) -&gt; nothing
        * Stun_GetRemaining( unit whichUnit ) -&gt; real
        * Stun_ModifyDuration( unit whichUnit, real whichModifier ) -&gt; nothing
        
        unit whichUnit = The unit you want to stun for X duration.
        real whichDuration = The X amount of seconds you want to stun the unit.
        boolean checkImmunity = Whether the system will ignore Spell Immunity/Custom Stun Protectors or not.
        string whichEffect = Path of the effect created on the stunned unit at whichPos point.
        string whichPos = Attachment point for above effect.
        real whichModifier = Value by which the duration of the stun will be changed for the unit.
------------------------------------------------------------------------------------------------------------------------
    - Using Stun Protectors - 1.4
------------------------------------------------------------------------------------------------------------------------
    1 - Create your ability. And remeber its rawcode.
    2 - Go to the Stun System trigger and make following:
    
    set SpellIds[&quot;&lt;ArrayNumber&gt;&quot;] = &quot;&lt;YourRawcode&gt;&quot;
    set NSpells = &quot;&lt;NumberOfProtectors&gt;&quot;
    
    Where &quot;&lt;ArrayNumber&gt;&quot; is a value that increases by 1 for every protector that you want the system to consider. Starts at 1.
    And &quot;&lt;YourRawcode&gt;&quot; is the abilitie&#039;s rawcode.
    &quot;&lt;NumberOfProtectors&gt;&quot; is the number of protectors that you want the system to know about.
    
    3 - Save and you are pretty much done, good sir.
------------------------------------------------------------------------------------------------------------------------
&#039;Implementation Section&#039;

------------------------------------------------------------------------------------------------------------------------
    - General - 1.1
------------------------------------------------------------------------------------------------------------------------
    * Copy the Unlimited Stun Spell and Unlimited Stun Buff spell/buff to your map. 
    * If you already have a dummy unit then DO NOT copy the one found in this map.
    * Copy the Stun System trigger to your map.
    * Change the AID_UNLIMITED_STUN to the Unlimited Stun Spell&#039;s rawcode in your map.
    * Change the BID_UNLIMITED_STUN to the Unlimited Stun Buff&#039;s rawcode in your map.
    * Save. And if no problems occur then congratulations.
    
------------------------------------------------------------------------------------------------------------------------
    - In Detail -
------------------------------------------------------------------------------------------------------------------------
    1.0 - Start off by copying the spell and buff to your map. They can be found in the Object Editor under
    Abilities /Netural Hostile/Units and at Buffs/Effects /Special/Buff. Save your map and open this one.
    
    2.0 - Skip this step if you already have a dummy unit in your map.
    If not, then copy the unit called dummy to your map. Save it and re-open this one.
    
    3.0 - Copy the Stun System trigger to your map and save it. If no problems occur then good job.
    Else re-copy it, if it still gives syntax errors etc. Contact me at TheHelper.net.
    
    4.0 - Open up the Object Editor in your map and look up the rawcodes of the Spell and Buff.
    And write them in the top-section (called Configurables) of the Stun System trigger.
    Save and test. If it works fine <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />, if not you might have to check your inputs and stuff.
------------------------------------------------------------------------------------------------------------------------    
&#039;Change Log&#039;

------------------------------------------------------------------------------------------------------------------------
    [20/07/08] - Version 1.0 released at TheHelper.net
    [20/07/08] - Hotfix. Updated to 1.0a.: Fixed overlapping stuns.
    [20/07/08] - Version 1.1 released at TheHelper.net: Added StunEx, GetRemaining and 
                                                        ModifyDuration functions. Also changed 
                                                        some of the code a little.
    
------------------------------------------------------------------------------------------------------------------------


Screenshot: Due to lack of effects from the system there're none.

Report bugs and suggestions to this thread.

EDIT: Update. More functions for the people!
 

Attachments

  • 0.w3x
    29.8 KB · Views: 227

Dr.Jack

That's Cap'n to you!
Reaction score
109
The code seems to be ok, leakless and optimized.
Just one question, could you explain me what is the difference between this system simply using GUI?

- Create dummy
- Add dummy stun
- Order dummy to stun target
- Wait X second
- Remove StunBuff from target
- Remove Dummy
 

Hatebreeder

So many apples
Reaction score
381
The code seems to be ok, leakless and optimized.
Just one question, could you explain me what is the difference between this system simply using GUI?

- Create dummy
- Add dummy stun
- Order dummy to stun target
- Wait X second
- Remove StunBuff from target
- Remove Dummy

Well,
If you wait, you won't have it MUI.
Which will fuck the Code up, and proberbly cause an Infinite Stun
 

Tukki

is Skeleton Pirate.
Reaction score
29
- Create dummy
- Add dummy stun
- Order dummy to stun target
- Wait X second
- Remove StunBuff from target
- Remove Dummy

1. It's not MUI. As Hatebreeder said.
2. It will "overwrite" when more ppl use it on the same unit.
3. This system allows pretty much, like support for users who may want to create their abilities that prevent units from getting stunned and Dispel abilities.
 

Tukki

is Skeleton Pirate.
Reaction score
29
A hotfix. I f***ed up the part where you increased an unit's duration. It's now being fixxed.

EDIT: FIXED :)
 

Dr.Jack

That's Cap'n to you!
Reaction score
109
1) Obviously a local/array would be used.
2) Simple If/Then/Else should solve the problem.
3) Same.

However, it seems like you are doing it all in the system, so it does save time...
Anyway, you answered (partially) my question, thanks. Seems like a nice system.
 

Tukki

is Skeleton Pirate.
Reaction score
29
1) Assuming I'm using array/local.?
Well, then I wouldn't really think you made it in GUI... (using locals, maybe shadowing could count as GUI but..)

2) Simple If/Then/Else should solve the problem.
That fixes the "overwriting" thing, but not that you are unable to re-stun units.

Basically you could create something like this in GUI. But not as efficient.

Thx for nice comments ppl <3
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
May I ask why on earth there is a textmacro for setting the globals?
 

Tukki

is Skeleton Pirate.
Reaction score
29
It makes it easier(?), in any case safer, for users to manage their settings as they are not direct touching the system :p
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
The values could be initialized (apart from the magic immune IDs which could be set anywhere else), but abusing textmacros for something like setting values of global variables seems highly unnecessary.
 

Tukki

is Skeleton Pirate.
Reaction score
29
Maybe, but it's not noticeable as it's done at the loading time. And initializing stuff at two separate places for the same system seems a bit odd.

EDIT: Code updated to version 1.1
 

Matrix

New Member
Reaction score
5
I dont think that for this small purpose (to stun unit and then remove buff) sm1 will use this huge system. But ,however good work and nice system.

P.S. did u do this sys earlier than I did Simple Stun System????
 

Tukki

is Skeleton Pirate.
Reaction score
29
I dont think that for this small purpose (to stun unit and then remove buff)
Well that's what the system is made for. And personally I'd rather use a robust system with some more features (and of course more lines) instead of a small system that you couldn't configure. And if you think this is huge then go ahead and check Item Ability Learn System (also made by me)..

P.S. did u do this sys earlier than I did Simple Stun System????
To be honest I created this system a while ago, but it was hard coded and not submit-ready, and when I saw your SSS then I though "What the heck?!" and submitted it.
 

Romek

Super Moderator
Reaction score
963
Wouldn't it be much simpler to just pause the unit and add a special effect?
That would also make the unit remember the order it was doing (You could make an argument for weather the unit should remember its orders or not)
 

Tukki

is Skeleton Pirate.
Reaction score
29
Maybe, but then as you say the unit will be paused -- wich works pretty much the same, only that it looks really awful compared to an ordinary stun..
 

RueK

New Member
Reaction score
11
Pretty noob code because you can make something like this in GUI with the same efficiency.

every noob could make such a system, tell us why do we need this? there are like 1 or 2 already posted on graveyard and btw this should be graveyarded too. unless you tell us what diferent thing your code can offers us.
 
Reaction score
333
Pretty noob code because you can make something like this in GUI with the same efficiency.

Make it then? This system provides a set of callable functions for managing stuns. Since you can not declare functions in GUI, you can not make this system in GUI. Besides, why should someone use GUI for something like this when Jass is a much better alternative?

every noob could make such a system, tell us why do we need this?

The point of the system is not that everyone "needs" to use it, but that if someone requires for whatever purpose an interface for creating and modifying dynamic stuns then they may use this system rather than having to script one themselves.

The idea behind resource submissions is that people are free to use them if they feel the need to.

there are like 1 or 2 already posted on graveyard and btw this should be graveyarded too. unless you tell us what diferent thing your code can offers us.

Why should the original poster answer to you when you have contributed nothing to this thread and only flame?
 

Tukki

is Skeleton Pirate.
Reaction score
29
Pretty noob code
Care to point out what?

every noob could make such a system
Not every GUI user could. And if so, why not you make one, to prove your statement? And as TheDamien said, you aren't allowed to create new functions in GUI..

GUI with the same efficiency.
No, seriously..

unless you tell us what diferent thing your code can offers us
Read first post?

I think TheDamien got pretty much, thx.
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
Why should the original poster answer to you when you have contributed nothing to this forum and only flame?

Fixed.

@RueK: After looking through your "Aggron Stonebreaker" codes I highly doubt you could recreate this in GUI with nearly the same effeciency.

@Tukki: Personally I find this somewhat useful for some people. Any decent JASS-coder could make this system, yet you're the one who made it. Keep up the good work.
 
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