Spell Spells - Multi-Unit Instanceability (MUI)

Tom Jones

N/A
Reaction score
437
Did you use Vexorians wehelper to declare the global inside the trigger? Actually even if you used wehelper, I still don't get what you did :p
 

Chocobo

White-Flower
Reaction score
409
Did you use Vexorians wehelper to declare the global inside the trigger? Actually even if you used wehelper, I still don't get what you did :p

Never mind. Just ignore it.

I used the normal WE from a friend's computer, because I can't save any map correctly without that map gets corrupted and deleted.

Variable Editor -> Declared a unit called unit
Trigger Editor -> Untitled Trigger 001 -> Actions -> Custom script: local unit udg_unit
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
>The game engine then creates a new trigger in the old triggers place, containing the same events, conditions, and actions
It doesn't create a new jass trigger and how the wc3 engien handles the executions of events is afaik pretty much unknown. Source or stop spreading lies.

>Target Unit Of Ability Being Cast
Sorry doesn't work after waits at all, so you can't say it's mui. Well, it's even worse than not being mui...

>We can conclude that Event Responses are MUI, even after long waits.
Try a 120 second wait and see what happens, the unit is decayed and doesn't excist any more :)

Conclusion: You can't always trust the event responses to be usefull after waits. You maybe should mention that.

>Group Responses:
There is no wait in that trigger so I don't understand how it can prove something to being mui. In fact, you can't use waits in a ForGroup callback...

Looks like a pretty usefull tutorial, the examples does a good job explaing why not having mui triggers is a problem.
 

Tom Jones

N/A
Reaction score
437
>It doesn't create a new jass trigger and how the wc3 engien handles the executions of events is afaik pretty much unknown. Source or stop spreading lies.

I don't care what the engine does, as long as people understands what I'm trying to explain. That was the easiest possible way I could think of.

>Target Unit Of Ability Being Cast
Very true, I'm going to update that as soon as possible.

>Try a 120 second wait and see what happens, the unit is decayed and doesn't excist any more
Yep, but that's kinda obvious isn't?

>There is no wait in that trigger so I don't understand how it can prove something to being mui. In fact, you can't use waits in a ForGroup callback...

I'm proving that picked and matching unit is MUI, I also state that you can't have waits in ForGroup calls, which is a lie. You can use ExecuteFunc() inside a ForGroup() calls callback function.

>Looks like a pretty usefull tutorial, the examples does a good job explaing why not having mui triggers is a problem.

Tyvm.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
>You can use ExecuteFunc() inside a ForGroup() calls callback function.
ExecuteFunc creates a new thread so it's not part of the callback.
Does the picked unit work outside of the callback thread, and after a wait in that thread?
Anway, proving that something is mui without having some kind of wait is impossíble so your example doesn't make any sence.

>Yep, but that's kinda obvious isn't?
The point is: You can't always trust the event responses after a wait, setting the unit name to a variable always work (but isn't mui) nut the event response doesn't always work.

>I don't care what the engine does
Neither do I. But you say that it creates a new trigger, which is false, unless it does it on the engien level (no jass trigger but something else), which is uknown.
 

Tom Jones

N/A
Reaction score
437
>Does the picked unit work outside of the callback thread, and after a wait in that thread?

Yep.

>Anway, proving that something is mui without having some kind of wait is impossíble so your example doesn't make any sence.

The trigger is getting executed by two units at the same time, if that isn't MUI the term has been redefined since I wrote the tutorial. I personally think that the example makes plenty of sense, and it's not getting changed.

>The point is: You can't always trust the event responses after a wait, setting the unit name to a variable always work (but isn't mui) nut the event response doesn't always work.

True, I'm going to add a explanation about the event responses that works properly, and clearly point out why you should allways stick with trigger unit when possible.

>Neither do I. But you say that it creates a new trigger, which is false, unless it does it on the engien level (no jass trigger but something else), which is uknown.

Indeed, I know I'm lying, but I got to explain the concept in a easy and understandable way.
 

2-P

I will work hard tomorrow
Reaction score
325
>"Also remember to null the global locals at the end of the trigger to avoid leaks,"

You should add that to your example trigger. Those who only used GUI before have probably no idea what they have to do.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
>The trigger is getting executed by two units at the same time, if that isn't MUI the term has been redefined since I wrote the tutorial. I personally think that the example makes plenty of sense, and it's not getting changed.

