• 🏆 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 SpellEvent v2.1.0.0

This resource provides GUIers with the ability to benefit from something like SpellEffectEvent by Bribe :)
I would like to give full credit to Bribe for this system because it's entirely based on his SpellEffectEvent!

The performance gain is incredible.
What it does is use only one trigger to evaluate one spell trigger rather than a thousand.
I coded it in GUI-Jass, so it doesn't require JNGP.

The GUI-Jass idea is Bribe's as well :)
GUI creates the variables automatically, and if you use custom scripts for most of the code, it turns out to be just as efficient as Jass ^_^

  • GUI SpellEvent
    • Events
    • Conditions
    • Actions
      • Custom script: local integer i = 1
      • -------- - --------
      • -------- Call the initialization function. --------
      • -------- - --------
      • Custom script: call ExecuteFunc("InitSpellEvent")
      • -------- - --------
      • -------- Creating the hashtable. --------
      • -------- - --------
      • Hashtable - Create a hashtable
      • Set SpellEventHash = (Last created hashtable)
      • -------- - --------
      • -------- Over here, I'm just looping through all the abilities to be registered and saving the triggers in a hashtable. --------
      • -------- - --------
      • Custom script: loop
      • Custom script: exitwhen udg_SpellEventAbility[i] == 0
      • Custom script: call SaveTriggerHandle(udg_SpellEventHash, udg_SpellEventAbility[i], 0, udg_SpellEventTrigger[i])
      • Custom script: set i = i + 1
      • Custom script: endloop
      • Custom script: endfunction
      • -------- - --------
      • -------- This function only evaluates and executes one trigger instead of evaluating a thousand triggers and executing one. --------
      • -------- - --------
      • Custom script: function OnSpell takes nothing returns boolean
      • Custom script: local trigger t = LoadTriggerHandle(udg_SpellEventHash, GetSpellAbilityId(), 0)
      • -------- - --------
      • -------- If the conditions return true, do the actions. --------
      • -------- If none of your spell triggers have conditions, you can optimize this system by deleting the 1st and 3rd custom scripts after this. --------
      • -------- - --------
      • Custom script: if TriggerEvaluate(t) then
      • Custom script: call TriggerExecute(t)
      • Custom script: endif
      • -------- - --------
      • Custom script: set t = null
      • Custom script: return false
      • Custom script: endfunction
      • -------- - --------
      • -------- This is the Initialization function of the entire system. --------
      • -------- - --------
      • Custom script: function InitSpellEvent takes nothing returns nothing
      • Custom script: local trigger t = CreateTrigger()
      • Custom script: call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
      • Custom script: call TriggerAddCondition(t, Condition(function OnSpell))
      • Custom script: set t = null
      • -------- - --------
      • -------- The only purpose of this is to automatically create the variables. --------
      • -------- - --------
      • Set SpellEventTrigger[0] = (This trigger)
      • Set SpellEventAbility[0] = Orb of Slow
      • -------- - --------
As you can see, this system is very short and easy to implement because all you have to do is:

1) Open up the trigger editor
2) Copy and paste the trigger to your map (Make sure you go to File >> Preferences and check "Create unknown variables when pasting trigger data")
3) Done!

  • SpellInit
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Set Abilities --------
      • Set SpellEventAbility[1] = Blizzard
      • Set SpellEventAbility[2] = MassTeleport
      • Set SpellEventAbility[3] = Summon Water Elemental
      • Set SpellEventAbility[4] = Holy Light
      • Set SpellEventAbility[5] = Resurrection
      • Set SpellEventAbility[6] = Divine Shield
      • -------- Set Triggers --------
      • Set SpellEventTrigger[1] = CastBlizzard <gen>
      • Set SpellEventTrigger[2] = CastMassTeleport <gen>
      • Set SpellEventTrigger[3] = CastSummonWaterElemental <gen>
      • Set SpellEventTrigger[4] = CastHolyLight <gen>
      • Set SpellEventTrigger[5] = CastResurrection <gen>
      • Set SpellEventTrigger[6] = CastDivineShield <gen>
      • -------- Run the Initialization Trigger --------
      • Trigger - Run SpellEvent GUI <gen> (ignoring conditions)
