• 🏆 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 without Hashtables???

Status
Not open for further replies.
Level 29
Joined
Mar 10, 2009
Messages
5,016
Hello guys, Im just wondering whats wrong with this trigger, it's suppose to change the value of the Caster or this should be MUI but why its not?...

I know wait sucks, but this suppose to be MUI...

  • Explode
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Bloodlust (Neutral Hostile 1)
    • Actions
      • Set BL_Index = (BL_Index + 1)
      • Set BL_Caster[BL_Index] = (Triggering unit)
      • Set BL_Target[BL_Index] = (Target unit of ability being cast)
      • Special Effect - Create a special effect attached to the overhead of BL_Target[BL_Index] using Abilities\Weapons\DemolisherFireMissile\DemolisherFireMissile.mdl
      • Set Sfx[BL_Index] = (Last created special effect)
      • Wait 10.00 seconds
      • Special Effect - Destroy Sfx[BL_Index]
 
Level 15
Joined
Jul 9, 2008
Messages
1,552
see how u got BL_index+1 with each cast
the special effect is getting saved with the vairable 1 on the first cast and so on

then with the wait and if some 1 else casts the spell the BL_index is set to 2 so when the destroy special effect goes off only number 2 is destroyed because thats what the BL_index number will be on

it is not MUI
 
What happens if another instance runs within 10 seconds? BL_Index will increase by 1, and so, the 1st time cast, BL_Index will be 1. But if casted again in 10 seconds, BL_Index will become 2, and then once the Wait is finished, it will destroy Sfx[2] instead of [1].

That isn't MUI.

EDIT: Sorry, posted at the same time as millzy.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
What happens if another instance runs within 10 seconds

Yes I know that, that's why I use index, but why doesnt the "BL_Target[BL_Index]" change the value...

Besides, you can use waits by assigning a local variable first like...

  • Custom script: local unit udg_VARIABLE
but I dont want to do that, I like index much better...so is it possible to have indexes without hastables?
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
^That's bad coding in my eyes, since udg_ refers to a global variable.

You must use another trigger that has a periodic trigger instead of the wait. An indexing tutorial should show how to make one.

really?, hmmm, strange, well I use the trigger below for that...and it casts properly even with waits...if you want proof I can give you a sample map :)

  • Effect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Bloodlust (Neutral Hostile 1)
    • Actions
      • Custom script: local unit udg_CasterUnit
      • Custom script: local effect udg_Effect
      • Set CasterUnit = (Triggering unit)
      • Set CasterTargetUnit = (Target unit of ability being cast)
      • Special Effect - Create a special effect attached to the overhead of CasterTargetUnit using Abilities\Weapons\DemolisherFireMissile\DemolisherFireMissile.mdl
      • Set Effect = (Last created special effect)
      • Wait 10.00 seconds
      • Special Effect - Destroy Effect
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
@Maker

dude its just a sample trigger that even WITH WAITS, it can be MUI...like I said on top, WAIT SUCKS but its not entirely useless...

@Adiktuz

Yes its bad...complicated indexing is not just 1 trigger, but the sample on top is VERY SHORT, and I believe that it can be done in 1 trigger without hash & custom script...I just dont know how...

====================
The reason why I post this is to be able to guide a beginner like me to KNOW MORE on HOW INDEX works, not complicated at first but rather step by step...

anyway +rep all of you guys...
 
Last edited:
@Maker

dude its just a sample trigger that even WITH WAITS, it can be MUI...like I said on top, WAIT SUCKS but its not entirely useless...

@Adiktuz

Yes its bad...complicated indexing is not just 1 trigger, but the sample on top is VERY SHORT, and I believe that it can be done in 1 trigger without hash & custom script...I just dont know how...

====================
The reason why I post this is to be able to guide a beginner like me to KNOW MORE on HOW INDEX works, not complicated at first but rather step by step...

anyway +rep all of you guys...

hashtables or custom value... but I'd prefer hashtable over CV... or use a loop to pick the index of the unit (though this one could bug if unit casts twice)...

you can really use index for that like they do in loops but its kinda bad because you use a 10 second wait so its like doing a 10 second loop...
 
tnx, already add +rep to you last time so hive wont let me give to you twice :)

if you want to use index for that, you need to do it like how they do it in periodic loops though it wont be efficient and could still bug since the wait is 10 seconds... so it would be like looping every 10 second... so I'd prefer using hashtable but it will also bug if the same unit casts twice...