The trigger is mui, no doupt about it. However this trigger is also mui:
Code:
    Events
        Unit - A unit Dies
    Conditions
    Actions
        Set SomeUnit = (Triggering unit)
        Game - Display to (All players) the text: (Name of (Owner of SomeUnit))
Since you draw the conclusion that (Picked Unit) is mui should I draw the conclusion that global variables are mui?

If I put a wait there my trigger isn't mui, if you put a wait in your trigger the trigger stop working. Neither of them does prove anything about somethings mui.
Proving that GetEnumUnit is mui requires jass (since it requires ExecuteFunc).
 

Cohadar

master of fugue
Reaction score
209
This proves that global locals are MUI, and by adding a global local to the two triggers we also made them MUI. You can localize the same global in several triggers, and a localized global can be set to any value, without overridding the same localized global in other triggers. The only problem with localized globals is, that because of the Trigger Editors poor conversion form GUI to JASS, global locals can’t be used in the following:

In a If/Then/Else’s condition.
In a group condition.
Inside a group loop.
In a Conditional wait.

Also remember to null the global locals at the end of the trigger to avoid leaks, and note that for some reason beyond my knowlegde, only one variable type can be localized in each trigger, etc. two localized unit variables wouldn't work.

Ok this is not correct.
You were using a standard programming technique called variable shadowing but your lack of it's basic functioning stopped you from using it's full potential

Explanation:

We will imagine that you declared a global variable GlobalNumber of type integer and that you assigned it a value of 7

now when you do:
custom script: local int udg_GlobalNumber
you are not "localizing" global variable
you are making new local variable with the same name as global one
now if you assign this variable a new value in GUI
Set GlobalNumber = 5
it will NOT overwrite global variable, but you will instead have two variables with same name, one with value of 7 and one with value of 5
the value of 7 will not be accessible inside trigger,
and that is why you think if/then/else wont works

Actually it works perfectly well it just does not work as you espected

Things to remember, if you assigned your global variable a value
and then shadowed it ("localized it") you cannot use that value.

but any values you assigned after localization will work fine,
and all GUI functions with it will work fine.

OK so what is the point of shadowing then?
Well it has great use actually:

It goes like this:
you create a global variable with prefix L L_SomeVariable
you prefix it so you know it will be shadowed and it reminds you that it can be used in only 1 trigger

then when you localize it in trigger
from that point on you don't need to use JASS
you just write GUI code and don't worry a thing
after GUI code another custom script for cleaning the variable and thats it

So instead of having to write whole function in JASS you just added
one global variable (witch you swore never to use outside that 1 trigger)
and 2 lines of script code, and all the rest can be GUI

I intend to write a tutorial on this,
after I get from classes today

The reason I did not do it before is because I thought everybody knew about this, it is so obvious if you have some software knowledge

See ya tonight..
 

Tom Jones

N/A
Reaction score
437
>you are making new local variable with the same name as global one...

Ye, I know. Why didn't I explain it correctly? People without general editor and/or programming knowlegde should be able to understand what I'm talking about. Same thing goes for my explanation of triggers. I'll add a comment or something that points out the reason for giving fictionary explanations when I get the time.

>and that is why you think if/then/else wont works

No, that's why I know it wont work in a if/then/else. As you mentinoned WE thinks we're refering to the global variable, making our local global obsolete.

>OK so what is the point of shadowing then?
Well it has great use actually:...

I would personally recommend people to learn jass instead of using local globals.


Thanks for the comments, and good luck on your own tutorial :)
 

Kahem

New Member
Reaction score
2
i tried this but it failed, i dont know why
the error thing told me that "custom script: Local unit udg_AbyssUnit" is "Expected a code statement" and disabled my trigger.

Also how do you do that to a Point?
Local point udg_AbyssPoint ?
Local location udg_AbyssPoint ?
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
"Global locals" aren't possible any more, as of the 1.24 patch.

A work-around is to create a plain local variable and set it to your value (for my example, it's the target point of the spell being cast):
Trigger:
  • Custom Script: local location l = GetSpellTargetLoc()


Then, when you want to use it in GUI, set a global variable to equal the value of the local:
Trigger:
  • Custom Script: set udg_TempPoint = l


At the end, remove leaks as usual:
Trigger:
  • Actions
    • Custom Script: call RemoveLocation(l)
    • Custom Script: set l = null
 
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