• 🏆 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!

GUI Buff System (GBS) V. 1.43

I proudly present you:
The GUI Buff System (GBS)

This little system makes you able to create, modify, stack and to iterate through multiple buffs, enabling you to easily implement custom buffs via spellbooks within your game without much problems.

And it does this all with nothing more than a single loop and 2 hashtables.

Features:
- Creating buffs with a single trigger run
- Easily retreiving and modifying every buff a unit possesses managed by this system
- Multiple custom events that let you retreive when and how the buff vanished or applies
- Periodic Events inside Buffs: Easily retreive whenever a certain time within a buff vanished, making triggering poisons a piece of cake!
- Priorising of buffs: give Priorities to your buffs to easily find the one who is the best for spellstealing!
- Tagging: give Buffs tags so your triggers can always retreive them and can filter differnt buffs!
- independant stacking: I found a system which stacked by refreshing the duration of every instance of the buff, this system handles every buff as an object on its own, making running multiple buffs with different timers by each other!
- Pick every Buff of a unit. Like the "Pick every unit within x" action, you can retreive every buff on a target unit and modify its values or run other actions!
- Save multiple values within a buff. When you register a buff, you can adjust how many reals the buff should carry with it, making saving values like damage per second or others easy.
- Automatically preloading and disabling of your spellbooks
-And the best from all: completely made with GUI users in mind!

Requirements:
Unit Indexer by Bribe

Optional i can recommend to also use the Damage Event by Bribe (
Link)

Explanation:

This System is meant for advanced GUI Users who can use an advanced system for managing their buffs. This is build very modular, so it doesn't support more than saving values for you and creating, stacking and overall managing of your buffs. For any effects of your buffs, use the functions and events the system gives you.
In the Map are some examples how this System can be used. I will add more examples, modules and functions within this system over time.
The documentation inhibits many technical details about the structure of the code and how to implement and change spells to your liking.
I made this system so i can use it within a map of mine (Invasion on Az'kar), but since i didn't found a buff system which has this amount of modularity, i though it would be a good idea to post it on the hive.


Issues:
Ofc, this System isn't with its flaws.
There are some issues, but the foremost one:
You mustn't use the enumerate functions inside the Main Loop (inside the Events of the trigger).
This was also in the last version the case, just forgot to write it here.
This cannot be changed, since they are referring to the same data to read and manipulate data inside of the hashtable.
(Update from 1.0 to 1.1 : You can now create buffs inside the GBS_Events. Use the "GBS Apply Buff New" for this. The old Function was left inside the system for compatiblity reasons)

Due to the nature of buffs made of spellbooks, the buff-icon does not fade out when the timer runs out. This is a feature i cannot retreive within the engine (WC3 is quite pricky when its about messing with the interface)

I have made some changes within the system, which can affect buffs you created with the system. Here are the compatibility issues:
Two things have to be considered when updating your version from 1.0 to the current one:

-When you use "Pick every Buff", the trigger now considers if GBS_Condition1 or GBS_Condition2 have some values in them.
-The Function "Pick every Buff" and "Pick Priority Buff" now sets the condtions to 0 to evade collisions with functions that are called afterwards. You may probably adjust that when you use these functions within loops or unit group calls.
- You can still use "GBS Apply Buff" in your triggers, but i highly recommend to use "GBS Apply Buff New", since it is safe with this function to create buffs within the main loop. Keep in mind that you need the GBS_C-Variables to run this instead of the GBS-Variables

Changelog:
V 1.0:
-Release

V1.1
-Added the use of the GBS-Conditions into the "GBS Pick Every Buff"
-Made "GBS Pick every Buff" and "GBS Pick Priority Buff" seting the Condition Integer to zero.
-Added considerations that are needed when updating the system to Version 1.1 from 1.0
-Moved the Updating of the Array Size from "GBS Allocate" to "GBS Loop" to catch Buff that were added in one of the GBS_Event Responses.
-Made it possible to create permanent bufs (till the death of the Unit). For this, set the Duration to exact -5.00
-Removed a Loop within "GBS Pick Every Buff" which cleaned the GBS_Buffcount-Array for no reasons
-Added a new batch of Variables to implement a Loop-Independant Buff Applying-Trigger:
-Now GBS_C_(Variable) (C for create) will be used for creating new buffs, while GBS_(Variable) is used to edit picked buffs
-Now it is able to create buffs within the Events with the "GBS Apply Buff New" function
-The Old function was left in case someone already used the system in his map.
-To Catch Buffs created by the new function, refer to the "GBS_Event became equal to 6.00"
-Added a new Event. "GBS_Event becomes equal to 7.00" refers to the first call of the Buff within the Loop. While "GBS_Event became equal to 6.00" is timely in line with the creation trigger, this one is called at the same time when all other buffs are run/cleaned up.
-Added a Changelog :)
-Added a Demo-spell called "Weave" (Credits go to Dota 2 for the idea *shame upon me*)

