HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell.. Multiple Instances?

08-27-2004, 03:37 AM#1
HexenLordX
I'm having serious problems with spells being able to be cast by more than 1 hero at a time, and I'm guessing its because I do not know much about arrays.

For a basic trigger, I'll do something like this:

Code:
Untitled Trigger 001
    Events
        Unit - A unit Begins casting an ability
    Conditions
        (Ability being cast) Equal to Replacement
    Actions
        Unit - Replace (Triggering unit) with a footman using The new unit's max life and mana
        Set NewUnit = (Last replaced unit)
        Animation - Play (Last replaced unit)'s stand animation
        Wait 3.50 seconds
        Unit - Replace NewUnit with a captain using The new unit's max life and mana

Now in that 3.5 second wait, if another player casts this ability, the original caster's footman will not become a captain, instead it will continue to be a footman, and the second caster will not have to wait the full 3.5 seconds, but only the time that the original caster had left.


I didn't want to do something like:

Owner of Casting unit Equal to Player 1 Red, set NewUnit1 = Last replaced unit.
Owner of Casting unit Equal to Player 2 Blue, set NewUnit2 = Last replaced unit.

I heard arrays were an easy way out, because I have MULTIPLE spells that if one person is casting, another person cannot cast or all of the effects will happen to the first caster, or if one person casts and another person casts right away, the second unit will get all of the effects and such. Since the map I'm making will be for b.net, multiple instances of every ability is required, so I'm just wondering how I can go about doing this.
08-27-2004, 03:56 AM#2
Rafael Br
Set the casting unit into a local variable, do a normal variable for the spell, the use the custom script line:
local unit udg_(your variable)
You can use the variable as a normal one, use the set variable action to set it to the casting unit.
EDIT: if you use a loop, Pick every unit and if\Then\Else, the local will generate errors on the trigger, you will have to convert it into custom text, and adust these actions, if you know JASS.
08-27-2004, 04:03 AM#3
HexenLordX
Quote:
Originally Posted by Rafael Br
Set the casting unit into a local variable, do a normal variable for the spell, the use the custom script line:
local unit udg_(your variable)
You can use the variable as a normal one, use the set variable action to set it to the casting unit.
EDIT: if you use a loop, Pick every unit and if\Then\Else, the local will generate errors on the trigger, you will have to convert it into custom text, and adust these actions, if you know JASS.

Okay, I get what your saying about setting the variable to a local variable. I tried putting the script in but wasn't sure where it would go or how I would check the variable afterwards. What would the trigger above in the first post look like after adding this in?
08-27-2004, 04:12 AM#4
Rafael Br
like this:

Code:
Untitled Trigger 001
    Events
        Unit - A unit Begins casting an ability
    Conditions
        (Ability being cast) Equal to Replacement
    Actions
        Custom Script: local unit udg_NewUnit
        Unit - Replace (Triggering unit) with a footman using The new unit's max life and mana
        Set NewUnit = (Last replaced unit)
        Animation - Play (Last replaced unit)'s stand animation
        Wait 3.50 seconds
        Unit - Replace NewUnit with a captain using The new unit's max life and mana

It is just like this, put the custom script line on the first line of the trigger and use the variable as a normal one, exept for loops, if\then\else.
08-27-2004, 04:15 AM#5
HexenLordX
Quote:
Originally Posted by Rafael Br
like this:

Code:
Untitled Trigger 001
    Events
        Unit - A unit Begins casting an ability
    Conditions
        (Ability being cast) Equal to Replacement
    Actions
        Custom Script: local unit udg_NewUnit
        Unit - Replace (Triggering unit) with a footman using The new unit's max life and mana
        Set NewUnit = (Last replaced unit)
        Animation - Play (Last replaced unit)'s stand animation
        Wait 3.50 seconds
        Unit - Replace NewUnit with a captain using The new unit's max life and mana

It is just like this, put the custom script line on the first line of the trigger and use the variable as a normal one, exept for loops, if\then\else.


So basically you just put it at the beginning of the trigger and it works its magic from there? Sweet dude thanks, I'll give you some rep for that.
08-27-2004, 04:21 AM#6
HexenLordX
One quick question, will this work for several different triggers in one?

Here's what I'm trying to say, I got one trigger, for when a unit casts an ability, it sets the casting unit = RapidUnit, the next action is to run a trigger.

