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

Hashtable being screwy

Status
Not open for further replies.
Level 10
Joined
Jun 10, 2007
Messages
557
I know I had a hashtable question a few weeks ago but I figured out the problem then and it worked fine... for a while. Now I have another one that's messing up in a completely different way.

Basically, the objective is to have the caster move towards the target point in a manner similar to a knockback and if he encounters any enemies along the way, the spell ends and he spawns a dummy unit that casts a spell on the enemy.

But what ends up happening is that he rockets across the map, not always in the targeted direction, going much farther and for much longer than I intend. The effect appears to be cumulative too; after casting the spell a few times he goes farther and faster than the last time. He stops and casts the dummy spell when he hits an enemy just fine, though.

  • Charge Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Charge (Berserker)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in ChargeGroup) Equal to 0
        • Then - Actions
          • Trigger - Turn on Charge FX <gen>
        • Else - Actions
      • Unit Group - Add (Triggering unit) to ChargeGroup
      • Unit - Pause (Triggering unit)
      • Animation - Play (Triggering unit)'s walk animation, using only Common animations
      • Set Location = (Position of (Triggering unit))
      • Set Location2 = (Target point of ability being cast)
      • Set ChargeAngle = (Angle from Location to Location2)
      • Set ChargeDistance = ((Distance between Location and Location2) x 0.04)
      • Set ChargeTime = ((Distance between Location and Location2) / 600.00)
      • Set ChargeLevel = (Level of Charge (Berserker) for (Triggering unit))
      • Hashtable - Save ChargeAngle as 0 of (Key (Triggering unit)) in Charge
      • Hashtable - Save ChargeDistance as 1 of (Key (Triggering unit)) in Charge
      • Hashtable - Save ChargeTime as 2 of (Key (Triggering unit)) in Charge
      • Hashtable - Save ChargeLevel as 3 of (Key (Triggering unit)) in Charge
      • Custom script: call RemoveLocation (udg_Location)
      • Custom script: call RemoveLocation (udg_Location2)
The casting trigger.

  • Charge FX
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in ChargeGroup and do (Actions)
        • Loop - Actions
          • Set Location = (Position of (Picked unit))
          • Set ChargeAngle = (Load 0 of (Key (Picked unit)) from Charge)
          • Set ChargeDistance = (Load 1 of (Key (Picked unit)) from Charge)
          • Set ChargeTime = (Load 2 of (Key (Picked unit)) from Charge)
          • Set ChargeLevel = (Load 3 of (Key (Picked unit)) from Charge)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ChargeTime Greater than 0.00
            • Then - Actions
              • Unit - Move (Picked unit) instantly to (Location offset by ChargeDistance towards ChargeAngle degrees)
              • Hashtable - Save (ChargeTime - 0.04) as 2 of (Key (Picked unit)) in Charge
              • Set Group = (Units within 100.00 of Location matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True)))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in Group) Greater than or equal to 1
                • Then - Actions
                  • Set Unit = (Random unit from Group)
                  • Unit - Create 1 Dummy for (Owner of (Picked unit)) at Location facing Default building facing degrees
                  • Unit - Add Maul to (Last created unit)
                  • Unit - Set level of Maul for (Last created unit) to ChargeLevel
                  • Unit - Order (Last created unit) to Neutral - Firebolt Unit
                  • Unit - Unpause (Picked unit)
                  • Animation - Reset (Picked unit)'s animation
                  • Hashtable - Save 0.00 as 2 of (Key (Picked unit)) in Charge
                • Else - Actions
              • Custom script: call DestroyGroup (udg_Group)
            • Else - Actions
              • Unit - Unpause (Picked unit)
              • Animation - Reset (Picked unit)'s animation
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in Charge
              • Unit Group - Remove (Picked unit) from ChargeGroup
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in ChargeGroup) Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
          • Custom script: call RemoveLocation (udg_Location)
The looping trigger, which is initially disabled.

So... I've been combing this thing for a while now and can't see what's wrong with it. Anybody find anything that might cause this? +rep will, of course, be given to helpful replies.

And before you ask, yes, I created the hashtable properly on map initialization.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
As far as I know, the trigger doesn't need to be turned off (nor initially disabled).
If the spell is casted twice after eachother, it will turn off once the first guy's charge is done, yet the second is still charging.

If that doesn't do anything, I'll try to dig a bit deeper in the trigger... on a rough first glimpse it looks fine.
 
Level 10
Joined
Jun 10, 2007
Messages
557
i have had problems with destroying leaks in spells in the initialization cause problems. try disabling the custom scripts in the first trigger and or second trigger.

Mhh... no, didn't really seem to do anything.

As far as I know, the trigger doesn't need to be turned off (nor initially disabled).

Well, it doesn't need to but this way it turns on when it's needed and off when it isn't, reducing the overall amount of strain on the engine during gameplay.

