Tommi,
You might want to read at least some of this; I made a mistake in my original speed increase formula at diabloii.net, correction is below.
I had not completed (and I haven't yet) my research into the subject when the whole discussion started, only found the velocity increase. You may not find this interesting, but should have some valuable comments. Note that this is NOT complete, there are still some cases that I haven't looked at (for example when you do not change your X position, the game handles things a bit differently).
First the "game graph". The game keeps track of unit location and movement with a coordinate system. I'm not sure if one coord represents the size of one tile/pixel, but as an example the width of the Rouge Encapment is 111. You will always stand right on the middle of a coord, but when moving you can be anywhere on it (from .0 to .65534, but still in integer form, only left shifted 16 bits). I hope I made this understandable. If you want to be able to see your current X/Y position, you can download a modified 1.09d D2Client.dll from http://www.geocities.com/hammermand2/files.../D2Clientxy.zip (you must right click and choose save target as..).
You move in small steps within the graph. The length of the step depends on your velocity increase, as well as other things. I did post a formula for velocity increase over at the diabloii.net forums, wich was a bit off. I'll try to make up for that here, by giving the correct method to calculate total velocity increase.
The game stores velocity increase in stat 67, STATS_VELOCITYPERCENT. For players, this is base 100. Then when you equip an armor it subtracts the value in 'speed' column in armors.txt from it (0, 5, or 10 for light, heavy, and medium armors). When in run mode, it adds to it ((RunVelocity * 100) / WalkVelocity) - 100. RunVelocty is currently 9 for all classes, and WalkVelocity 6 (this value can be found in charstats.txt). Various skills, such as Vigor, add their % move increase to that value (not sure about all such skills, have only checked Vigor). Now, when in run or walk mode (using skills such as Frenzy should also count, but Charge won't since that's a sequence), you get a bonus to the velocity from % faster run/walk on items. It is subject to a diminishing return formula, wich is:
effective rw = [(150 * frw) / (frw + 150)]
This bonus will only be added IF you have any % faster run walk items. After adding the effective rw to the velocity increase, it is lower capped at 25 (NOT 15 as I said at diabloii.net, that was a typo). I guess we could sum all this up in a formula,
RunBonus = ((RunVelocity * 100) / WalkVelocity) - 100 ; only add if running!
VelocityPercent = 100 - armor speed + Skill FRW ; stat 67, STATS_VELOCITYPERCENT
Item bonus = [(150 * frw) / (frw + 150)] ; only add if any item frw!
Velocity increase = RunBonus + VelocityPercent + ItemBonus
Velocity Increase is lower capped at 25
Total Velocity = (WalkVelocity * 256 * Velocity Increase) / 100
For the Charge skill, it is:
Total Velocity = charge speed increase * ((VelocityPercent * (RunVelocity * 256)) / 100) / 100
Now for the calculations of each step length. Some of it I'll write as it were code, since I find that more easy to understand at times, will try to keep it simple. Target X/Y position is originally stored unshifted (that is, not with the precision mentinoned above). Current X/Y is stored shifted.
target_x = (target_x * 2^16) + 32768
target_y = (target_y * 2^16) + 32768
Now the target locations have been shifted for more precision, and the +32768 part makes it so you'll end up on the middle of the target coordinate.
if (current_x < target_x) {
current_x2 = target_x
target_x2 = current_x
}
This is done to prevent negative numbers in further calculations, and doesn't change your actual target location at all. I put the 2 there to avoid confusion. If this is not done (that is, current x is equal or greater than target x), current_x2 and target_x2 will just be current_x and target_x.
if (current_y >= target_y) {
target_y2 = current_y
current_y2 = target_y
}
Similar check with Y pos, but note the difference in the expression.
travel_x = current_x2 - target_x2
travel_y = current_y2 - target_y2
This finds the x/y distance that you want to travel, this is not the step length. Now, if travel_x is lower than travel_y, the "2 variables" are swapped (that is, target_y2 will be target_x2, current_y2 will be current_x2, and vice versa). Continuing on to index calculations:
travel_y2 = current_y2 - target_y2
If the result of this is zero, the index calculations are skipped and index = 0. I'll name these new travel variables differently, since the previous ones will be used a bit more later on (and this way it'll hopefully cause less confusion).
travel_x2 = current_x2 - target_x2
index = (travel_x2 * 127) / travel_y2
Index will never be higher than 127, note that. This index will then be used to get information from a step table, wich will determine the step length. See the table at http://www.geocities.com/hammermand2/files.../step_table.txt. As you will see, each index has 3 values, and from now on the 1st will be called value1, 2nd will be value2 and 3rd will be value3. Ok, so now we're finally getting to the actual step length calculations.
if (travel_x < travel_y) {
step_y = value1
step_x = value2
step_temp = -1 - value 3
step_temp = step_temp AND 0x0F
}
"step_temp AND 0x0f" sets it to the last digit, ie. 12345 would give 5. The step_temp value gets used later on, dont worry much about it for now.
else {
step_y = value2
step_x = value1
step_temp = value3
}
if (current_y >= target_y) {
neg(step_y)
step_temp = -1 - step_temp
step_temp = step_temp AND 0x1F
}
"step_temp AND 0x1f" basically "wraps it" to 31. Ie. 0 = 0, 1 = 1, 2 = 2 ... 31 = 31. Then 32 = 0, 33 = 1, etc (surely there is a better way of explaining this, but this'll have to do for now).
if (current_x < target_x) {
neg(step_x)
}
else {
step_temp = -1 - step_temp
step_temp = step_temp AND 0x3F
}
step_temp = step_temp + 8
step_temp = step_temp AND 0x3F
Finally, the velocity increase is factored in: (see formula for velocity above)
step_x = (total velocity increase * step_x) / 256
step_y = (total velocity increase * step_y) / 256
That is pretty much it, unless there is something I have missed or have yet to see (as I said before, this isn't really complete). And, come to think of it, you can just ignore "step_temp", I can't find any more mention of it in my notes and from what I vaguely remember it doesn't say anything about step length. I'll leave it there since others might have an idea on what it is, or I'll find what it does later.
Hope it wasn't confusing, and didn't include any errors.
You might want to read at least some of this; I made a mistake in my original speed increase formula at diabloii.net, correction is below.
I had not completed (and I haven't yet) my research into the subject when the whole discussion started, only found the velocity increase. You may not find this interesting, but should have some valuable comments. Note that this is NOT complete, there are still some cases that I haven't looked at (for example when you do not change your X position, the game handles things a bit differently).
First the "game graph". The game keeps track of unit location and movement with a coordinate system. I'm not sure if one coord represents the size of one tile/pixel, but as an example the width of the Rouge Encapment is 111. You will always stand right on the middle of a coord, but when moving you can be anywhere on it (from .0 to .65534, but still in integer form, only left shifted 16 bits). I hope I made this understandable. If you want to be able to see your current X/Y position, you can download a modified 1.09d D2Client.dll from http://www.geocities.com/hammermand2/files.../D2Clientxy.zip (you must right click and choose save target as..).
You move in small steps within the graph. The length of the step depends on your velocity increase, as well as other things. I did post a formula for velocity increase over at the diabloii.net forums, wich was a bit off. I'll try to make up for that here, by giving the correct method to calculate total velocity increase.
The game stores velocity increase in stat 67, STATS_VELOCITYPERCENT. For players, this is base 100. Then when you equip an armor it subtracts the value in 'speed' column in armors.txt from it (0, 5, or 10 for light, heavy, and medium armors). When in run mode, it adds to it ((RunVelocity * 100) / WalkVelocity) - 100. RunVelocty is currently 9 for all classes, and WalkVelocity 6 (this value can be found in charstats.txt). Various skills, such as Vigor, add their % move increase to that value (not sure about all such skills, have only checked Vigor). Now, when in run or walk mode (using skills such as Frenzy should also count, but Charge won't since that's a sequence), you get a bonus to the velocity from % faster run/walk on items. It is subject to a diminishing return formula, wich is:
effective rw = [(150 * frw) / (frw + 150)]
This bonus will only be added IF you have any % faster run walk items. After adding the effective rw to the velocity increase, it is lower capped at 25 (NOT 15 as I said at diabloii.net, that was a typo). I guess we could sum all this up in a formula,
RunBonus = ((RunVelocity * 100) / WalkVelocity) - 100 ; only add if running!
VelocityPercent = 100 - armor speed + Skill FRW ; stat 67, STATS_VELOCITYPERCENT
Item bonus = [(150 * frw) / (frw + 150)] ; only add if any item frw!
Velocity increase = RunBonus + VelocityPercent + ItemBonus
Velocity Increase is lower capped at 25
Total Velocity = (WalkVelocity * 256 * Velocity Increase) / 100
For the Charge skill, it is:
Total Velocity = charge speed increase * ((VelocityPercent * (RunVelocity * 256)) / 100) / 100
Now for the calculations of each step length. Some of it I'll write as it were code, since I find that more easy to understand at times, will try to keep it simple. Target X/Y position is originally stored unshifted (that is, not with the precision mentinoned above). Current X/Y is stored shifted.
target_x = (target_x * 2^16) + 32768
target_y = (target_y * 2^16) + 32768
Now the target locations have been shifted for more precision, and the +32768 part makes it so you'll end up on the middle of the target coordinate.
if (current_x < target_x) {
current_x2 = target_x
target_x2 = current_x
}
This is done to prevent negative numbers in further calculations, and doesn't change your actual target location at all. I put the 2 there to avoid confusion. If this is not done (that is, current x is equal or greater than target x), current_x2 and target_x2 will just be current_x and target_x.
if (current_y >= target_y) {
target_y2 = current_y
current_y2 = target_y
}
Similar check with Y pos, but note the difference in the expression.
travel_x = current_x2 - target_x2
travel_y = current_y2 - target_y2
This finds the x/y distance that you want to travel, this is not the step length. Now, if travel_x is lower than travel_y, the "2 variables" are swapped (that is, target_y2 will be target_x2, current_y2 will be current_x2, and vice versa). Continuing on to index calculations:
travel_y2 = current_y2 - target_y2
If the result of this is zero, the index calculations are skipped and index = 0. I'll name these new travel variables differently, since the previous ones will be used a bit more later on (and this way it'll hopefully cause less confusion).
travel_x2 = current_x2 - target_x2
index = (travel_x2 * 127) / travel_y2
Index will never be higher than 127, note that. This index will then be used to get information from a step table, wich will determine the step length. See the table at http://www.geocities.com/hammermand2/files.../step_table.txt. As you will see, each index has 3 values, and from now on the 1st will be called value1, 2nd will be value2 and 3rd will be value3. Ok, so now we're finally getting to the actual step length calculations.
if (travel_x < travel_y) {
step_y = value1
step_x = value2
step_temp = -1 - value 3
step_temp = step_temp AND 0x0F
}
"step_temp AND 0x0f" sets it to the last digit, ie. 12345 would give 5. The step_temp value gets used later on, dont worry much about it for now.
else {
step_y = value2
step_x = value1
step_temp = value3
}
if (current_y >= target_y) {
neg(step_y)
step_temp = -1 - step_temp
step_temp = step_temp AND 0x1F
}
"step_temp AND 0x1f" basically "wraps it" to 31. Ie. 0 = 0, 1 = 1, 2 = 2 ... 31 = 31. Then 32 = 0, 33 = 1, etc (surely there is a better way of explaining this, but this'll have to do for now).
if (current_x < target_x) {
neg(step_x)
}
else {
step_temp = -1 - step_temp
step_temp = step_temp AND 0x3F
}
step_temp = step_temp + 8
step_temp = step_temp AND 0x3F
Finally, the velocity increase is factored in: (see formula for velocity above)
step_x = (total velocity increase * step_x) / 256
step_y = (total velocity increase * step_y) / 256
That is pretty much it, unless there is something I have missed or have yet to see (as I said before, this isn't really complete). And, come to think of it, you can just ignore "step_temp", I can't find any more mention of it in my notes and from what I vaguely remember it doesn't say anything about step length. I'll leave it there since others might have an idea on what it is, or I'll find what it does later.
Hope it wasn't confusing, and didn't include any errors.