HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Unit Acceleration

01-22-2007, 03:39 AM#1
WTFish
I was wondering how I could make it so that units accelerate.

Initially, (when they are standing still), I need their movement speed to be at 0, but when they are issued a move order, they will accelerate until they reach their maximum speed. It would need a fatigue bar, that starts to fill up once your unit has reached maximum speed, and as it fills up, the unit will begin to slow down. When it is full, the unit is paused as the fatigue level decreases, the unit is only unpaused when this bar is empty. Also, if a unit stops to rest (hold position), I want this bar's level to go down.

If your unit was at say 80% fatigue, and you stopped, and waited a while until his fatigue bar went down to 50%, then you start moving your unit again. Your unit's speed is at 0, and he starts to accelerate. Your unit is semi-fatigued, and he starts running, so his fatigue bar should start going up, even though he is not at his top speed. (this is where it has become way to tricky for me ).

Basically, your fatigue starts to go up once you reach max speed, and your fatigue will continue to go up as long as you keep running, until it gets full, when your unit is paused until its fatigue goes back down to 0. If your unit has fatigue (and were standing still) and they start running (ie they were fatigued, but stopped to rest, but ran too early), their fatigue will increase until it gets to full, when they are paused until it goes back down to 0.

In summary, units gain fatigue once they have passed their top speed. Units also gain fatigue if they are moving (at any speed), while they already have fatigue.

Perhaps the fatigue bar could be shown by text (eg. Fatigue: ||||||||||) in a leaderboard/multiboard that gets updated constantly, and is unique for each player.

How can I do the acceleration/decceleration thing so that it will not lag? (each player only has 1 unit, there are only 12 units in game so that might help some). Do I use periodic triggers?

Also, how can I detect when the unit stops moving (they will have to accelerate again. ie. they are resting to reduce their fatigue), or does a too sharp turn? (ie what would realistically make you have to stop).

It just doesn't seem realistic that units in warcraft can be standing still then break into a full sprint, run at that speed and never get tired, and do 180 degree turns without having to stop or even slow down.

Is it even possible to detect how sharp their turn is, or if they stop? .

If someone could post their answer to either of the problems with in [trigger] tags that would be great.

Ty.
01-22-2007, 11:44 AM#2
grim001
Well, I would say that this is all definately doable, but you aren't going to get a simple answer in a little trigger tag. It would be a fairly elaborate system you're gonna have to code yourself in JASS, or recruit a JASSer to help you out.
01-23-2007, 01:04 AM#3
WTFish
Well I don't know how to do JASS, so I'm hoping this thread can generate some help. If JASS is a definite requirement, is there anyone reading this that is interested in helping?

Thanks
01-23-2007, 01:17 AM#4
PipeDream
Check out the tutorials in the JASS section, in particular there's two by knutz that I think will help you.
01-23-2007, 02:03 AM#5
Pyrogasm
Hows about something related to this (don't know if some of these are valid commands):
Movespeed Increase:
Collapse Events
Time - Every 0.15 seconds of game time [or whatever interval seems good]
Conditions
Collapse Actions
Collapse Unit Group - Pick every unit in Move_Group and do (Actions) [Move_Group contains all the units in the map that the movespeed thing should apply to, excluding those in Stop_Group]
Collapse Loop - Actions
Unit - Set (Picked Unit) movespeed to ((Movespeed of (Picked Unit)) + 5) [or whatever the value should be]
Collapse If (All Conditions are true) then do (Actions), else do (Actions)
Collapse If - Conditions
(Picked Unit) is in Fatigue_Group[2]
Collapse Then - Actions
Unit - Set Custom value of (Picked Unit) to ((Custom value of (Picked Unit)) + 1)
Collapse Else - Actions
Collapse If (All Conditions are true) then do (Actions), else do (Actions)
Collapse If - Conditions
(Picked Unit) is in unit (Fatigue_Group[1] )
Collapse Then - Actions
Unit - Order (Picked unit) to Hold Position
Unit Group - Remove (Picked Unit) from Move_Group
Unit Group - Add (Picked unit) to Stop_Group
Collapse Else - Actions
Do Nothing
Blech. This will become a mess that I don't want to type out, so I'll outline what you'll need:

- A unit's "fatigue" level to be equal to its custom value, and all unit's base custom value to be 0
- Unit groups: Move_Group, Fatigue_Group[1], Fatigue_Group[2], Stopped_Group
- A periodic trigger that sets "Fatigue_Group[1]" equal to all units with a custom value of 100 (or greater, if custom values can go above 100), because there's no event to detect that that
- A periodic trigger that sets Move_Group equal to all units
- A periodic trigger that picks every unit in Stop_Group, and sets it's movespeed and custom value (for fatigue decrease over time) lower each time

Sorry, I'm a bit distracted right now so I can't write it all out. That's not all you'll need, but it'll get you started. PM me.
01-23-2007, 02:18 AM#6
WTFish
@PipeDream: I had a look at them, and perhaps you misunderstood what I was aiming at: The units are not moved by triggers, it is standard wc3 unit movement, but the longer they run the faster they will move (until they reach max speed, after that they deccelerate) - Pyrogasm is more along the right track.

@Pyrogasm: In your example, how does a unit get added to Fatigue_Group[2]? I want it so the unit only starts becoming fatigued after they have reached their max movement speed, and every periodic timer from then on, they do not gain speed anymore, and will lose speed and gain fatigue until their fatigue reaches 100, then they are paused and their fatigue degenerates, they are only unpaused when they have 0 fatigue level. I also want it so that any unit that is not moving (current order = stop or hold position) degenerates their fatigue level (when a unit stops, I need their speed to go back to 0).

Do I need -

1 periodic trigger picking every unit that has a custom value of 100, and adds them to Stop_Rest_Group, and pauses them (orders them to hold position first).

1 periodic trigger picking every unit that has a current order of stop / hold position, and set their movement speed to 0 and their custom value to their current custom value - 1.

1 periodic trigger picking every unit that is not in Stop_Rest_Group or Fatigue_Group or current order is stop/hold position and sets their movement speed to their current movement speed + 5. If their current movement speed is equal to/greater than than 500, they are added to Fatigue_Group. It then picks every unit in Fatigue_Group, and sets their custom value to their custom value + 1, and their movement speed to their current movement speed - 5. It then picks every unit that is in Stop_Rest_Group and sets their custom value to their custom value - 1. If their custom value is 0, they are removed from Stop_Rest_Group and unpaused.

If there are any flaws in this (which undoubtedly there will be), it would be great if someone could point them out before I go and make the triggers lol. I hope that this will work as I intend it to (although I have ignored the sharp turning thing for now lol).
01-23-2007, 03:59 AM#7
Pyrogasm
You're close, but not perfectly on track. You still need all the groups I said above.

Here's how I see it:

- Move_Group = Units that can move either with or without increasing fatigue (movespeed less than 500)
- Fatigue_Group = Units that have fatigue, but not enough to make them stop; if they continue to move, they will continue to gain fatigue. Most likely, these will be units that have a MS of 500, but haven't gained 100 fatigue. They could also be units that had fatigue, but stopped running before they became paused; they will gain fatigue for moving at any speed
- Stop_Rest_Group = Units that are stopped for any reason
- Any given unit can only either be in Move_Group or Stop_Rest_Group (not both), but can sometimes be in Fatigue_Group in combination with one or the other.
- Minimum move speed is 5 (otherwise units could never move initially, in order to be added to Move_Group)
Quote:
1 periodic trigger picking every unit that has a custom value of 100, and adds them to Stop_Rest_Group, and pauses them (orders them to hold position first).
That is correct, but you'd want to set their movespeed first.
Quote:
1 periodic trigger picking every unit that has a current order of stop / hold position, and set their movement speed to 0 and their custom value to their current custom value - 1.
I'd say, make it a trigger that adds units with the current order of stop/hold position (maybe 'smart' too, but I don't know much about that) to Stop_Rest_Group. Then have it add units with a custom value greater than 0 to Fatigue_Group. Then make another periodic trigger that takes every unit in Stop_Rest_Group that has a custom value greater than 1 and subtracts 1 from it, then sets all the units' movespeeds to 5.

