• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System] BuffGenerator

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
I recommend changing the ForEachBuff module (changes are highlighted):

JASS:
    // ForEachBuff Modules
    module ForEachBuff
        static method ForEachBuff takes unit enumUnit returns nothing
            local Buff this=total
    endmodule
    module ForEachBuffLoop
            @implement ForEachBuff@ //This way the above module is optional, because JassHelper only includes the first "implement"
            loop
                exitwhen this==0
                if UnitHasBuff(enumUnit,this) then
    endmodule
    module ForEachBuffNull
                endif
                set this=this-1
            endloop
    endmodule
    module ForEachBuffEnd
            @implement ForEachBuffNull@ //Same as the above
        endmethod
    endmodule

I think it's weird in one of your functions you declare a local variable "i" and then declare "this" which simply points to "i", is there a reason for it?
 
Level 4
Joined
Jun 9, 2011
Messages
91
I recommend changing the ForEachBuff module (changes are highlighted):

JASS:
    // ForEachBuff Modules
    module ForEachBuff
        static method ForEachBuff takes unit enumUnit returns nothing
            local Buff this=total
    endmodule
    module ForEachBuffLoop
            @implement ForEachBuff@ //This way the above module is optional, because JassHelper only includes the first "implement"
            loop
                exitwhen this==0
                if UnitHasBuff(enumUnit,this) then
    endmodule
    module ForEachBuffNull
                endif
                set this=this-1
            endloop
    endmodule
    module ForEachBuffEnd
            @implement ForEachBuffNull@ //Same as the above
        endmethod
    endmodule
Updated to v3.2 and implemented this.
Now can use too:
JASS:
implement ForEachBuffLoop
	// code here
implement ForEachBuffEnd

I think it's weird in one of your functions you declare a local variable "i" and then declare "this" which simply points to "i", is there a reason for it?
On ForEachBuff module "this" refers to current buff of the loop.

@edit
Thanks for the suggestion =) I didn't know that the JassHelper ignores the second implement
 
Last edited:
I have an awesome idea! :D
Instead of having a static integer inside the module, you can keep an integer array inside the library and do this:

JASS:
module BuffStruct

    static method operator buff takes nothing returns integer
        return Buff.index__q[thistype.typeid]
    endmethod

    // code bla bla ble

    private static method onInit takes nothing returns nothing
        set Buff.index__q[thistype.typeid] = InitBuff(AURAID, BUFFID, function thistype.m)
    endmethod
endmodule

typeid is a unique integer that is generated when you create a struct.
 
How? I'm removing an integer from your module and putting it in the struct so it doesn't get copied a bunch of times.
Plus, you already have an onInit method in there and onInit methods all get combined into one function after compiling.
And, that method operator is already present in your module and the typeid is there by default.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
API is a bit vague:

CountBuffs -> CountBuffsOnUnit

AddBuff -> UnitAddBuff

RemoveAllBuffs -> UnitRemoveBuffs

JASS:
    //You can change these to let the unit ID be the variable stored, and "GetBuffEventUnit" can just do "GetUnitById(buffID)".
    function GetBuffEventUnit takes nothing returns unit
        return eu
    endfunction

    function GetBuffEventUnitId takes nothing returns integer
        return GetUnitUserData(eu)
    endfunction

This provides a unique way of handling buffs. What I suggest for adding some utility is to maybe make a function to create a unique buff without having to use the module (ie. to split InitBuff into a public function without the code argument).
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I only see a couple of problems with this.

You aren't handling recursive events. As this stands, events fired inside of events will break =).

With vex's new optimizer released, the variable names should be changed to be readable. I plan to do this with all of my own resources at some point ;o.

This appears to be an excellent resource. I don't see any other problems for now ^_^.

+rep

edit
Ah, I now see problems o-o. Buffs != Abilities ; ). You have to add buffs using something like DummyCaster. Because of this, you'll have to store the buff levels and what not.

So this needs a little bit of rewriting to work correctly : ).

Well, actually, you could do abilities inside of spell books to make them appear as buffs, but that just seems like extra object editor data that you don't need. Also, keep in mind that auras do break EVENT_UNIT_IN_RANGE, so you shouldn't use them to apply buffs.

I think that this needs a bit more work and some more thought put into the design. It's almost there =o.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Nestharus said:
You aren't handling recursive events. As this stands, events fired inside of events will break =).

With "real" events recursivity problem is really easy to handle :

JASS:
call DisableTrigger(GetTriggeringTrigger())
// your code
call EnableTrigger(GetTriggeringTrigger())

Can't the same be used with Event ? (Note that i have not really thought about it)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
unit indexing events?

You don't want removed units not to deindex within a unit deindex event do you? What if you create a unit within a unit index event?

Also damage events. If you issue damage to a unit from an effect of the current damage, you want that damage to be modified by the triggers :\.

If DAMAGE_TYPE == fire, issue extra damage

like that ;o.


What if a buff removes other buffs, like negative buffs, and keeps negative buffs from being applied? You'd need the events to fire ; ).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Hmm, disable a trigger doesn't stop it, so it would work fine, or i'm missing something.

Damage events : for me the real good one is just to make all abilities cause 0 damage, and code every spells which make damage, this way you obvioulsy know what happens.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
RemoveUnit(u1) //fires event

Inside of the event
JASS:
//Remove all units owned by deindexed unit
loop
    //get next unit owned by u1
    call RemoveUnit(ownedUnit)

    //if you disable the deindexer here, the owned unit will not
    //be deindexed, meaning that you will leak indexes. The events
    //have to fire in order for the owned unit to be deindexed. This
    //code runs inside of a fire event, meaning that it needs proper
    //recursion handling so that the event can be recursively run within
    //itself like this example.

    //without recursion, you will not be able to remove any units within
    //a deindex event and you will not be able to create any units within
    //an index event
endloop

edit
In this case, you would not be able to remove buffs within remove events or add buffs within add events.

If you have buffs that depend upon other buffs and a key buff is removed, then you wouldn't be able to remove those other buffs w/o bugging up your events.
 
Top