HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Multi-instance considerations, please help!

08-18-2004, 05:14 PM#1
wheee
Hey,

I've been seeing this more and more lately upon looking at other people's triggers... but, could someone briefly go over the main things you should do or try to avoid when making a spell multi-instance-able, or multiplayer-capable.

For example, does using wait in triggers cause problems in multiplayer UMS games?

Another problem that I've been experiencing is the "delay" it takes a dummy caster to cast a dummy spell then to move to the next target and cast another dummy spell. For example, re-creating chain lightning... I have a rudimentary version made where a caster will cast a dummy chain lightning on a target, then calculate the damage on the target, then move to that target's location, and repeat - to give the chain effect.

However, I ran into two problems... first, the damage dealt to the target is accomplished before teh dummy caster is finished casting his dummy spell, thus cancelling the spell if damage is sufficient enough to kill the target. Second, if I don't use wait (0.6s) or more, then the dummy caster doesn't have enough time to cast his dummy chain lightning before moving, and therefore, you don't get to see the animation.

Can anyone give me any ideas on this? I want to avoid wait, as it slows it down and doesn't even look like chain lightning anymore.

Please help, thanks.
08-18-2004, 05:33 PM#2
Anitarf
When doing things multi-instanceable, you must basicaly just make sure you store any information hero-specific-wise. What that means is, use variable arrays, so every hero has a specific slot where he can store information (like target units etc...) without overwriting any information any other hero may have stored. The easiest way, when you have max one hero per player, is to just store any information for a hero under the index in the array that is equal to the player number of the owner of the hero.

A hero owned by player 4 would store any targets it needed to store in the variable TempUnitvariable[4], for example. But in the triggers, you don't write that, you don't write one trigger for each player, instead you write one trigger that stores the info on the target to TempUnitVariable[(player number of (owner of (casting unit)))].

