System Status

Weep

Godspeed to the sound of the pounding
Reaction score
401
The stun spell is set to target Air, Enemy, Friend, Ground, Invulnerable, Neutral, Organic, Vulnerable. Wouldn't that prevent casting on mechanical units?

Invulnerable, Vulnerable ought to be sufficient.
 

Jesus4Lyf

Good Idea™
Reaction score
397
The stun spell is set to target Air, Enemy, Friend, Ground, Invulnerable, Neutral, Organic, Vulnerable. Wouldn't that prevent casting on mechanical units?

Invulnerable, Vulnerable ought to be sufficient.
100% correct. Updated and credit note updated. Thanks.

Mod review? :D
 

Hatebreeder

So many apples
Reaction score
381
100% correct. Updated and credit note updated. Thanks.

Mod review? :D

Hey Jesus, i got a question:
Is AddStun(Unit,Timeout) Stackable?
For instance; Lets say you "stormbolt" (using AddStun), and stun for 3 seconds. 1 Second later, someone else uses the same ability to stun. Will it Stun for 5 Seconds?
 

Hatebreeder

So many apples
Reaction score
381
AIDS stands in place of PUI - if you use PUI you can delete it and replace it with AIDS and keep pretending you have PUI. But then you can use AIDS resources. :)

(But you should read the documentation on this.)

Otherwise, yes they conflict.

Bummers ! >_<
 

quraji

zap
Reaction score
144
That is now fixed (v1.1.3), I move for this to be approved. :thup:
:thup:

I actually really like this. Works well and is very simple (in interface and implementation). The only thing I would say it's missing is an AddTimedStun function. I can understand why you wouldn't want to include one, but it seems like an essential part of a stun system (as it will be how most stuns will be used).

So, I tweaked a version to add this functionality and fix something I saw as a possible issue. It also gave me a chance to play with the new [ljass]static if[/ljass]:
JASS:

library Stun initializer OnInit uses AIDS, DummyCaster, optional KT, optional TimerUtils
    globals
        public constant integer BUFF=&#039;Bstn&#039;
        private constant integer ABIL=&#039;Astn&#039;
        private constant integer OID_FIREBOLT=852231
    endglobals
    
    //====================================================================
    // AIDS struct for efficiently storing the &quot;level&quot; of stun for a unit.
    private struct StunData extends array
        integer level
        private static method AIDS_filter takes unit u returns boolean
            return GetUnitAbilityLevel(u,&#039;Aloc&#039;)==0
        endmethod
        private method AIDS_onDestroy takes nothing returns nothing
            set this.level=0
        endmethod
        //! runtextmacro AIDS()
    endstruct
    
    //====================================================================
    // Functions.
    public function IsUnitStunned takes unit u returns boolean
        return GetUnitAbilityLevel(u,BUFF)&gt;0
    endfunction
    
    function AddStun takes unit target returns nothing
        local StunData data=StunData[target]
        set data.level=data.level+1
        call IssueTargetOrderById(DUMMY,OID_FIREBOLT,target)
    endfunction
    
    /* qEdit: Added a check to make sure a stun is only &quot;removed&quot; from a unit if there is one present.
     *          This ensures that if a user accidentally uses RemoveStun extra times, it wont break.
     */
    function RemoveStun takes unit target returns nothing
        local StunData data=StunData[target]
        if data.level&gt;0 then
            set data.level=data.level-1
        endif
        if data.level==0 then
            call UnitRemoveAbility(target,BUFF)
        endif
    endfunction
    
    /* qAdd: adds following function and automatically implements either TimerUtils or KT if they are present in the map
     * function AddTimedStun(unit target, real time)
     *     -stuns &lt;target&gt; for &lt;time&gt;
     */
    static if LIBRARY_TimerUtils then
    // timer utils first, it&#039;s better for one-shot timers, right?
        private struct tu_data
            unit u
        endstruct
        
        private function tu_RemoveTimedStun takes nothing returns nothing
            local tu_data d = GetTimerData(GetExpiredTimer())
            call RemoveStun(d.u)
            call d.destroy()
        endfunction
        
        function AddTimedStun takes unit target, real time returns nothing
            local timer t = NewTimer()
            local tu_data d = tu_data.create()
            set d.u = target
            call AddStun(target)
            call SetTimerData(t, d)
            call TimerStart(t, time, false, function tu_RemoveTimedStun)
        endfunction
        
    elseif LIBRARY_KT then
    
        private struct kt_data
            unit u
        endstruct
        
        private function kt_RemoveTimedStun takes nothing returns boolean
            local kt_data d = KT_GetData()
            call RemoveStun(d.u)
            call d.destroy()
            return true
        endfunction
        
        function AddTimedStun takes unit target, real time returns nothing
            local kt_data d = kt_data.create()
            set d.u = target
            call AddStun(target)
            call KT_Add(function kt_RemoveTimedStun, d, time)
        endfunction
    endif
    
    //====================================================================
    // Initialiser.
    private function OnInit takes nothing returns nothing
        call UnitAddAbility(DUMMY,ABIL)
    endfunction
endlibrary


Now of course you don't have to pay attention to this, but I thought I'd post it.

Once again nice little system.
 

quraji

zap
Reaction score
144
I agree, I don't think it's necessary to approval as the system is useful enough without the timed function. That doesn't make a self-expanding system any less cool though :p

Although I do think you should include the RemoveStun safety as I think it is plausible that someone call it too many times and put the stun level into the negative.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Bump for approval.

>Although I do think you should include the RemoveStun safety as I think it is plausible that someone call it too many times and put the stun level into the negative.

That should not be plausible - it could then remove stuns it didn't create... But I should add debug messages if you do this.
 

quraji

zap
Reaction score
144
That should not be plausible - it could then remove stuns it didn't create... But I should add debug messages if you do this.

Well the problem isn't just removing stuns that aren't aren't yours, but it's also that if there stun level is 1 and you accidentally remove it twice (or if the stun level is 0 for that matter), then you have a problem.

Attached is a test map that gives an example of what I mean (in a believable way).

Even if it's not likely it could happen, breaking stuns for that unit.
 

Attachments

  • Stun_test.w3x
    39.3 KB · Views: 316

Jesus4Lyf

Good Idea™
Reaction score
397
That's the situation in which you would want a debug message, and not just a set-to-0 instead of -1. Let's say you had a massive 30 second stun spell, casting that smaller spell would remove that big stun, and if you stunned the unit again right before the end, it would only last a fraction of a second. :)