In the trigger it, the event is every .1 seconds, and it creates a dummy unit for Owner of (RapidUnit). Will the local variable carry over to another trigger?
08-27-2004, 06:36 AM#7
Anitarf
I don't think it will, it's a local variable for a reason.
For doing triggered Hero spells, in maps where each player may have only one hero, you can use variable arrays to store player-specific information: In targetUnit[1] you store the target unit for player 1, in targetUnit[2] you store the info for player 2... The nice thing is, you don't need any if-then-elses, because arrays can accept any integer function as an index, so you can say: set targetUnit[(owner of (casting unit))]. You need as many of these variable arrays as the hero with the most complex spells needs them.

That's still hard to do with waits, because you loose the "event response - casting unit" after a wait (cast event responses are bugged, they can act as global variables and be overwritten by other spells), so you can't reference the unit, even if it is safely stored in a variable. In that case, you must loop through all the units in the array after the wait to find out your unit, in which case you need to know which of these units you are looking at activated the trigger later than yours, so you don't do the effect for them instead, and a good way for that is to mark them with an undispellable buff that lasts 3.4 seconds...

There are more ways to get multi-instancablility: If you want something to happen periodically to all units under effect of a spell, and there can be more of them, don't store them in a unit variable, use a unit group. If you want player specific things to happen to units (like damage that gives experience on kill), then use a unit-group variable array, so you have it for every player as explained above...
08-27-2004, 07:27 AM#8
HexenLordX
Yeah, that Custom Script: local unit udg_variable, screwed up half of my abilities, and not only could multi instances of them not exist, but they weren't even usable.
08-27-2004, 07:40 AM#9
Pheonix-IV
i can tell you a simple way around the trigger above that allows multi-instability and dosnt require advanced triggering. It IS spell specific tho, and i know ways to get around many things that others would use triggers for.
08-27-2004, 07:41 AM#10
logik
what i reckon you should do is make NewUnit an array of how many players are playing...

and all you do is.

** note i just edited the script you posted, i cant be bothered opening up WE and doing all this when you had wrote down most of the stuff**

Untitled Trigger 001
Events
Unit - A unit Begins casting an ability
Conditions
(Ability being cast) Equal to Replacement
Actions
Unit - Replace (Triggering unit) with a footman using The new unit's max life and mana
Set NewUnit (player number of triggering player) = (Last replaced unit)
Animation - Play (Last replaced unit)'s stand animation
Wait 3.50 seconds
Unit - Replace NewUnit (player number of triggering player) with a captain using The new unit's max life and mana
08-27-2004, 12:55 PM#11
Anitarf
That's really smart, logik, really smart, except for the fact that there's no "triggering player" event response on a "begins casting" event.

Allright, LordX, I can give you a specific solution for this spell: Before waiting for 3.5 seconds, add your unit to a unit group variable, and have a dummy caster cast a shadow strike or doom (these are two buffing spells I know of that can't be dispelled) with a duration of 3.4 seconds onto the target unit. (the dummy caster should have it's "cast point" set to 0). Then, after the wait, you just do a check for all units in the unit group that don't have the undispellable buff, and transform them further. Any other units that use this ability while your trigger waits will still have the buff after the first 3.5 seconds run out, so they won't get the effect of the first unit.
08-27-2004, 01:15 PM#12
logik
player number of [owner of triggering unit] my friend...

that should work.
08-28-2004, 01:06 AM#13
Pheonix-IV
or simply create a phoenix egg type unit with the footman's stats and a 3.5 second lifespan. Make it turn into the captain when it "expires" and simply replace the target unit with the egg when you cast the spell.
08-28-2004, 05:33 AM#14
HexenLordX
Quote:
Originally Posted by Pheonix-IV
or simply create a phoenix egg type unit with the footman's stats and a 3.5 second lifespan. Make it turn into the captain when it "expires" and simply replace the target unit with the egg when you cast the spell.

I could do that, but only for that trigger. Most of the other triggers are just plain old triggered abilities, so that wouldn't work too well.

Oh and Logik, I'ma go try what you said. I hope it works.. thanks a million.
08-28-2004, 09:18 AM#15
Pheonix-IV
like i said, i can provide workarounds for alot of triggered spells, but they are specific, i cant provide a workaround that works for everything.