V1.2
- Swapped Unit Indexer with Unit Event
- fixed a bug which causes buffs that stack only with the same buff from other sources to stack completely independly
- fixed a buff that made a buff expire an isntance too early, which made buffs firering on uncertain intervals (e.g. a buff that should fire every 0,5 seconds for 5 seconds would fire 9 instead of 10 times)
- Added three new demo skills: immolation, stagger and ignite poison
- gave the TempInteger more descriptive names (Referring to the Main Loop)
- fixed a buff which made it impossible to apply permanent buffs

V1.3
-Split up the GBS Init Trigger into GBS Preload and GBS Initialize Buff. The Old Type of Initialisation should be workable either. Just keep sure to not add the buffs into the wrong order! (Or Add them like i did with the Demo-Spells. Then it doesnt matter.)
- Moved the Initialisation of the DEMO Buffs into their respective folder. Made them the Way you can register them in a order you want. They keep the Variables.

V1.4
-Added Module Support: You can directly now interact with the hashtable and save variables other than reals (like groups) into the hashtable
=> Unfortunally, this change caused that the system uses 2 hashtables instead of one.
- Added a demo-module: global group
- Added a new demo spell: Spirit Link

V1.41

-Removed a rare issue that caused newly created units to inherit buffs of units, but only when affected by a new buff, removed before from the game with buffs before dying (like artillery kills)
- You can now detect when a unit is removed from the game with a buff on it
-Added a baracks to the test map to create more testing units to test the skills better
-Added a remove unit on esc-press trigger to test allocation more properly

V1.42

-Fixed an issue in which buffs could not be allocated properly and not removed properly on occasion.

V1.43

-Fixed an issue with modules that caused buff instances in the hashtable to overriden with wrong information and potentionally causing memory leaks


Last words:
I would be happy to receive some feedback and ideas how i can improve the system. I will add more functions from time to time.


Edit: Changed Title to make the function more appearend
Contents

GBS Ver 1.43 (Map)

Reviews
KILLCIDE
Most of your functions include Saving and loading into the hash, so I skipped most of your code. With that in mind, I also didn't spend a lot of time checking these functions to make sure you were saving / loading the right things. Other than that...
Level 10
Joined
Oct 5, 2008
Messages
355
This system only manages buffs. In conjunction with bribes damage engine, you can remake most (if not all) orb effects and make them stackable, but this is only a possibility what can be done with this.
I add more examples in later versions.

The examples given works on any physical damage dealt. I cant recall if barrage does physical damage, but if it doesnt, then you need only to remove the condition in the demo trigger which checks if the damage dealt isnt magical. But then, it wpuld fire for any instance, like spells, if you dont implement other failsaves.
Edit: i curretly havent got access to my pc, so i cant check this for myself

Edit 2: Version 1.1 is up! Have gotten rid of the problem that you cannot create buffs within the main event and tweaked here and there and also added the option for infinite lasting buffs and another demo spell. Check it out if you want!
 
Last edited:
Level 10
Joined
Oct 5, 2008
Messages
355
Thanks, glad to hear you like it. :)
I'm probably going to add dummy caster support into the system, so things like silence/stuns or just the normal frenzy spell can be used within the systems structure. I also found that when units get transforned that the buffs need to be reaplied. So 1.2 should arrive around this weekend, depending on how much spare time i got :D.
 
Level 12
Joined
Jun 12, 2010
Messages
413
Well, there are a lot of other dummy caster and stun systems that can be integrated with yours (I was already thinking about a cool spell using my disable system and this). It would be more modular to just handle the buffs xP
You can also make the buff ability permanent instead of reapplying it. Though i think that may not work with spellbooks :S Why do you use spellbooks instead of tornado aura? :S
 
Last edited:
Level 10
Joined
Oct 5, 2008
Messages
355
You got a point there. Its already made the way that you can fit other systens into uts events. I shouldnt undermine this ^^.