That's why I intend to add the debug message, but not the protection (because the protection would allow the system to behave incorrectly - doesn't actually solve anything <_<).
 

quraji

zap
Reaction score
144
Let's say you had a massive 30 second stun spell, casting that smaller spell would remove that big stun, and if you stunned the unit again right before the end, it would only last a fraction of a second. :)

Not sure what you mean. All I know is that there should only be as many, or less, RemoveStun calls as there are AddStun calls, in total. If the stun level of a unit drops below 0 then something is wrong (and if it isn't fixed/prevented then future stuns for the unit may never work).
 

Jesus4Lyf

Good Idea™
Reaction score
397
I mean like...
JASS:
    function RemoveStun takes unit target returns nothing
        local StunData data=StunData[target]
        set data.level=data.level-1
        if data.level==0 then
            call UnitRemoveAbility(target,BUFF)
        endif
    endfunction

-->
JASS:
    function RemoveStun takes unit target returns nothing
        local StunData data=StunData[target]
        set data.level=data.level-1
        if data.level==0 then
            call UnitRemoveAbility(target,BUFF)
        debug elseif data.level&lt;0 then
            debug call BJDebugMsg(&quot;Stun Error - Removed more stuns than added.&quot;)
        endif
    endfunction

It is invariably going to be a code error that needs repairing, not just a user style that should be accepted. Therefore, a debug message, not a correction, is the best approach, imho. Does that makes sense?

An error like that should never be in a released version...
 

quraji

zap
Reaction score
144
>I mean like...

I understand the debug message, I just didn't understand your spell example :p


>It is invariably going to be a code error that needs repairing, not just a user style that should be accepted. Therefore, a debug message, not a correction, is the best approach, imho. Does that makes sense?

Yes I agree that the user shouldn't do it, but if he does, and never sees the debug message...


>An error like that should never be in a released version...

True, which is why you should prevent it in your code ;)

How about a check and a debug message, so they can fix it if they find it, but it won't be a problem if they don't catch it.
 
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