conclusion? its better to use periodic loops + index than that wait... coz in reality, its really harder to use indexing in waits rather than in periodic loops...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
if you want to use index for that, you need to do it like how they do it in periodic loops though it wont be efficient and could still bug since the wait is 10 seconds... so it would be like looping every 10 second... so I'd prefer using hashtable but it will also bug if the same unit casts twice...

conclusion? its better to use periodic loops + index than that wait... coz in reality, its really harder to use indexing in waits rather than in periodic loops...

got it thanks again :D
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
I thought local shadowing was already removed on recent patches...

I remember reading somewhere that they fixed it to work with more than 1 or 2 variables

imho it is nt bad at all since it is the similar to:

JASS:
function a takes nothing returns nothing
local integer i = 10
endfunction

function b takes nothing returns nothing
local integer i = 0
call a()
call BJDebugMsg(I2S(r))//displays 0
endfunction
  • Set
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: local integer udg_i = 10
  • Show
    • Events
      • Player - Player 1 (Red) types a chat message containing <Empty String> as An exact match
    • Conditions
    • Actions
      • Game - Display to (All players) the text: (String(i))
the displayed value will be 0
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
coding mui with indexing or hashtables are very different. Firstly let's point out that you can combine both ways.

Indexing uses variables with arrays, we index them with an integer we increase for every instance. Although this isnt recycling indexing which is alot better but just to explain the basics.

To refer to the variables we loop threw the arrays with a loop. Thats how we index. Indexing have a limit of 8190 instances, we don't use 0 as an instance.

Hashtables is different, slower but has unlimited instances.

There are alot of tutorials about this, i can recommend hanky's dynamic template in the spell section and deuturium's essentials tutorial in the tutorial section.

Good luck, pm me if you have any problems or issues, ill gladly answer your questions.
 
Yes I know that, that's why I use index, but why doesnt the "BL_Target[BL_Index]" change the value...