If the spell is casted twice after eachother, it will turn off once the first guy's charge is done, yet the second is still charging.

Huh? It should turn off once all of the charging units on the map are finished... at least I think so.
 
Level 4
Joined
Apr 23, 2009
Messages
65
Try this: Remove the triggers that turn the second trigger on/off. Then in the second trigger just add an if/then/else action. Set the condition as number of charged units greater then 0. Then paste all your actions in the then box.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
How do you want to set the time/speed of the charge? Do you want the time to be the same regardless of the distance, and the speed changes depending on distance?

  • Unit - Move (Picked unit) instantly to (Location offset by ChargeDistance towards ChargeAngle degrees)
^The offset location leaks.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Ohh, yeah - sorry ^^ I've misread the turn off trigger-part.
What I don't get is that you use ChargeTime, while it isn't really necessary... leave it out and work with the distance.
Here is a bit of math: Let's say the distance between Loc1 and Loc2 is 500
ChargeTime = 0.83
ChargeDistance = 20

It moves with an offset of 20 every 0.04 seconds over a total timespan of 0.84 (not 0.83... not that much of a difference anyway).
0.84 / 0.04 = amount of times the trigger loops (every loop is 0.04 seconds, for a total of 0.84 seconds), this gives us 21.
If you multiply 21 with 20 (the amount of loops with the offset every loop), you get 420.
The unit will thus move a total distance of 420... that's 80 too short.

When the offset is 800, the total distance will become 1066...

Conclusion: If the distance is over 600, it will go too far - if it is under 600, it won't go far enough.
Reason: you have adjusted 2 variables, while they both depend on eachother - the formula would be correct if either one of them would be static (e.g.: ChargeTime = 1.00 or ChargeDistance = 20).
If they both change, it will be incorrect.

I hope this helped, have fun.
 
Level 10
Joined
Jun 10, 2007
Messages
557
How do you want to set the time/speed of the charge? Do you want the time to be the same regardless of the distance, and the speed changes depending on distance?

I wanted it to be relative to the distance, so it would take twice as long at 600 range than at 300 range but truth to be told I don't particularly care as long as it'll make the spell work.

  • Unit - Move (Picked unit) instantly to (Location offset by ChargeDistance towards ChargeAngle degrees)
^The offset location leaks.

Oops, so it does. Thanks. :smile:

Ohh, yeah - sorry ^^ I've misread the turn off trigger-part.
What I don't get is that you use ChargeTime, while it isn't really necessary... leave it out and work with the distance.
Here is a bit of math: Let's say the distance between Loc1 and Loc2 is 500
ChargeTime = 0.83
ChargeDistance = 20

It moves with an offset of 20 every 0.04 seconds over a total timespan of 0.84 (not 0.83... not that much of a difference anyway).
0.84 / 0.04 = amount of times the trigger loops (every loop is 0.04 seconds, for a total of 0.84 seconds), this gives us 21.
If you multiply 21 with 20 (the amount of loops with the offset every loop), you get 420.
The unit will thus move a total distance of 420... that's 80 too short.

When the offset is 800, the total distance will become 1066...

Conclusion: If the distance is over 600, it will go too far - if it is under 600, it won't go far enough.
Reason: you have adjusted 2 variables, while they both depend on eachother - the formula would be correct if either one of them would be static (e.g.: ChargeTime = 1.00 or ChargeDistance = 20).
If they both change, it will be incorrect.

I hope this helped, have fun.

Ooohhh... wow, that helped a lot, thanks. :thumbs_up:

Though now he always goes a reasonable distance in a consistent manner, he still always seems to go in a weird direction, regardless of where the spell is targeted. Is there something wrong with the angles?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Though now he always goes a reasonable distance in a consistent manner, he still always seems to go in a weird direction, regardless of where the spell is targeted. Is there something wrong with the angles?
No, I don't see anything wrong with it :s
Is it always a specific angle? (the opposite direction, always the same angle, always a small difference to the same side, like when you want 90º, it goes to 100º and when you want 20º it goes to 30º or something), or does it seem completely random?
Also, does it have anything to do with the turning of the unit? (if you cast is straight in front of you, so the unit doesn't need to turn, is different then when you cast it behind the unit)?

What you can do is pick the facing angle of the triggering unit... normally it should be the same, but it can't hurt to try it out, right?
 
Level 10
Joined
Jun 10, 2007
Messages
557
No, I don't see anything wrong with it :s
Is it always a specific angle? (the opposite direction, always the same angle, always a small difference to the same side, like when you want 90º, it goes to 100º and when you want 20º it goes to 30º or something), or does it seem completely random?
Also, does it have anything to do with the turning of the unit? (if you cast is straight in front of you, so the unit doesn't need to turn, is different then when you cast it behind the unit)?

At first I thought it was just random but it appears to be gravitating towards the center of the map.

What you can do is pick the facing angle of the triggering unit... normally it should be the same, but it can't hurt to try it out, right?

Ah, that's true...

Alright, after some testing that does work better, but even at the maximum allowable turn speed the unit still can't turn fast enough to go in the proper direction when you target it, say, directly behind him.
 
Level 10
Joined
Jun 10, 2007
Messages
557
Which ability did you base it on?

Channel.

^Yeah, if it always heads to the center of the map, it can't get the "targe point of ability being cast" and defaults to center of the map.

Ah... okay. I had some problems detecting a target unit of Channel as well so maybe that's it.

Testing in a few minutes...

Okay, I tested it out with a couple of other point-targeted abilities like Serpent Ward and it didn't seem to change anything. :sad:
 
Level 15
Joined
Dec 18, 2007
Messages
1,098
First, let's address something. Why do you make both the Speed and the Time have variable values? Why not set one of them as a static one?

From what you have, the distance travelled will vary.
Let's say you aim 600 distance away:

Duration - 1 sec
Speed - 24 per 0.04 seconds
Total Distance Moved - 24 * 25 = 600

If you aim 300 distance away:
Duration - 0.5 sec
Speed - 12 per 0.04 seconds
Total Distance Moved - 12 * 25 * 0.5 = 150

Following this, I believe it will move 1800 range if you aim 900 range away. I haven't calculated it though.

Next, let's address this leak:
  • Unit - Move (Picked unit) instantly to (Location offset by ChargeDistance towards ChargeAngle degrees)
Polar offset creates a location, so this will leak. Please address this leak :D

And there's no need to turn off the trigger. If there are no units in the group, nothing happens.

Otherwise, there should not be a problem. Sometimes, the angle gets slightly screwed up, but it should not be off by too much, maybe 5 degree.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
First, let's address something. Why do you make both the Speed and the Time have variable values? Why not set one of them as a static one?

From what you have, the distance travelled will vary.
Let's say you aim 600 distance away:

Duration - 1 sec
Speed - 24 per 0.04 seconds
Total Distance Moved - 24 * 25 = 600

If you aim 300 distance away:
Duration - 0.5 sec
Speed - 12 per 0.04 seconds
Total Distance Moved - 12 * 25 * 0.5 = 150

Following this, I believe it will move 1800 range if you aim 900 range away. I haven't calculated it though.

Next, let's address this leak:
  • Unit - Move (Picked unit) instantly to (Location offset by ChargeDistance towards ChargeAngle degrees)
Polar offset creates a location, so this will leak. Please address this leak :D

And there's no need to turn off the trigger. If there are no units in the group, nothing happens.

Otherwise, there should not be a problem. Sometimes, the angle gets slightly screwed up, but it should not be off by too much, maybe 5 degree.

Isn't this exactly what I have already said?

If you had read the post, you would know that:
  • The math has already been fixed.
  • The leak has already been fixed.
  • The trigger is turned off so the overall strain is reduced.
  • The angle is pointed towards the center of the map, meaning the "Target point of ability being cast" can not be found, so it's not just 5 degrees.
Please... read before posting.
 
Level 15
Joined
Dec 18, 2007
Messages
1,098
Isn't this exactly what I have already said?

If you had read the post, you would know that:
  • The math has already been fixed.
  • The leak has already been fixed.
  • The trigger is turned off so the overall strain is reduced.
  • The angle is pointed towards the center of the map, meaning the "Target point of ability being cast" can not be found, so it's not just 5 degrees.
Please... read before posting.
Oh, sorry. Didn't see your post.

Anyway, there isn't anything that is the obvious reason for this maulfunction. Does it always happen?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Oh, sorry. Didn't see your post.

Anyway, there isn't anything that is the obvious reason for this maulfunction. Does it always happen?
No problem I guess :/

It might have something to do with the channel target, that if you set it to "Unit or Point", it doesn't get the point location or something.
I'm going to test this right now...
Edit: I was wrong, all tests show that it clearly picks the correct location :/
 
Level 10
Joined
Jun 10, 2007
Messages
557
Anyway, there isn't anything that is the obvious reason for this maulfunction. Does it always happen?

It does, I think I've narrowed it down to the ability that I'm using now. I'll try it with some more ground-targeted abilities and see if that does anything...

EDIT: That's odd, even Shockwave didn't change anything. o_O

This is very strange, I have other spells in this very map that work fine and operate off of Target Point of Ability Being Cast - and they're even based off of Channel!

EDITEDIT: Whoops, fixed typo.


OKAY: After some tinkering I actually found the solution: pausing the unit was somehow interfering with getting the target location and removing the pause and unpause actions now causes the spell to work perfectly.

+rep all around, thanks a bunch for your help guys, even if it wasn't the solution. :grin:
 
Status
Not open for further replies.
Top