I use spellbooks because you can add multiple abilities in it. This only gets usefull in corner cases. For example when you want to add an orb effect into the spellbook to change the projectile. Also things like permanent invisibility with a fade time of 0 can be added, thus creating invisibility and/or enhanced invisibility (that doesnt dispell on attack/cast). But these are only corner cases. I can enable an option which makes it able to use slow aura directly though. The only Difference would ve that these dont need to be disabled. This comes for sure into the next version. Thanks!
 
Level 12
Joined
Jun 12, 2010
Messages
413
Yeah, I was thinking it was maybe because of multiple abilties xD
Slow aura is good because you will only need half of the object editor data of an aura+spellbook combo.
This system is looking pretty good right now, it's similar to Effect Over Time, but is full GUI (which is pretty impressive, I wouldn't have the patience to deal with GUI for a big system like this) and a lot easier to use/understand. Also, I'm pretty sure EOT uses an array and is limited to 8192 buffs, while you're using a Hashtable here.
Looks pretty approvable to me, when you fix the transforming units issue. Just have to wait until the mods have time to make a review :)

Just one suggestion:
Use Bribe's Unit Event (in my signature) instead of his Unit Indexer. "The latest update to Unit Event makes it completely replaces GUI Unit Indexer (it's an inprovement on every level), so you only should use this system instead of Unit Indexer"
 
Level 10
Joined
Oct 5, 2008
Messages
355
Well, will quickly fix the transforming issue tomorrow (and also add in a function to detect whenever a buff gets overriden, so you can compare the old buff and the newly applied one against each other, but this will be one of these events in which you can again not create any new buffs).

Well i thought that if i make a System for GUI-Users, i make it completely in GUI, since then someoen can look into the code and try to understand what is acutally happening there. On the other hand i'm not that confortable with Jass so i take some time before i start uploading jass stuff here probably ^^.

Just looked quickly over EOT and indeed it works with an array although it connects a space in a hashtable for each effect. But both systems are different from each other. EOT has much more options, since it doesn't make the main ID's of the effects solid like this system does (mine system only allows the use predefined buffs, while this one could technically create effects and buffs at will). On the other hand, this makes it harder to use, since you have to customize it for yourself and manage the ID's for yourself, which is one of the main focus the GBS has.


I will replace the Indexer with the unit Event, thanks for the suggestion ^^.
 
Level 10
Joined
Oct 5, 2008
Messages
355
Version 1.2 is up!

Changelog:

V1.2
- Swapped Unit Indexer with Unit Event
- fixed a bug which causes buffs that stack only with the same buff from other sources to stack completely independly
- fixed a buff that made a buff expire an isntance too early, which made buffs firering on uncertain intervals (e.g. a buff that should fire every 0,5 seconds for 5 seconds would fire 9 instead of 10 times)
- Added three new demo skills: immolation, stagger and ignite poison
- gave the TempInteger more descriptive names (Referring to the Main Loop)
- fixed a buff which made it impossible to apply permanent buffs
- Made the main loop reapply the buff when the unit looses it (due to transformation)
 
Last edited:
Level 37
Joined
Jul 22, 2015
Messages
3,485
As mentioned in chat, I need you to do one thing before I can continue reviewing the system.