This will register your spells to the system. When a unit casts SpellEventAbility, SpellEventTrigger will run (while checking conditions in-case you need them.)

You don't need to check what ability is being cast in your spell trigger =)

  • You may not register more than one trigger for a spell.
    If you really want two triggers to run, then the solution would be to execute the second trigger in the first line of the first trigger's actions. Either that, or you could merge the triggers. There are no obvious examples of how two triggers registered to the spell effect event for the same spell is the only way to go.
  • Make sure you run the SpellEvent GUI trigger only once.
  • Don't touch any of the custom scripts unless instructed to do so within the comments.

  • v1.0.0.0
    • Release
  • v1.0.0.1
    • Simplified Implementation by making all variables Auto-create.
    • Added some comments.
  • v2.0.0.0
    • The whole system is now in one trigger only.
    • Faster and better way of registering spells to the system.
    • Added more comments.
    • Fixed possible bug.
  • v2.1.0.0
    • You don't need the count variable during registration any more.

Keywords:
spell, event, effect, spells, cast, system, event engine, engine, Bribe, Nestharus, Magtheridon96, DotA, naruto, omnislash, meathook, kamehameha.
Contents

Just another Warcraft III map (Map)

Reviews
Everyone should use this for their GUI spells.

Moderator

M

Moderator

Reviewed by Maker, GUI SpellEvent v1.0.0.0, 3rd Mar 2012

Everyone should use this for their GUI spells.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Neither do I. What does this do besides storing ability being cast into a global
 
If you assign "A unit starts the effects of an ability" to 400 triggers, you're creating 400 * 16 = 6400 spell effect events, and whenever a unit casts a spell, the conditions of all these 400 triggers will be evaluated (400 Trigger Evaluations :O)

With this, there will always be only 1 trigger evaluation/trigger execution per spell cast and only 16 spell effect events!

That's why this increases performance and keeps your FPS pretty high whenever a unit casts a spell!

Spell-spamming should never cause as much lag as it did ever again ;)
 
Level 14
Joined
Nov 18, 2007
Messages
816
You forgot to mention that with this, there can only ever be one trigger responding to a particular spells effect. You cant have two triggers responding to the same spell.
You can of course argue that having two triggers respond to the same spell is bad practice and id agree. But you didnt mention this limitation.

Also, the concept you follow originated in 2009 at thehelper.net and wc3c.net.
 
I acknowledged that, but I can't come up with any good reasons as to why someone would want two triggers to run when you cast 1 spell :/

I will update the description with a disclaimer and solution to the problem.

Also, the concept you follow originated in 2009 at thehelper.net and wc3c.net.

Yeah, I know the idea isn't new :3
 
All you need to do is remove the "A unit starts the effects of a spell" event from your spell trigger, and register your spell to the system like this:

  • Set SpellEventAbility = MyAbility
  • Set SpellEventTrigger = MyTrigger
  • Trigger - Run GUI SpellEvent (ignoring conditions)
And guess what, you don't even need to add conditions to check what the ability being cast is :)

edit
Updated.
Now has easier implementation.
The SpellEventAbility and SpellEventTrigger variables weren't auto-created before.
 
Level 12
Joined
Aug 12, 2008
Messages
349
I'm still not sure how to implement it. How if I want to register more than 1 spell?
Set it up right after I set up the first one?
  • Set SpellEventAbility = MyAbility
  • Set SpellEventTrigger = MyTrigger
  • Trigger - Run GUI SpellEvent (ignoring conditions)
  • Set SpellEventAbility = MyAbility2
  • Set SpellEventTrigger = MyTrigger2
  • Trigger - Run GUI SpellEvent (ignoring conditions)
EDIT: Ohh you updated it. I got it now. Thanks. Epic system :D
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Makes sense.

The only problem i have with it is, how would i get target of ability / unit target of ability?
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
this faster than useing special unit event?

i mean compared with this

for a=1 to 12
if player(a-1) is playing and player(a-1) is user then
add event udg_hero[a] cast spell
endif
endloop

another side i am glad coz i waited for this, for non vjass version :D
(i think here also cant use triggerspeel right?)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
I'm not going to filter out players who aren't users or aren't playing because some people could use those players for AIs and stuff :p