Then I'd use the move trigger I posted above, modified a little bit, but still with the check for units in Fatigue_Group.

There's probably something I've missed, so if someone could point it out...

WTFish, if you give me a day or so, I'm sure I could set this up for you... maybe even submit it as a system
01-23-2007, 04:06 AM#8
PipeDream
Set move speed is a nightmare, if you use it with auras that change move speed, things bug out. Change move speed with abilities. Doing this in a global fashion will be very difficult in GUI though...
01-23-2007, 05:56 AM#9
WTFish
Can't you just use
Trigger:
unit - Set movement speed of "unit" to x
, or am I missing something here?

@Pyrogasm: I am going to try make it now, but if (or when) things go wrong, I will post in this thread and hopefully someone can provide answers. I was hoping this could be a unique feature of my map, but if you are willing to create it, it would be fine to have it as a submitted system lol (not sure if I am going to be able to make it anyway lol).

Ty for help so far.
01-23-2007, 07:56 AM#10
grim001
If you attempt to change the unit's move speed while it is moving I do not think it will update until a new order is issued. I think you'll get better results with triggered movement combined with standard movement.
01-23-2007, 10:22 AM#11
Pheonix-IV
If you change a units move speed while moving the change takes place instantly. The only problems you get when using move speed changing triggers is when items and auras increase move speed.
01-23-2007, 11:41 AM#12
grim001
In that case you still have the horrible problem of having to use SetUnitMoveSpeed... good luck with that..
01-23-2007, 01:10 PM#13
Pyrogasm
He could just trigger his other movement-speed affecting auras and spells too, you know.
01-23-2007, 07:15 PM#14
WTFish
There are no auras or items or w/e that affect movespeed so it is fine :).

EDIT: Oh wait, I actually was going to have a "cripple" spell, but I wasn't sure what it should affect. Would it be possible to make the cripple spell affect acceleration? Ie. when it picks a unit in the move unit group, I could just do this: If unit has buff of type Cripple, then set movement speed of unit to movement speed of unit + 1, else set movement speed of unit to movement speed of unit + 5. That way their acceleration is slowed, without having to change much in the system.

EDIT2: I gave the trigger a try, and there is something that isn't working for me:
Trigger:
Unit Group - Pick every unit in (Units in (Playable map area) matching (((Current order of (Matching unit)) Equal to (Order(stop))) or ((Current order of (Matching unit)) Equal to (Order(hold position))))) and do (Actions)
This doesn't seem to select any units because, when I tried the trigger, the unit didn't accelerate at all, and when I ordered him to hold position his movement speed wasn't set to 0.... I made it so whenever I press the esc key it gives the current order of my unit. I then ordered my unit to Hold Position, then pressed esc. It didn't say that it had a current order, but when I right clicked somewhere and pressed esc, it said "smart", which means the trigger was working. Perhaps I am doing something wrong? Any help would be appreciated.
01-24-2007, 01:29 PM#15
grim001
Wow, just that line of code would leak bad... sorry to say but you're not going to get this working just screwing around with GUI commands... I recommend finding a JASSer or learning JASS or giving up.