System Status

Jesus4Lyf

Good Idea™
Reaction score
397
Let's say you had a massive 30 second stun spell, casting that smaller spell with a double remove at the end would remove that big stun, and if you stunned the unit again right before the big stun should end, it would only last a fraction of a second. :)
As said (bold bits added).
That would occur with your solution.
 

quraji

zap
Reaction score
144
>As said (bold bits added).

I got it now (it wasn't very clear without the bold parts..).

>That would occur with your solution.

That would occur anyways...plus you'd start permastunning units. And a permastun doesn't really make the code error more obvious (in fact if I were a novice coder I might even try adding more RemoveStun calls to try to fix it..).
I don't know, I guess I'd just rather not have things get permastunned and possibly ruin a game (imagine your hero gets this), if I didn't happen to catch it during map testing or whatever.

Either way it is an error and should be reported via debug message.

Edit: Hey another "static if" idea. This should fire events on add/removal of stuns, if Event is in the map :)
 

Jesus4Lyf

Good Idea™
Reaction score
397
If a unit is immune to stun it should not have the stun added - what you are asking is odd. In spells, the spell itself checks if the unit should be able to be under the effect of the spell. To have the system implement this kind of thing is overkill... Sure, I could add a whole subsystem which is just a group of untis which are stun immune and have AddStun return false if the unit is in the group. But the mapper can write a wrapper that does this anyway.

I could, perhaps, add a ClearStun/RestoreStun thing, which will be an entire reimplementation of this system within itself (think exactly what I've done, but to add a status of immunity, which also must be able to stack in a similar way, and when removed it checks to see if the unit should resume being stunned) but isn't this overkill? I mean, I like to write my systems to do as little as possible... if the mapper wants specific things like that, surely they're willing to code it... <_<

But perhaps this is a good idea. Along with implementing the timed stun stuff. Then we can have a timed unstun stuff too. Then we can implement all kinds of things people didn't want, and give them all the reason they need not to use it at all! :p

I think I'll do it when I get a chance: AddStunImmunity, RemoveStunImmunity, TimedStun and TimedStunImmunity. :(
I have to admit, it seems fairly useful.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
All I meant was a way to remove all stuns at any time. In Forest CTF, when a player captures the flag, abilities, life, mana, buffs, unit positions, etc. all get reset. With a ClearStun-like function, I could interrupt every ability on the maps' stun.

Or I could have an area affect spell which removes all stuns for units in the area.

etc.

I wasn't even thinking about being able to re-add the stun, all I really meant was a way to set the stun-count to 0. The timed stun type stuff wouldn't really be what I was interested in, you're absolutely right.
 

Jesus4Lyf

Good Idea™
Reaction score
397
See, that's difficult for the exact same reason I mentioned before to quraji.
Whatever function you set up to remove a stun is still going to fire, either setting the stun to negative or removing a new stun that was added prematurely (cannot solve both).

For your map then, that can't be solved without manipulating the timers associated with stuns, at which point you may as well add the RemoveStun call yourself for them.

I can, instead, allow the timed stun functions to return something which can be destroyed if you wish to end the stun prematurely. I could keep a list of these for all units which would allow you to destroy all timed stuns for a unit. :thup:

Hell, I can code everything for everyone who doesn't want to code anything and put it into one monstrous system which has so many features no one knows what they do, but that is "poor system design". However, this hasn't been approved in weeks so I will start adding random useless crap until a moderator smiles and says "ok". Imho, the system does as it should. It will be a pain to create a logical interface for timed stuns in any way because of things people associate with stuns, like effects.
 

Viikuna

No Marlo no game.
Reaction score
265
The best way is to have some buff system which handles all timed effects in your map.

Im actually making a one, whihc will porbably never be released, because Im lazy and I have too much other stuff going on so I havent done any wc3 stuff for a while really.

But anyways, when you have a proper buff system, it is easy to do stuff like this:

JASS:
scope RemoveBuffsWhenUnitDies
/*
This code is simply for removing buffs from untis that die
uses 0.0 timer, so you should be able to get buffs from dying units,
even if your death event triggers after this 
( Of course this can also be fixxed with some event system with priority events )
*/

private struct main
   unit unit
endstruct

private function Remove takes nothing returns nothing
    call RemoveBuff(GetEnumBuff())
endfunction

private function SomeOtherNiceLittleFunction takes nothing returns nothing
      local timer t=GetExpiredTimer()
      local main this=GetTimerData(t)
      if UnitHasAnyBuff(this.unit) then
          call ForAllBuffs(this.unit,Remove)
      endif
      call ReleaseTimer(t)
      call this.destroy()
endfunction

private function NiceLittleFunction takes nothing returns boolean
     local main this=main.create()
     local timer t=NewTimer()
     set this.unit=GetTriggerUnit()
     call SetTimerData(t,this)
     call TimerStart(t,0.0,false,function SomeOtherNiceLittleFunction)
     return false
endfunction

private function Init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddCondition(t,function NiceLittleFunction)
endfunction

endscope


Or possibly this:

JASS:
   

/*

 BuffClass is like group of bufftypes.
 Examples of buffclasses: PositiveBuffs, NegativeBuffs, ImbaBuffs

 Or for some elemental map: FireBuffs, EarthBuffs, WaterBuffs, AirBuffs.

 example:
call ClassAddBuffType(FireBuffs,InnerFire)
call ClassAddBuffType(PositiveBuffs,InnerFire) */

// Dispel:


if UnitHasBuffOfType(this.unit,NegativeBuffs) then
          call ForAllBuffsOfType(this.unit,NegativeBuffs,Remove)
endif

//edit. Actually, thats not how it would go, but anyways you get the idea...


edit. Anyways. My point is that theres nothing wrong with this method Stun uses. You just need to handle your timed effects better.


edit3. Removed that edit2 part because it contained some stuff that was kinda lol. Sometimes my brain just doesnt work properly.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Anyways. My point is that theres nothing wrong with this method Stun uses. You just need to handle your timed effects better.
Yep, my point too. If Stun does any more, I'm convinced its interface is confused. But this needs to be approved, so I'll start coupling things on that shouldn't be like timed stuns (and deprecate them from the moment they're released, disabled with static ifs). :thup:

Actually, a better idea, I'll write a second lib that uses Stun (and put it in the first post with it). Then I can please without stuffing up system roles, and allow things to require stuff. :thup:

I just think carefully about interfaces for these things. If one doesn't, they fail.
 

quraji

zap
Reaction score
144
Actually, a better idea, I'll write a second lib that uses Stun (and put it in the first post with it). Then I can please without stuffing up system roles, and allow things to require stuff. :thup:

Aw, I was already doing that >.>

But yes, please keep the current system the way it is. It's great in it's simplicity, even though it does come at a bit of a cost (the system is so simple that much of the work is left to the user, like timing the stuns, integrating them, adding effects, etc.). Extended library ftw (static if timed stun was cool but complicates the base system).
 

Jesus4Lyf

Good Idea™
Reaction score
397
Aw, I was already doing that >.>
If you'd like to work together on it, I'd be happy to...
We can discuss it here and share versions and ideas to come up with a good interface. I'm without WC3 most of the time. When we conclude on a reasonable implementation, I'll put the TimedStun lib in the first post.

Alternatively, (ideally) I'd have this approved alone, and let you write what you like.
But yes, please keep the current system the way it is. It's great in it's simplicity, even though it does come at a bit of a cost (the system is so simple that much of the work is left to the user, like timing the stuns, integrating them, adding effects, etc.). Extended library ftw (static if timed stun was cool but complicates the base system).
Yep. It also sucks because spells and that can't require it easily. Like, you'd need to set a flag inside the system and that... :confused:
 

quraji

zap
Reaction score
144
If you'd like to work together on it, I'd be happy to...
We can discuss it here and share versions and ideas to come up with a good interface. I'm without WC3 most of the time. When we conclude on a reasonable implementation, I'll put the TimedStun lib in the first post.

Alternatively, (ideally) I'd have this approved alone, and let you write what you like.

Well, this is what I had so far:
JASS:

library StunExtras requires Stun, optional TimerUtils, optional KT
    // CONFIG:
    globals
        private constant string DEFAULT_ATTACHPOINT = &quot;head&quot; // the default attachment point to use when none is specified
    endglobals
    // END CONFIG
    
    
    // static ifs don&#039;t like being in global declarations...      
    static if (not LIBRARY_TimerUtils and not LIBRARY_KT) then
        globals
            private constant boolean DO_CUSTOM = true
            private hashtable Table = InitHashtable()
            private constant key STUN_KEY
        endglobals
    endif
    
    private struct data
        unit u
        effect e
    endstruct
    
    private function RemoveTimedStun takes nothing returns boolean
        static if (LIBRARY_TimerUtils) then
            local timer t = GetExpiredTimer()
            local data d = GetTimerData(t)
            call ReleaseTimer(t)
            set t = null
        elseif (LIBRARY_KT) then
            local data d = KT_GetData()
        else
            local timer t = GetExpiredTimer()
            local data d = LoadInteger(Table, STUN_KEY, GetHandleId(t))
            call PauseTimer(t)
            call DestroyTimer(t)
            set t = null
        endif
        
        call RemoveStun(d.u)
        if (d.e!=null) then
            call DestroyEffect(d.e)
        endif
        call d.destroy()
        return true
    endfunction
    
    private function StartStunTimer takes real time, data d returns nothing
        static if (LIBRARY_TimerUtils) then
            local timer t = NewTimer()
            call SetTimerData(t, d)
            call TimerStart(t, time, false, function RemoveTimedStun)
            set t = null
        elseif (LIBRARY_KT) then
            call KT_Add(function RemoveTimedStun, d, time)
        else
            local timer t = CreateTimer()
            call SaveInteger(Table, STUN_KEY, GetHandleId(t), d)
            call TimerStart(t, time, false, function RemoveTimedStun)
            set t = null
        endif
    endfunction
    
    function AddTimedStun takes unit target, real time returns nothing
        local data d = data.create()
        set d.u = target
        set d.e = null
        call AddStun(d.u)
        call StartStunTimer(time, d)
    endfunction
    
    function AddTimedStunEffect takes unit target, real time, string fxpath returns nothing
        local data d = data.create()
        set d.u = target
        set d.e = AddSpecialEffectTarget(fxpath, d.u, DEFAULT_ATTACHPOINT)
        call AddStun(d.u)
        call StartStunTimer(time, d)
    endfunction
    
    function AddTimedStunEffectEx takes unit target, real time, string fxpath, string attachPoint returns nothing
        local data d = data.create()
        set d.u = target
        set d.e = AddSpecialEffectTarget(fxpath, d.u, attachPoint)
        call AddStun(d.u)
        call StartStunTimer(time, d)
    endfunction
endlibrary


I've tested it a bit and all functions seem to work fine in all 3 modes :thup:
 

Jesus4Lyf

Good Idea™
Reaction score
397
That is really cool.
JASS:
private function StartStunTimer takes real time, data d returns nothing

-->
JASS:
private function StartStunTimer takes data d, real time returns nothing

If you switch them, the KT call will inline. :)
But I'd actually embed this function with a textmacro (Lyncor style). :p
 

quraji

zap
Reaction score
144
>If you switch them, the KT call will inline. :)

Ah, good thinking (for what the one inline is worth :p).

>But I'd actually embed this function with a textmacro (Lyncor style). :p

Which? You mean like this?
JASS:

library StunExtras requires Stun, optional TimerUtils, optional KT
    // CONFIG:
    globals
        private constant string DEFAULT_ATTACHPOINT = &quot;head&quot; // the default attachment point to use when none is specified
    endglobals
    // END CONFIG
    
    
    // static ifs don&#039;t like being in global declarations...      
    static if (not LIBRARY_TimerUtils and not LIBRARY_KT) then
        globals
            private constant boolean DO_CUSTOM = true
            private hashtable Table = InitHashtable()
            private constant key STUN_KEY
        endglobals
    endif
    
    private struct data
        unit u
        effect e
    endstruct
    
    private function RemoveTimedStun takes nothing returns boolean
        static if (LIBRARY_TimerUtils) then
            local timer t = GetExpiredTimer()
            local data d = GetTimerData(t)
            call ReleaseTimer(t)
            set t = null
        elseif (LIBRARY_KT) then
            local data d = KT_GetData()
        else
            local timer t = GetExpiredTimer()
            local data d = LoadInteger(Table, STUN_KEY, GetHandleId(t))
            call PauseTimer(t)
            call DestroyTimer(t)
            set t = null
        endif
        
        call RemoveStun(d.u)
        if (d.e!=null) then
            call DestroyEffect(d.e)
        endif
        call d.destroy()
        return true
    endfunction
    
    private function StartStunTimer takes data d, real time returns nothing
        static if (LIBRARY_TimerUtils) then
            local timer t = NewTimer()
            call SetTimerData(t, d)
            call TimerStart(t, time, false, function RemoveTimedStun)
            set t = null
        elseif (LIBRARY_KT) then
            call KT_Add(function RemoveTimedStun, d, time)
        else
            local timer t = CreateTimer()
            call SaveInteger(Table, STUN_KEY, GetHandleId(t), d)
            call TimerStart(t, time, false, function RemoveTimedStun)
            set t = null
        endif
    endfunction
    
    //! textmacro StunExtras_Func takes effectstuff
        local data d = data.create()
        set d.u = target
        set d.e = $effectstuff$
        call AddStun(d.u)
        call StartStunTimer(d, time)
    //! endtextmacro
    
    function AddTimedStun takes unit target, real time returns nothing
        //! runtextmacro StunExtras_Func(&quot;null&quot;)
    endfunction
    
    function AddTimedStunEffect takes unit target, real time, string fxpath returns nothing
        //! runtextmacro StunExtras_Func(&quot;AddSpecialEffectTarget(fxpath, d.u, DEFAULT_ATTACHPOINT)&quot;)
    endfunction
    
    function AddTimedStunEffectEx takes unit target, real time, string fxpath, string attachPoint returns nothing
        //! runtextmacro StunExtras_Func(&quot;AddSpecialEffectTarget(fxpath, d.u, attachPoint)&quot;)
    endfunction
