[Release] Direction Sectors

02/19/2012 01:06 Spirited#1
Hey everyone.

So, it turns out that when you jump... you change directions. It's ok if people see you jump... but for people just walking into the screen, all they see is your old, predefined direction from before the jump. Firstly, here's a direction diagram:

[Only registered and activated users can see links. Click Here To Register...]

Based on that, you can probably imagine that when you jump, you face in the direction of whichever arrowhead you're closest to. Here's the formula I developed that can be used to find that direction:

Code:
public const double RADIAN_TO_DEGREE = 57.295779513082323;

        /// <summary>Find the direction of a character based on two points.</summary>
        /// <param name="x1">The X Coordinate at Point 1.</param>
        /// <param name="y1">The Y Coordinate at Point 1.</param>
        /// <param name="x2">The X Coordinate at Point 2.</param>
        /// <param name="y2">The Y Coordinate at Point 2.</param>
        /// Developed by Spirited Fang - 2/18/2012
        public static byte GetDirectionSector(ushort x1, ushort y1, ushort x2, ushort y2)
        {
            double angle = (Math.Atan2(y1 - y2, x1 - x2) * RADIAN_TO_DEGREE) - 67.5;
            if (angle < 0)
                angle += 360;
            return (byte)(angle / 45);
        }
EDIT: Updated formula: [Only registered and activated users can see links. Click Here To Register...]

It's a minor detail, but you know - I'm into those minor details.

Sincerely,
Spirited Fang
02/19/2012 01:32 InfamousNoone#2
Why not just use the standard implementation from the EO source?
It involves having to introduce doubles into the algorithm, and it avoids using any trigonometric functions.

edit:
nvm it appears that the EO function wasn't intended to be used in a system of any 2 (x,y) coordinate pairs to obtain the direction.
02/19/2012 01:39 Spirited#3
Quote:
Originally Posted by InfamousNoone View Post
Why not just use the standard implementation from the EO source?
It involves having to introduce doubles into the algorithm, and it avoids using any trigonometric functions.
Right! I keep forgetting that I can use EO as a reference. I'm not very familiar with it yet, but I'll look through it and see what I can find. Thanks Roy.

Edit: I was just going to comment on your edit, it doesn't seem like it. Direction is sent in EO's packet... but it's not in CO's. Maybe it's a structure issue with their recent changes with 10010. When you jump, it defaults your direction to 0 (in real co).
02/20/2012 16:24 nTL3fTy#4
Quote:
Originally Posted by InfamousNoone View Post
Why not just use the standard implementation from the EO source?
It involves having to introduce doubles into the algorithm, and it avoids using any trigonometric functions.

edit:
nvm it appears that the EO function wasn't intended to be used in a system of any 2 (x,y) coordinate pairs to obtain the direction.
Code:
int CGameMap::GetDirection(int x0,int y0,int x1,int y1)
{
	int Dir;
	
	long Tan[4]	={-241,-41,41,241};
	long DeltaX	=x1-x0;
	long DeltaY	=y1-y0;
	
	if(DeltaX==0)
	{
		if(DeltaY>0)
			Dir	=0;
		else
			Dir	=4;
	}
	else if(DeltaY==0)
	{
		if(DeltaX>0)
			Dir	=6;
		else
			Dir	=2;
	}
	else
	{
		int Flag=abs(DeltaX)/DeltaX;
		
		DeltaY	*=(100*Flag);
		int i;
		for(i=0;i<4;i++)
			Tan[i]	*=abs(DeltaX);
		
		for(i=0;i<3;i++)
			if(DeltaY>=Tan[i] && DeltaY<Tan[i+1])
				break;
			
			//** note :
			//   i=0    ------- -241 -- -41
			//   i=1    ------- -41  --  41
			//   i=2    -------  41  -- 241
			//   i=3    -------  241 -- -241
			
			DeltaX=x1-x0;
			DeltaY=y1-y0;
			
			if(DeltaX>0)
			{
				if(i==0)			Dir	=5;
				else if(i==1)		Dir	=6;
				else if(i==2)		Dir	=7;
				else if(i==3)
				{
					if(DeltaY>0)	Dir	=0;
					else			Dir	=4;
				}
			}
			else
			{
				if(i==0)			Dir	=1;
				else if(i==1)		Dir	=2;
				else if(i==2)		Dir	=3;
				else if(i==3)
				{
					if(DeltaY>0)	Dir	=0;
					else			Dir	=4;
				}
			}
	}
	
	Dir	=(Dir+7)%8;
	return Dir;
}
02/20/2012 16:28 Korvacs#5
@nTL3fTy - Yeah your right that is a horrible way of doing it...
02/27/2012 04:12 unrrrreaL#6
Quote:
Originally Posted by Korvacs View Post
@nTL3fTy - Yeah your right that is a horrible way of doing it...
since you resigned from mod you've become a little critical haha.. i like it
02/27/2012 16:07 m7mdxlife#7
And what happens if you jump and SS/FB in a direction a different direction than the one you are jumping to? your char should be facing where your SS/FB is going or supposed to be if you had low stam?
minor details ;)
02/27/2012 16:09 Korvacs#8
Quote:
Originally Posted by m7mdxlife View Post
And what happens if you jump and SS/FB in a direction a different direction than the one you are jumping to? your char should be facing where your SS/FB is going or supposed to be if you had low stam?
minor details ;)
Since the attack packet is handled after the jump packet, the attack packets direction would override the change made by the jump packet.

So this would work as intended.
01/13/2013 07:13 Spirited#9
The above formula isn't correct in some cases.
Here's the updated formula:

Code:
        /// <summary> This function returns the direction for a jump or attack. </summary>
        /// <param name="x1">The x coordinate of the destination point.</param>
        /// <param name="y1">The y coordinate of the destination point.</param>
        /// <param name="x2">The x coordinate of the reference point.</param>
        /// <param name="y2">The y coordinate of the reference point.</param>
        public static byte GetDirectionSector(ushort x1, ushort y1, ushort x2, ushort y2)
        {
            double angle = GetAngle(x1, y1, x2, y2);
            byte direction = (byte)Math.Round(angle / 45.0);
            return (byte)(direction == 8 ? 0 : direction);
        }

        /// <summary> This function returns the angle for a jump or attack. </summary>
        /// <param name="x1">The x coordinate of the destination point.</param>
        /// <param name="y1">The y coordinate of the destination point.</param>
        /// <param name="x2">The x coordinate of the reference point.</param>
        /// <param name="y2">The y coordinate of the reference point.</param>
        public static double GetAngle(double x1, double y1, double x2, double y2)
        {
            // Declare and initialize local variables:
            double angle = (Math.Atan2(y2 - y1, x2 - x1) * RADIAN_TO_DEGREE) + 90;
            return angle < 0 ? 270 + (90 - Math.Abs(angle)) : angle;
        }