Needs Fixed

  • All though the way you have users add buffs into your system is okay, it can get ugly really fast. I would love for you to change this. My recommendation for you is to have a temp global variables users can store things into, followed by running a trigger that will then cache those variables into the index. Here is an example:

    • Custom Buff List
      • Events
        • Map initialization
      • Conditions
      • Actions
        • -------- Demo 1 --------
        • Set GBS_AddBuff = Venomed Spear
        • Set GBS_AddSpellBook = Buff: Venomed Spear (Spellbook)
        • Set GBS_AddIsPositive = False
        • Set GBS_AddSpace = 1
        • Set GBS_AddClass = 1
        • Set GBS_AddPriority = 1
        • Set GBS_AddStack = 1
        • Trigger - Run GBS Add Buff <gen> (ignoring conditions)
        • -------- Demo 2 --------
        • Set GBS_AddBuff = Fury Swipes
        • Set GBS_AddSpellBook = Buff: Fury Swipes (Spellbook)
        • Set GBS_AddIsPositive = False
        • Set GBS_AddSpace = 1
        • Set GBS_AddClass = 0
        • Set GBS_AddPriority = 2
        • Set GBS_AddStack = 3
        • Trigger - Run GBS Add Buff <gen> (ignoring conditions)
    • GBS Add Buff
      • Events
      • Conditions
      • Actions
        • Set GBS_MaxIndex = GBS_MaxIndex + 1
        • -------- ^ use this in place of GBS_Init_BuffAmount --------
        • Set GBS_Buff[GBS_MaxIndex] = GBS_AddBuff
        • Set GBS_SpellBook[GBS_MaxIndex] = GBS_AddSpellbook
        • Set GBS_Positive[GBS_MaxIndex] = GBS_AddIsPositive
        • Set GBS_Space[GBS_MaxIndex] = GBS_AddSpace
        • Set GBS_Class[GBS_MaxIndex] = GBS_AddClass
        • Set GBS_Priority[GBS_MaxIndex] = GBS_AddPriority
        • Set GBS_Stack[GBS_MaxIndex] = GBS_AddStack
        • -------- afterwards, you can reset the temp global variables to null, 0, etc --------

Suggestions

  • Nothing

Status

Awaiting Update
 
Level 10
Joined
Oct 5, 2008
Messages
355
Update of the System Version 1.3:
V1.3
-Split up the GBS Init Trigger into GBS Preload and GBS Initialize Buff. The Old Type of Initialisation should be workable either.
- Moved the Initialisation of the DEMO Buffs into their respective folder. Made them the Way you can register them in a order you want. They keep the Variables.
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Most of your functions include Saving and loading into the hash, so I skipped most of your code. With that in mind, I also didn't spend a lot of time checking these functions to make sure you were saving / loading the right things. Other than that, the code is okay for me, and the system seems to work properly from my tests. All though you add a lot of functionality to your system, I am afraid of the kind of learning curve this has on users. Thankfully, you were nice enough to put an extensive readme.

Needs Fixed

  • Nothing

Suggestions

  • Instead of using a function to check the number of units in GBS_Group in your loop trigger, you can use an integer counter to keep track of the number of units. Everytime you index or deindex a buff instance, you can increment or decrement the integer, while also checking whether or not it is 1 (turn on loop), or 0 (turn off loop). I personally think this is much better than checking it every GBS_Init_timer seconds
  • I would store the triggers you run in the code into variables so that when users import it into their map, they don't have to reactivate them in the code due to the Run Trigger function being disabled. They would only have to re-enable the variables you set the triggers to in the "Config" section

Status

Approved
 
Level 10
Joined
Oct 5, 2008
Messages
355
I'm flattered :) , and thank you @KILLCIDE for the review. Currently, before i go out with another upgrade, i'm collecting ideas what i could add into the system. So if anyone has any suggestions/bugs, go forward and write it here.

I'm think about addind a module support, so you can adjust the amount of intrinsic in buffs added effects/variables (e.g. groups to make an easy "spirit link" ability). This is possible since i have a hardcoded value in the hashtable (the 4 spaces used for the referenced unit, the duration, the fire-interval and the current fire-interval, i will then change that value to a variable to make adjustment possible). The linking would be done with a list with pointers. I'm also thinking about making it possible to have buffs fire multiple times per instance e.g. when you fast forward a buff for 3 sec. This is also easily implementable with a loop in the main trigger. The last update would be from changing for a "pick every unit" iteration to a "first of group" approach. But i need to look how it is implemented properly in jass.
 
Level 7
Joined
Jan 23, 2011
Messages
350
Making a FirstOfGroup iteration is better for instantaneous groups(like making thunderclap with triggs), is quite messy if you're using a group that won't be destroyed instantly, stick to ForGroup(AKA pick every unit in group and do)

I think adding some extra values to save like groups, lightnings, effects and even extra units could be helpful, specially for SpiritLink type buffs
 
Level 10
Joined
Oct 5, 2008
Messages
355
Update of the System Version 1.4:
-Added Module Support: You can directly now interact with the hashtable and save variables other than reals (like groups) into the hashtable
=> Unfortunally, this change caused that the system uses 2 hashtables instead of one.
- Added a demo-module: global group
- Added a new demo spell: Spirit Link

The handling of the system hasnt changed much at all, although it added many possibilities now, using and saving of the modules is directly fiddling with the structure of the hashtable. I have added an instruction on how to use them properly.
Warning: The outdated "Apply Buff" trigger doesnt support modules. I anyway highly recommend to use the "GBS Apply Buff new" trigger