endlibrary
 

Viikuna

No Marlo no game.
Reaction score
265
That stuff just limits you more than helps you lol. ( in other words: it sucks )

Theres no flexibility.
What if you want to do what Darthfett said and remove all stun instances? Or what if you want to make all instances last 2 times longer or something?

What if I have some spell that turns unit in to a stone: ( stuns it, makes it grey and adds armor and hp regeneration. ) Now when I want to dispel all the negative buffs, I need to be able to tell difference between stuns caused by negative buffs and stuns caused by positive buffs.

( Or in some elemental map: stuns caused by buffs that belong to both frost class and negative class )


You just need a proper buff system for handling your timed effects.


Also abut this system: You either need to add at least silence, attack disable and movement disable ( all those are like parts of stun effect, in a way ) or make a own system for each one.

Second option sucks obviously, so just do the first one.
If someone needs a stun control like this, he will naturally need those other thingies too.
 

quraji

zap
Reaction score
144
That stuff just limits you more than helps you lol. ( in other words: it sucks ).

Okay. It was just supposed to be a simple extension, not a complex buff system. If it's not what you want go find one of those buff systems you're on about.
Sorry if that sounds rude, but there are plenty of times to use a simple timed stun without the need to ever dispel it or whatever. If no one ever needed simple timed stuns like this, then yeah it would suck, but I think they do...
Again, it's just a small extension to J4L's Stun system. Complex tracking and snare/silences and stuff isn't within it's scope.
 

Viikuna

No Marlo no game.
Reaction score
265
Sorry if that sounds rude, but there are plenty of times to use a simple timed stun without the need to ever dispel it or whatever.

I might be wrong, but I thought that the point of this system is to give control over stun stuff.
If you want a timed stun without power to modify it anyway, you can always use dummy caster and stormbolt.

Simple and limited system might feel a good idea when making just few spells at the time, but when you make a whole map, that "plenty of times" case is rarely the only case.
I just dont see any point in simple extension that works in 85% of time, when you still need that buff system for that remaining 15%, when you can as well do all with that buff system.

Also its a wrong approach in general IMO, since most of timed effects do more than just one thing at the time. Some timed effect might both slow and do damage overtime, or stun and reduce armor. Thats why its easier to handle these effects as somekind of packages, aka buffs.
 

quraji

zap
Reaction score
144
I might be wrong, but I thought that the point of this system is to give control over stun stuff..

The point of "this system" (I assume you mean Stun itself) is irrelevant, if you're trying to make a case against the code I did.

I fully understand that more complex effects require a more complex system, with more control. That still doesn't convince me that a simple (and feature void) set of TimedStun functions is useless.

Anyways, I think we should stop arguing in J4L's thread..
 

Viikuna

No Marlo no game.
Reaction score
265
Right.

Okay, I guess you like it simple. I myself have nothing against simple as long as it doesnt come with some terrible extra limitations.

But yea, I have stated why I find this timed stun thingy doing more harm than good, and you have made your point, so I guess we are done then, eh.


But anyways. Jesus4Lyf. Try not to miss that post where I suggest you to add silence and attack disable and that other useful stuff.
( Ofc you could create a separate libraries for each of those, but I dont really get why would you wanna do that. )
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top