Quote:
Originally Posted by InvincibleNoOB
One thing I'd like to know is the character speed calculation in silkroad.In B323 we get three speed values,but how do we use them?
|
The three speed values are the Walking Speed, Running Speed, and the Berserk Speed in that order. If you read the values as floats rather than DWORDs, you should see meaningful numbers.
For example my noob char's speeds are the default:
00 00 80 41 = 16.0f
00 00 48 42 = 50.0f
00 00 C8 42 = 100.0f
So here is example code showing the wrong and right ways to get the values:
Code:
#include <windows.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
BYTE walkSpeed[] = {0x00, 0x00, 0x80, 0x41};
BYTE runSpeed[] = {0x00, 0x00, 0x48, 0x42};
BYTE zerkSpeed[] = {0x00, 0x00, 0xC8, 0x42};
DWORD dwWalkSpeed = *((LPDWORD)(walkSpeed));
DWORD dwRunSpeed = *((LPDWORD)(runSpeed));
DWORD dwZerkSpeed = *((LPDWORD)(zerkSpeed));
float fWalkSpeed = *((float*)(walkSpeed));
float fRunSpeed = *((float*)(runSpeed));
float fZerkSpeed = *((float*)(zerkSpeed));
// The values in hex
printf("%X %X %X\n", dwWalkSpeed, dwRunSpeed, dwZerkSpeed);
// Wrong, byte ordering is incorrect
printf("%f %f %f\n", dwWalkSpeed, dwRunSpeed, dwZerkSpeed);
// Right, byte ordering is correct due to the initial float type cast
printf("%f %f %f\n", fWalkSpeed, fRunSpeed, fZerkSpeed);
printf("\n\n");
// Alternatively, we can perform a memcpy to float values
float fWalkSpeed2 = 0;
float fRunSpeed2 = 0;
float fZerkSpeed2 = 0;
memcpy(&fWalkSpeed2, &dwWalkSpeed, 4);
memcpy(&fRunSpeed2, &dwRunSpeed, 4);
memcpy(&fZerkSpeed2, &dwZerkSpeed, 4);
// Right, byte order is correct
printf("%f %f %f\n", fWalkSpeed2, fRunSpeed2, fZerkSpeed2);
return 0;
}
Now, once you have the new values, comes the tricky part. The reason there are three speed values is because there are three player only moving states. The player can be in a walk moving state, a run moving state, or a zerk moving state. Based on what their current state is, that is the velocity that you use in order to calculate their position at any given time.
However, the velocity values are not enough because you need to know which direction the character is facing to come up with a movement vector. The orientation flag is 2 bytes for the character and comes in a few different packets based on what the player is doing. If the player uses the left and right arrow keys, the new direction the character is facing arrives in its own packet I believe.
If the player spawns in your view, the orientation is part of the spawn packet. Also, if the player spawns in your view, it has a flag if the player is already moving or not as well as the location it is going to.
I don't have a function or anything that models how Silkroad handles movements, but the basic theory is pretty simple. Trying to reimplement it yourself for an emu or clientless is rather tricky though and hence why I don't think anyone hsa published the algorithms for it (anyone really good at math could probably come up with it though.)
Let's say your character is currently facing 0 degrees, which I think is East/Right, but let's just make it that for the example. Assuming the current player state is Walk and that has a current speed value of 16.0f, we know the player moves 16 units for some time reference. What an accurate conversion is I don't know, but doing simple timing, it took about 13s to travel 16 units at that speed. That means it can travel about 1.23 units per sec at that rate.
So, if we start at (0, 0) and were moving with a rotation of 0 (to the right) at a velocity of 16.0f in sro units, we know each second we would be traveling 1.23 units further in game. So after 5 seconds we would be at (6.15, 0). After 10 seconds we would be at (12.3, 0).
That's the simple stuff for when moving in a straight line on one axis. However, most game movements are going to have both X and Y movements, so that's where the current rotation comes in. Using a unit circle, we can get a movement vector. If we were facing 45 degrees, north east let's say, then for each second that passes, we will be moving some factor of our speed in the X direction and Y direction.
In order to simulate movements ourselves outside of the client, we have to take all these things into consideration as well as run our simulation loop at the same frequency the client does (I don't know what it is). and we can then know the instantaneous position of any entity.
Things get slightly more complicated as you have to factor in when players are on a transport as the speed is now the transports speed. Likewise, you have to consider dismounting and mounting. You also have to take into account knockback skills or the phantom skill that allows a rapid change in position without the players velocity being taken into account.
It's kind of a big mess when considering all the things to factor in. That's why most programs just "cheat" at the estimate and use the movement packets position and do a coarse calculation of how long it should take to get here and delay that long.
I don't really know if you can make the problem any simpler than that though. I understand all the concepts of how it works, but I'm not really sure about accurately replicating the logic myself. Due to all that work, it might just be good to "estimate" where the player might be and go from there.
That's just my take on the issue so far, I've only recently messed with pulling the clients final position data for any entity from memory, but not so much trying to calculate it myself outside of the client.
Quote:
Originally Posted by hack0r89
there is something i'd like to know about silkroad: the terrain. or better: how it is stored.
there is something in the media.pk2 that tells the client where you can walk on and where a wall or tree is (well...i think it was the media.pk2 but it's been a while since i researched on this topic)
maybe you could cover this topic in one of the next guides?
|
I've had some limited experience with the game's map files. However, I don't know enough to write a guide on it telling anything too useful at this time. I might look again into the files later on but for now I still have a bit of learning to do before being able to release anything useful in that regards. I only know of a few developers that actually understand it all but as far as I know, that information was never released.
I know there is some useful information regarding the models posted on SRF by cruor. That information is important because the last I remember, I found the location of some obstacles, but had no idea of the size or direction they were facing. But anyways, I'll have to check that out later sometime.