Edit, i forgot to use @KILLCIDE 's suggestions fort hat version. So expect a new one coming soon ;D
 
Level 10
Joined
Oct 5, 2008
Messages
355
I have found a rather rare occuring isssue, which is why i never found it.

The issue was that units which gets instantly removed by either artillery/possession/other or the remove unit trigger weren't catched by the system. That means that when a unit with a buff was removed, its instance wasn't deleted and a unit that was created afterwards inherited the old unit buffs, but this would only come up when the unit was newly affected by a buff, else it wouldn'e be added to the systems main loop.

This issue was resolved in Version 1.41. There is a new event that catches units removed by these occasions with buffs, so you need to add that to your buffs when you want the system to catch these situations (before these weren't detected at all)

You can detect that via (GBS_Event = 7.00)
 
Level 10
Joined
Oct 5, 2008
Messages
355
2 Hashtables and 1 Unit Indexer, kind of an overkill? :p

Yeah, i rode myself in a corner with the structure of the data, using the indizes of the indexer as keys for the hashtable while stuffing further variables on different keys to prevent accidently overlap (probably due to not knowing on which positions the handle id's get created).
I probably could try to condense the hashes into one another and if i get to know the handle id generation could rebuild it in a way that it only needs a single hashtable. But for that i would need again to read into the code and fiddle bits out.
 
Level 10
Joined
Oct 5, 2008
Messages
355
I fixed a bug that screwed up the allocation of buffs.

It was a single line of code, but it cause the system to believe that a unit had less buffs then were really present. This caused all kind of weird behaviour. But most importantly when modules are used it could have caused memory leaks due to data not being catched by the "on alloc" functions. also, these buffs would still linger on the unit even when the system sees them as removed.


And the worst was that it was utterly unreproduceable. In fact, the number of buffs a unit was supposed to have was set to the custom value of the cause of the last buff, increased by 1. So the setup was even under testing conditions completely random. And the problem would only show when many buffs were placed on multiple units at the same time by a unit with a low custom v alue.

Good thing im using this system in a complex project of mine, so i have the chance to catch such corner-case bugs...
 
Level 10
Joined
Oct 5, 2008
Messages
355
Hi again,

I updated the system again.

There was a bug with the indexing of modules within the table that caused false information in the buff table that could bleed into the tables for the units, potentionally causing buffs to get wrongly transfered from one unit to the other. Also, this can potentionally cause memory leaks, which was fixed as well.
 
Level 7
Joined
Feb 9, 2021
Messages
301
Hi again,

I updated the system again.

There was a bug with the indexing of modules within the table that caused false information in the buff table that could bleed into the tables for the units, potentionally causing buffs to get wrongly transfered from one unit to the other. Also, this can potentionally cause memory leaks, which was fixed as well.
Hey, do you have a version that works for 1.26a? It seems like your system is exactly what I need for my project.
 
Last edited:
Level 6
Joined
Oct 31, 2015
Messages
95
I suppose this system does not cover the transformation problem. When a unit is transformed (Bear Form, Burrow, ...) it loses all abilities which the unit does not possess by default. Even if the timers keep track of the buff duration, any effects and the buff display are lost since the spellbook abilities are not preplace in the given unit. If this is the case (which I believe it to be) this would not be the only system lacking such feature.
 
Level 10
Joined
Oct 5, 2008
Messages
355
I suppose this system does not cover the transformation problem. When a unit is transformed (Bear Form, Burrow, ...) it loses all abilities which the unit does not possess by default. Even if the timers keep track of the buff duration, any effects and the buff display are lost since the spellbook abilities are not preplace in the given unit. If this is the case (which I believe it to be) this would not be the only system lacking such feature.
Hey there,

The system readds the buff to a unit if it in any way looses it (like morph, burrow and bear form). It also works with the permanent morph bug (giving a morph ability with the alternative being the current unit to a unit and removing it to transform the target permanently). For as long as the unit's ID does not change the system works consistent with transformations.

Hey, do you have a version that works for 1.26a? It seems like your system is exactly what I need for my project.

I believe hashtables were added with 1.24c with no more functionallity added to them after 1.26a i believe. So i think the system miiiiiiiiiight work with 1.26a. But honestly i would need to test that.
 
Top