Everything that could've been done before, could be done here. (Including TriggerSleepAction)

ok ok but if we talk theoritical then useing specific unit events then it is faster for rpgs where only heroes can get that abilities?

another question it's use ability start effect right? so not begins casting an ability,right?

i asked the triggersleep thing coz once i checked last timer RegisterPlayerUnitEvent then there was problem with wait, no? i thought this work same way jass converted to jass from vjass
 
Last edited:
i asked the triggersleep thing coz once i checked last timer RegisterPlayerUnitEvent then there was problem with wait, no? i thought this work same way jass converted to jass from vjass

RegisterPlayerUnitEvent had a problem with waits because I didn't want it to be 2-3x slower :p

In this version, I'm forced to execute the trigger instead of just evaluating it because in GUI, you can't put all the code in the conditions block D:

ok ok but if we talk theoritical then useing specific unit events then it is faster for rpgs where only heroes can get that abilities?

The speed gain would be very marginal ;p
I don't want to complicate things and give users the ability to configure which players get registered to the system and which players don't D:
A user who has some knowledge of Jass could do that by himself and a GUI user would only loose an amount of speed so little, even Nestharus wouldn't care =P

another question it's use ability start effect right? so not begins casting an ability,right?

Yeah, it registers triggers to the start ability effect event.
This is because it's the most commonly used event for spells.
You don't need a system to handle the channel and begin cast events because typically, for every 100 or so spells, you might have 5-20 that use those events, so you wouldn't gain a worthwhile amount of performance ;/

You would gain performance, but not as much as you would with this ;P
 
Level 10
Joined
Aug 21, 2010
Messages
316
1.The system is very good...

2.This is absolutely unnecessary - set SpellEventTrigger = (ThisTrigger),set SpellEventAbility = Lesser Clarity Potion

3.The only thing that I personally do not like in this system is,constant repetition of the system trigger [Trigger - Run GUI SpellEvent <gen> (ignoring conditions)
] so I started working on this a bit and the result is excellent. Now only need one call system trigger.

4.OMG you gave me a good idea with this!!!

5.Sorry I forgot to say 5/5
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
1.The system is very good...

2.This is absolutely unnecessary - set SpellEventTrigger = (ThisTrigger),set SpellEventAbility = Lesser Clarity Potion

3.The only thing that I personally do not like in this system is,constant repetition of the system trigger [Trigger - Run GUI SpellEvent <gen> (ignoring conditions)
] so I started working on this a bit and the result is excellent. Now only need one call system trigger.

4.OMG you gave me a good idea with this!!!

5.Sorry I forgot to say 5/5

1) lolk?

2) Incorrect. Thats to automatically initialize those variables when copying and pasting into a map

3) Eh sorta true but its essentially the only way to do it besides having 8192 variables, which would lag even more

4) lolk?

5) lolk?
 
Or I could use an array and add 1 more variable to store the number of spells :3

  • -------- Set Abilities --------
  • Set SpellEventAbility[1] = Blizzard
  • Set SpellEventAbility[2] = MassTeleport
  • Set SpellEventAbility[3] = Summon Water Elemental
  • Set SpellEventAbility[4] = Holy Light
  • Set SpellEventAbility[5] = Resurrection
  • Set SpellEventAbility[6] = Divine Shield
  • -------- Set Triggers --------
  • Set SpellEventTrigger[1] = CastBlizzard <gen>
  • Set SpellEventTrigger[2] = CastMassTeleport <gen>
  • Set SpellEventTrigger[3] = CastSummonWaterElemental <gen>
  • Set SpellEventTrigger[4] = CastHolyLight <gen>
  • Set SpellEventTrigger[5] = CastResurrection <gen>
  • Set SpellEventTrigger[6] = CastDivineShield <gen>
  • -------- Set Number of Abilities --------
  • Set SpellEventCount = 6
  • -------- Run the Initialization Trigger --------
  • Trigger - Run SpellEvent GUI <gen> (ignoring conditions)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Or I could use an array and add 1 more variable to store the number of spells :3

  • -------- Set Abilities --------
  • Set SpellEventAbility[1] = Blizzard
  • Set SpellEventAbility[2] = MassTeleport
  • Set SpellEventAbility[3] = Summon Water Elemental
  • Set SpellEventAbility[4] = Holy Light
  • Set SpellEventAbility[5] = Resurrection
  • Set SpellEventAbility[6] = Divine Shield
  • -------- Set Triggers --------
  • Set SpellEventTrigger[1] = CastBlizzard <gen>
  • Set SpellEventTrigger[2] = CastMassTeleport <gen>
  • Set SpellEventTrigger[3] = CastSummonWaterElemental <gen>
  • Set SpellEventTrigger[4] = CastHolyLight <gen>
  • Set SpellEventTrigger[5] = CastResurrection <gen>
  • Set SpellEventTrigger[6] = CastDivineShield <gen>
  • -------- Set Number of Abilities --------
  • Set SpellEventCount = 6
  • -------- Run the Initialization Trigger --------
  • Trigger - Run SpellEvent GUI <gen> (ignoring conditions)