The problem with waits here, however, is that any spells cast during a wait overwrite the "event response - casting unit", so any trigger that uses that after the wait can get screwed (unlike, when working with no multi-instancability, when you don't need such event responses much because everything is so specific). This, surprisingly, doesn't happen with "event response - summoning unit": if two heroes spawn a summoned unit one after another, then each trigger that runs on this event will remember it's own "summoning unit". That's why, when making a spell which doesn't really matter what it's based on, because you do all the effects with triggers, it can sometimes help to ase it on a summon spells.

These problems kind of become obsolete once you start using local variables, because they do exactly what "event response - summoning unit" does, they stay trigger-specific and aren't affected by events that happen while a trigger waits. But I'm not that far yet to be a user of local variables.

To get the caster to insta-cast, make sure you spawn him already facing the unit it is supposed to cast stuff on (or give him a faster turn rate) and, also, decrease his "art - animation - cast point" to 0.
08-18-2004, 07:21 PM#3
Vexorian
Quote:
Originally Posted by Anitarf
When doing things multi-instanceable, you must basicaly just make sure you store any information hero-specific-wise. What that means is, use variable arrays, so every hero has a specific slot where he can store information (like target units etc...) without overwriting any information any other hero may have stored. The easiest way, when you have max one hero per player, is to just store any information for a hero under the index in the array that is equal to the player number of the owner of the hero.

A hero owned by player 4 would store any targets it needed to store in the variable TempUnitvariable[4], for example. But in the triggers, you don't write that, you don't write one trigger for each player, instead you write one trigger that stores the info on the target to TempUnitVariable[(player number of (owner of (casting unit)))].

The problem with waits here, however, is that any spells cast during a wait overwrite the "event response - casting unit", so any trigger that uses that after the wait can get screwed (unlike, when working with no multi-instancability, when you don't need such event responses much because everything is so specific). This, surprisingly, doesn't happen with "event response - summoning unit": if two heroes spawn a summoned unit one after another, then each trigger that runs on this event will remember it's own "summoning unit". That's why, when making a spell which doesn't really matter what it's based on, because you do all the effects with triggers, it can sometimes help to ase it on a summon spells.

These problems kind of become obsolete once you start using local variables, because they do exactly what "event response - summoning unit" does, they stay trigger-specific and aren't affected by events that happen while a trigger waits. But I'm not that far yet to be a user of local variables.

To get the caster to insta-cast, make sure you spawn him already facing the unit it is supposed to cast stuff on (or give him a faster turn rate) and, also, decrease his "art - animation - cast point" to 0.
that's not true, event responses aren't global variables, they don't get overwritten.

Event Responses depend of the current instance of the trigger, likely Triggering Unit for instance doesn't change no matter how much waits you have, It will only return null if you remove that unit.

Spell Responses work during the effect of the event, likelly A unit begins casting / channeling an ability , will lose its responses after a wait, while A unit starts the effect of an ability will get event responses during the casting of the spell.
08-19-2004, 05:02 AM#4
wheee
Quote:
Originally Posted by Lord Vexorian
that's not true, event responses aren't global variables, they don't get overwritten.

Event Responses depend of the current instance of the trigger, likely Triggering Unit for instance doesn't change no matter how much waits you have, It will only return null if you remove that unit.

Spell Responses work during the effect of the event, likelly A unit begins casting / channeling an ability , will lose its responses after a wait, while A unit starts the effect of an ability will get event responses during the casting of the spell.

Hrmmm, can you give any more precautions to the use of wait, in making a trigger multiplayer-capable?

One thing I'm doing right now, is creating a unit to use it's animation then to remove it from the game. However, if I use it's "expiration timer", it won't fully remove the unit from the game (ie. if it's a hero, I get the hero dying-animation/sound)... so it was better to remove->unit ... but I need to use a wait timer to wait for the animation to be done before removing...

Do you forsee any problems with this?
08-19-2004, 06:03 AM#5
Anitarf
Quote:
Originally Posted by Lord Vexorian
that's not true, event responses aren't global variables, they don't get overwritten.

Event Responses depend of the current instance of the trigger, likely Triggering Unit for instance doesn't change no matter how much waits you have, It will only return null if you remove that unit.

Spell Responses work during the effect of the event, likelly A unit begins casting / channeling an ability , will lose its responses after a wait, while A unit starts the effect of an ability will get event responses during the casting of the spell.

In my experience from experimenting, when I had a trigger that displayed the name of the spell that was cast, waited 2 seconds, and displayed it again, that trigger displayed the name of some other spell after the wait, if that other spell was cast in that time. So, not only did it not display the name of the original spell that was cast, it actually displayed some other spell (instead of "default string" or something like that). It is true, however, that the spells were all insta-cast, I didn't try it with any channelings that would still last after those 2 seconds. You are probably right, but I'm still curious, if the trigger was just supposed to loose the "ability being cast" after it is complete, how come it also gained some other ability to display it's name? That would suggest global behaviour of the event response, at least on some level... I have to repeat these tests...
08-19-2004, 12:27 PM#6
Vexorian
Quote:
Originally Posted by Anitarf
In my experience from experimenting, when I had a trigger that displayed the name of the spell that was cast, waited 2 seconds, and displayed it again, that trigger displayed the name of some other spell after the wait, if that other spell was cast in that time. So, not only did it not display the name of the original spell that was cast, it actually displayed some other spell (instead of "default string" or something like that). It is true, however, that the spells were all insta-cast, I didn't try it with any channelings that would still last after those 2 seconds. You are probably right, but I'm still curious, if the trigger was just supposed to loose the "ability being cast" after it is complete, how come it also gained some other ability to display it's name? That would suggest global behaviour of the event response, at least on some level... I have to repeat these tests...
I don't think so, they aren't global variables, they are natives it could be that the first spell only lasted less than 2 seconds and the trigger that detected it didn't show anything, while the trigger that detected the other one showed the second spell
08-19-2004, 06:12 PM#7
Anitarf
I don't know, Lord Vexorian, I just did a test and I don't see the results conflicting with my theories. I don't dare claiming yet that I am absolutely right, though, but here are the test specifics, for your consideration:

Triggers:
Code:
EventResponseDetection
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
    Actions
        Game - Display to (All players) the text: ((Name of (Casting unit)) + ( cast info  + (Name of (Ability being cast))))
        Wait 3.00 game-time seconds
        Game - Display to (All players) the text: ((Name of (Casting unit)) + ( cast echo  + (Name of (Ability being cast))))
Code:
EventResponseDetection2
    Events
        Unit - A unit Spawns a summoned unit
    Conditions
    Actions
        Game - Display to (All players) the text: ((Name of (Summoning unit)) + ( summon info  + (Name of (Summoned unit))))
        Wait 3.00 game-time seconds
        Game - Display to (All players) the text: ((Name of (Summoning unit)) + ( summon echo  + (Name of (Summoned unit))))

And the practical results, when trying the triggers by having two units cast spells one after another, are the following (note that I tried it with channeling spells as well, so they were still lasting when the second spell was cast):
Code:
Priestess of the Moon cast info Starfall
Mountain King cast info Thunder Clap
Mountain King cast echo Thunder Clap
Mountain King cast echo Thunder Clap

Archmage cast info Summon Water Elemental
Archmage summon info Water Elemental
Blood Mage cast info Phoenix
Blood Mage summon info Phoenix
Blood Mage cast echo Phoenix
Archmage summon echo Water Elemental
Blood Mage cast echo Phoenix
Blood Mage summon echo Phoenix
Note how, when the echo for the first spell was supposed to be displayed, it displayed the info of the second spell? That's what I'm talking about. I'm attaching the map for you to inspect.

Edit: removing old, unnecesary attachments.
08-20-2004, 11:41 PM#8
Vexorian
I found that the ability responses are bugged , and act as a global variable but each event has its own global variable.

Have a pitlord and an archmage, the results in these 3 triggers are quite different:

Code:
Untitled Trigger 001
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
    Actions
        Game - Display to (All players) the text: ((1 + (Name of (Casting unit))) + (Name of (Ability being cast)))
        Wait 2.00 seconds
        Game - Display to (All players) the text: ((2  + (Name of (Casting unit))) + (Name of (Ability being cast)))

------------------------------------------------------------------

Untitled Trigger 001
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
    Actions
        Game - Display to (All players) the text: ((1 + (Name of (Triggering unit))) + (Name of (Ability being cast)))
        Wait 2.00 seconds
        Game - Display to (All players) the text: ((2  + (Name of (Triggering unit))) + (Name of (Ability being cast)))

------------------------------------------------------------------

Untitled Trigger 001
    Events
        Unit - Archmage 0068 <gen> Starts the effect of an ability
        Unit - Pit Lord 0070 <gen> Starts the effect of an ability
    Conditions
    Actions
        Game - Display to (All players) the text: ((1 + (Name of (Triggering unit))) + (Name of (Ability being cast)))
        Wait 2.00 seconds
        Game - Display to (All players) the text: ((2  + (Name of (Triggering unit))) + (Name of (Ability being cast)))

Try them, my conclusions are that they do act like a global variable but there is one for each event, they also seem to happen only with the ability responses.

Anyways the Generic Unit Starts the effect of an ability, actually creates 12 events for the trigger (1 per player) so if there is only one hero per player it shouldn't do much, but there is always the chance another unit have a spell, and it will overwrite the value.

Specific unit events seem to work, but they aren't recomended for use.

A fix in gui would be having a pack of global variables per ability, that will be one player / one heroe multi instancibility.

For other levels of multi instancibility, you'll be forced to use local variables
08-21-2004, 01:15 AM#9
Mythmon
also, i think accesing the gamecache resets the event event responses, at least Target unit of spell does, this screwed me up in my spell for an hour or two
08-21-2004, 02:03 AM#10
weaaddar
gamecache is not the culprit. I just stored the ability casting unit in gamecache without a hitch. My guess is you used a blizzard.j function which uses a wait in your code.
08-21-2004, 03:30 AM#11
Mythmon
no, i stored a string, not the unit, but anyways, im pretty sure thats why its not wokring, because i can put the action before the gamecache and it works, but put it after the gamecache action and it works, i havent thoroughly tested it, in fact, i havent tested it at all, but my logic is saying thats the reason
08-21-2004, 12:25 PM#12
Vexorian
I am pretty sure it is not the cause, my Spell Templates System, And AIAndy's spell classes wouldn't work well
08-21-2004, 07:14 PM#13
Anitarf
Anyway, the summon spawning event responses seem to work correctly after waits and other summons being spawned etc, so if you have any point targeting spell or notarget spell that has it's triggered effects over time, and you don't want to have to use special variables to store casting unit/target point of ability being cast, then use a summoning spell for the base and use the summon event responses.