Yeah, really?
Unit A casts Bloodlust. Increases BL_Index by 1.
Unit B casts Bloodlust only 2 seconds later. Increases BL_Index by 1.
So, 2 seconds after Unit A casted, BL_Index is now 2.
Therefore, after 8 seconds(which, added upon the 2 seconds between Unit A and B's casting time equals to 10) it will destroy BL_Sfx[BL_Index], won't it?
And what is BL_Index by then? 2! So, in other words it will destroy BL_Sfx[2], and then BL_Sfx[1] will be permanently around, creating a leak and unwanted special effect.
 
basically you cannot index without a loop... be it an integer or a custom loop... while for hashtable you can...

+its also bad method to get an index using the unit itself, it will bug if the same unit casts more than once... its better if you just loop thru every index and then use a real variable to check whether the time is up or not...

I suggest you follow baassee's suggestion...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Guys I already solve this problem, instead of wait I use index & hash & every second event & it works...

I'm a beginner so it makes my head turn around hahaha!

For the benefit of others who is a beginner like me, this is the trigger...

  • Effect 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Bloodlust (Neutral Hostile 1)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index Equal to 0
        • Then - Actions
          • Trigger - Turn on Timer 1 <gen>
        • Else - Actions
      • Set Index = (Index + 1)
      • Special Effect - Create a special effect attached to the overhead of (Target unit of ability being cast) using abilities\weapons\DemolisherMissile\DemolisherMissile.mdl
      • Set Sfx[Index] = (Last created special effect)
      • Set SfxDur[Index] = 5.00
  • Timer 1
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Set Counter = (Counter + 1)
      • Game - Display to (All players) the text: (String(Counter))
      • For each (Integer Loop) from 1 to Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SfxDur[Index] Greater than 0.00
            • Then - Actions
              • -------- Actions --------
              • Set SfxDur[Index] = (SfxDur[Index] - 1.00)
            • Else - Actions
              • Special Effect - Destroy Sfx[Index]
              • Set Index = (Index - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
 
Last edited:
Level 29
Joined
Mar 10, 2009
Messages
5,016
GOOD!!!! :goblin_good_job:

what's Counter for?

hmmm...

on this:

SfxDur[Index] Greater than 0.00
Then - Actions
-------- Actions --------
Set SfxDur[Index] = (SfxDur[Index] - 1.00)
Else - Actions
Special Effect - Destroy Sfx[Index]
Set Index2[Loop] = Index2[Index]
Set Index = (Index - 1)
Set Loop = (Loop - 1)

it should be SfxDur[Loop], Sfx[Loop] I think coz in the current trigger, no matter what the value of loop is, it would always return the value of index...


hmmm... ah, no, it should work fine... I havent noticed that it was a reversed loop...

its nothing, counter is just for DISPLAY purposes, so when the Sfx is destroyed,
then the counter also stops...its just that nothing more...
 
Yeah I just missed it...

also the Set Index2[Loop] = Index2[Index] is not needed...

so that's why I was wondering about where you use it... I thought you use it in another trigger... ^_^

btw, you can put the last ifthenelse (the one that turns off the trigger) into the else action (after set index = index -1) so that it would only run when index is actually reduced... not a big deal though...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
so that's why I was wondering about where you use it... I thought you use it in another trigger... ^_^

btw, you can put the last ifthenelse (the one that turns off the trigger) into the else action (after set index = index -1) so that it would only run when index is actually reduced... not a big deal though...

Correct coz it will be more faster to run, but the trigger is works anyway...
 
Guys I already solve this problem, instead of wait I use index & hash & every second event & it works...

I'm a beginner so it makes my head turn around hahaha!

For the benefit of others who is a beginner like me, this is the trigger...

  • Effect 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Bloodlust (Neutral Hostile 1)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index Equal to 0
        • Then - Actions
          • Trigger - Turn on Timer 1 <gen>
        • Else - Actions
      • Set Index = (Index + 1)
      • Special Effect - Create a special effect attached to the overhead of (Target unit of ability being cast) using abilities\weapons\DemolisherMissile\DemolisherMissile.mdl
      • Set Sfx[Index] = (Last created special effect)
      • Set SfxDur[Index] = 5.00
  • Timer 1
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Set Counter = (Counter + 1)
      • Game - Display to (All players) the text: (String(Counter))
      • For each (Integer Loop) from 1 to Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SfxDur[Index] Greater than 0.00
            • Then - Actions
              • -------- Actions --------
              • Set SfxDur[Index] = (SfxDur[Index] - 1.00)
            • Else - Actions
              • Special Effect - Destroy Sfx[Index]
              • Set Index = (Index - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions


wait... noticed some error...

You loop From 1 to Index
then you only use index in all the arrays
so when you loop only the array with the "index" equal to the value of the current Index... and it wont loop thru the other values...

Example: Index = 2
We loop from 1 - 2
lets say SFXDUR[2] = 5

on loop 1

SFXDUR[Index] > 0 so SFXDUR[Index] = SFXDUR[Index] - 1

Index remains as 2

on loop 2

SFXDUR[Index] > 0 so SFXDUR[Index] = SFXDUR[Index] = SFXDUR[Index] - 1

Index remains as 2
---------------------------------
so only the array of the index 2 is looped...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016



wait... noticed some error...

You loop From 1 to Index
then you only use index in all the arrays
so when you loop only the array with the "index" equal to the value of the current Index... and it wont loop thru the other values...

Example: Index = 2
We loop from 1 - 2
lets say SFXDUR[2] = 5

on loop 1

SFXDUR[Index] > 0 so SFXDUR[Index] = SFXDUR[Index] - 1

Index remains as 2

on loop 2

SFXDUR[Index] > 0 so SFXDUR[Index] = SFXDUR[Index] = SFXDUR[Index] - 1

Index remains as 2
---------------------------------
so only the array of the index 2 is looped...

basically, index will always be 0 or 1, there is no error coz i've tested it, the only problem I can see here is the TIME (Set SfxDur[Index]), coz if you cast it again, then the NEW cast will start with 5, so the last casting is reset, after then NEW cast explodes, then the previous cast will explode also...the solution I can think of is to replace the loop with another array index...

WHY zero?, coz when starting the ability, the TIMER 1 will always be ON, otherwise its OFF, isnt it?

WHY one? coz of "Set Index = (Index + 1)", and back to zero via "Set Index = (Index - 1)", so the loop is just 1...
 
Last edited:
it can be greater than 1... try to cast it twice at the same time... it would lead to a value of Index = 2...

+

you dont do Index = Index - 1 always, its only called when SfxDur[Index] becomes 0.00 which is after 5 seconds...

or you're not trying to make it MUI?

based on your comment, you're not really trying to make it MUI...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
it can be greater than 1... try to cast it twice at the same time... it would lead to a value of Index = 2...

+

you dont do Index = Index - 1 always, its only called when SfxDur[Index] becomes 0.00

or you're not trying to make it MUI?

I've casted it 3-4 times 'within the time duration' & it always explodes, otherwise if its not MUI then the Sfx will be permanent...

like I said above the only problem is the TIME...always resets when cast, of course its because of the set index thing...
 
Last edited:
I've casted it 3-4 times 'within the time duration' & it always explodes, otherwise if its not MUI then the Sfx will be permanent...

okay... but do they explode within 5 seconds after cast?


like I said above the only problem is the TIME...always resets when cast, of course its because of the set index thing...

so they dont explode 5 seconds after you cast them but after 5 seconds of last cast... so its not that MUI... in this case it works since its just an effect removal but it would cause serious bugs on other actions...

and it produces a reversal effect, the last cast explodes first, and the very first cast will explode last...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
okay... but do they explode within 5 seconds after cast?

Yes

so they dont explode 5 seconds after you cast them but after 5 seconds of last cast... so its not that MUI... in this case it works since its just an effect removal but it would cause serious bugs on other actions...

no, i said "after then NEW cast explodes, then the previous cast will explode also"...basically 1-3 seconds apart...
 
Yes



no, i said "after then NEW cast explodes, then the previous cast will explode also"...basically 1-3 seconds apart...

so the new cast explodes first than the other... If its MUI they should explode exactly 5 seconds after you casted each instance and not wait for the new instances to finish first...

now think of this:

what if instead of an effect what you did is:

A spell which should heal a unit per second for 5 seconds

You cast it on Unit A, after 1 second you cast it on unit B
using you "indexing" method
Unit A will stop to get healed until UnitB finishes healing...

Basically the way you indexed it is wrong... Not because it works means it correct already... It works on this but it wont on other things... I'm just trying to correct it for future uses.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
so the new cast explodes first than the other... If its MUI they should explode exactly 5 seconds after you casted each instance and not wait for the new instances to finish first...

this is the problem Im talking about, so maybe Im thinking of replacing it with a static index just for the time, what do you think?...

what you said is true, just the TIME...other than that its OK...
 
this is the problem Im talking about, so maybe Im thinking of replacing it with a static index just for the time, what do you think?...

what you said is true, just the TIME...other than that its OK...

you dont really need another... use the variable Loop instead of Index and then:

Here its something like this
  • For Each integer Loop from 1 to Index
    • Do - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • SfxDur[Loop] Greater than 0.00
        • Then - Actions
          • -------- Actions --------
          • Set SfxDur[Loop] = (SfxDur[Loop] - 1.00)
        • Else - Actions
          • Special Effect - Destroy Sfx[Loop]
          • //Transfer everything that the index array holds into the current array
          • Set Sfx[Loop] = Sfx[Index]
          • Set SfxDur[Loop] = SfxDur[Index]
          • Set Index = (Index - 1)
          • Set Loop = Loop - 1
basically when you finish using a current index you transfer everything that the Max Index holds into the current index(Loop) and then reduce the Max index and set Loop to Loop - 1 so that it would re run the loop on the current index(which now hold the data from the previous Max index)


btw, the problem in that trigger is not "just" TIME, its a serious thing actually...
 
I mean dont put the word "just"...

but well, each cast will make the new cast explode faster... example at 5 casts Index = 5 so the latest cast will explode after only 1 second since it will be looped 5 times during one run of your periodic trigger...

Not just Dur, but all arrays should use the current index (in that case the variable Loop), the Max Index (in that case the variable Index) is just used to keep track how many instances actually exists...

Basically that's how you do indexing...

you loop from first to the last index...
if you dont need the current index anymore,
-you replace it with the values of the last index and repeat the loop on that index
 
Ok I understand now, so I should not use the said index dynamic variable for all array variables, instead replace it with another dynamic index such as loop (current index)...okay Im gonna try this...tnx!

Yup... you only use it to keep track of the max number of instances currently used and on the trigger which sets data into the arrays (which is usually the OnCast triggers)...

there are lots of GUI/jass spells on the spells section that uses indexes if you need more info or look at the tutorials section... ^_^
 
Status
Not open for further replies.
Top