i prefer this because more with 1 line but less with alot run trigger line :p
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
@Magtheridon96/Bribe ty



rofl, i have over 50 variable array if not more and u dont see any lagg after initilizing

sorry but u dont know how its work in wacraft or just underestimate it

variable arrays dont matter. its the 8192 arrays that kill. I had about ~10 8192 variables in my map once and the game wouldn't run any user-defined triggers whatsoever because of a handle overload due to the array size
 
Level 4
Joined
Jul 17, 2011
Messages
55
If you assign "A unit starts the effects of an ability" to 400 triggers, you're creating 400 * 16 = 6400 spell effect events, and whenever a unit casts a spell, the conditions of all these 400 triggers will be evaluated (400 Trigger Evaluations :O)

With this, there will always be only 1 trigger evaluation/trigger execution per spell cast and only 16 spell effect events!

That's why this increases performance and keeps your FPS pretty high whenever a unit casts a spell!

Spell-spamming should never cause as much lag as it did ever again ;)

thanks for clearing that up, I will surely use this for my map, Good Job! :thumbs_up:
 
Level 10
Joined
Aug 21, 2010
Messages
316
Well, now this is much better
The way you do this a little different from my,but the basis is the same.
As for me personally, this should look like any system,simple and useful

Scoreboard
JASS VS GUI
10 - 0
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
variable arrays dont matter. its the 8192 arrays that kill. I had about ~10 8192 variables in my map once and the game wouldn't run any user-defined triggers whatsoever because of a handle overload due to the array size

then u made something really wrong coz i use alot array and dont ahve any problem, i mean i never got error from this also u can consider when u make a array its isnt 8192 size because u watched from ur thread too, when u create unit group array then u must create cgroup manually its mean other index's unused


i really doubt normally the arrays kill any map because u cant see any map without arrays
think about that before hashtable patch still was alot rpg and every map used arrays what was made in we :p

basically anyway u dont need array with 8192 size, u can use more array or if u use unit and others array and u scared about 8192 then u can null when unit die :p

arrays still better in alot case because u dont need extra function calls, dont need group (what mean also alot function call and check) also more readable and easier to use
 
@Illidans911:

Here's a tip to increase map performance when using arrays in GUI:
- If you always set the array sizes to 1, it won't make a difference at all ;)
Arrays in Warcraft III are defaulted to:
  • 0
  • ""
  • null
  • false
  • 0.00

Thus, setting the size to something other than 1 for any array would just add overhead to the map initialization.

The sizes are only useful when you're in need of default values.

edit

king_drift_alex said:
So, can it now be used ?

Yeah :3

Anyway:
Updated.
This is the final version.
I had one more idea to make this 100% bug-free even when the user doesn't read the instructions at all,
but then I realized that a user who doesn't read the instructions deserves what he's going to get :>
 
Last edited:
Level 11
Joined
Mar 27, 2011
Messages
293
All Their Functions that use of vJass Cause Errors in My World Edit Example: When a function and then Inactive Active, a message from the World's Edit Speaking Mistakes (More than 200 lines) and Non Allows Enable New Function because of errors.
Someone know Fix This?
 
Top