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

Indexing

Status
Not open for further replies.
Level 33
Joined
Mar 27, 2008
Messages
8,035
Okay I have learned a bit how to use Indexing in triggers, thanks to tutorials by Magtheridon96 :)

Okay now, how do I check for the same unit, if it still has any other instances for that unit ?

Okay, let's make an example;
I have a spell that will apply buff to the target unit, lasts for 5 seconds.

Unit[1] = (Target unit of ability being cast)
Duration[1] = 5.00

And as usual in the loop trigger, we will loop through all instances and reduce the duration.

Let's say at the 2nd second of the spell being casted, another same spell is casted to the same unit, so now it would be;
Unit[2] = (Target unit of ability being cast)
Duration[2] = 5.00

So, when Duration[1] reaches 0.00, it would remove the buff.
But, I don't want to remove the buff yet because Duration[2] still has value greater than 0.00.

So now my question is, how do I check for that same unit, if it has any other instances left ?

I mean the same unit, having more than 1 instances applied for it.

And when Duration[1] ends, it still has Duration[2], and I don't want to remove buff when Duration[1] ends, I want to remove buff when all instances applied to the unit reaches 0.00, how would I do that ?
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Usually, there are not multiple buffs of the same spell on the unit but the prior instance is overwritten, meaning the second cast in this example would also take index 1 and reset the duration etc.

Well, else you would need to assign a whole array to the unit. You can split up a hashtable for example.
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
I learned something while I learning Indexing.

Indexing allows data-stacking.
Hashtable allows data overwriting.

Which in this case, Hashtable would be easier and viable, because if duration left is 2 seconds, when the spell targets the same unit, the data gets overwritten with the initial duration, 5 seconds.

So, Hashtable will never remove the buff until the data value is 0.

But that's for Hashtable, what about Indexing method ?

There's gotta be a way.

Also, this buff has 0 second duration, meaning infinite.

The only way to remove the buff is either dispelled OR remove via triggers.

How can I remove via triggers if I don't know how to check how many instances left for that unit ?

Usually, there are not multiple buffs of the same spell on the unit but the prior instance is overwritten, meaning the second cast in this example would also take index 1 and reset the duration etc.
This would work if the buff has X seconds duration, it is removed by default Blizzard engine.

But this spell removes that buff by trigger, which I need to know how many instances left for that unit for it to remove the buff.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Handle indexing is done because there are no memory mediums like hashtable or array that would take the handle types as a key. It grants them another identification to dedicate data to them. Of course, you can have multiple of these ids.

You can overwrite data in a hashtable but you do not have to. There is not a difference to arrays or other mediums.

Of course you want to remove the buff by trigger. That is what you have shown but why do you need other instances but the longest/latest at a time? It only depends on the instance that is started last or has the longest remaining duration.
 
Level 14
Joined
Aug 8, 2010
Messages
1,022
Am, i have an idea, it worked in a spell for my map. So you create a trigger, the same as the loop one (you copy it) but with different event (when the event occurs, it loops trough all instances). And so when the event occurs ("A unit starts the effect of an ability" should be used in your case), you loop trough the instances (in the new trigger) and if Target Unit of Ability Being Cast is equal to Unit[InstanceArray], then immediately recycle the instance the picked unit is in (without removing the buff), this way the new applied instance will remove the effect if it's not recycled by another instance afterwise.

Oh, you also have to check the ability being cast in the conditions. It must be the same as the ability that gives the buff, or whatsoever.
Hope it works, man! :)
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
My idea is to put that unit in a Unit Group.
Each time a spell casted on the target, check whether the target is in the group or not.
If not, create a new instance and new duration for the unit.
If the unit is already in the group, I would loop through all current instances to check which instance does the unit belongs to.
Once it has found, set the duration = instance of that unit.
This way, duration would be save to that unit 1 at a time.

But this require a loop through all instances per spell check, I want to remove O(n) search if I can.

I guess Hashtable is the way... because Hashtable does not use O(n) search in this case.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Normally, you would already have a shared indexer for unit arrays. Once a unit enters the map, it receives an id between 0 and 8190, so you can use this number in any array. If you only need to store one buff instance at a time, you probably won't require a hashtable.

Also take a look into vJass structs.
 
Level 14
Joined
Aug 8, 2010
Messages
1,022
If the unit is already in the group, I would loop through all current instances to check which instance does the unit belongs to.
Once it has found, set the duration = instance of that unit.
Here, you can do what i said.

*Little side note - do you use Hanky's indexing system or no? Cuz' this solution works only for it*

So, to loop trough all instances, you have to do the following.
Copy the loop trigger, remove the event. In the initial trigger (before you index the new instance), you run the trigger with no event (before you do so, you save the target unit of ability being cast in a variable, lets call it "TargetUnit"). The trigger will loop trough all the instances (like in the loop trigger) and if the UnitVar[IndexArray] = TargetUnit, then set Duration[IndexArray] = MaxDuration.

Before all actions in the initial trigger, set a boolean to false. After you run the eventless trigger, set the variable to true if TargetUnit is matching UnitVar[IndexArray] in any of the instances, else do nothing. And so in the initial trigger, if this boolean is true, then create new instance, else do nothing. (the duration will already be reset in the eventless trigger)

Sorry for the spam if you don't use Hanky's indexing system... :/ Forgot to ask you.
 
Status
Not open for further replies.
Top