Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Programming
You last visited: Today at 19:18

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Mam/CO2 Map Coordinate Calculations

Discussion on Mam/CO2 Map Coordinate Calculations within the CO2 Programming forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jul 2018
Posts: 15
Received Thanks: 9
Mam/CO2 Map Coordinate Calculations

Hi Everyone, Jonathis here again. I am still whiling away on my Monster and Me 2.5 Client rebuild project. Looking for some help on the TQ Coordinate system, as I am not getting expected results. I have confirmed MaM uses the same coordinate system as Conquer Online, and read through a number of posts regarding the calculations, including the extremely useful post found here by unknownone:

The map dimensions are the following:
pixels: 3840 x 2400
tiles: 135 x 135 (according to the map file)
tile size is the standard 64 x 32

So here's my problem... Mouse Coordinate to Map Coordinate works nearly perfectly utilizing unknownone's algorithm:
Code:
	int tempX = mouseX - (mouseX % tileWidth);
	int tempY = mouseY - (mouseY % tileHeight);

	int coordX = tempX / tileWidth + tempY / tileHeight;
	int coordY = tempY / tileHeight + (map->width - tempX) / tileWidth;

	//Array replicating 'Rainbow Tile'
	int posX = mouseX - tempX;
	int posY = mouseY - tempY;
	if (tileZone[posX][posY] == TileZone::TOPLEFT) coordX--;
	else if (tileZone[posX][posY] == TileZone::TOPRIGHT) coordY--;
	else if (tileZone[posX][posY] == TileZone::BOTTOMLEFT) coordY++;
	else if (tileZone[posX][posY] == TileZone::BOTTOMRIGHT) coordX++;
I cross referenced the given coordinates in quite some detail with the coordinate system in game, with the only hiccup being the x coordinate was always 1 off. I can fix that by adding 1 to it, though I'm not completely sure why it is off given the above. Once I add the 1 offset, I get exact matches to the ingame coordinates.

Now comes the problem. I try to do the reverse, and apply the Map Coordinate to Screen Point algorithm, and get very odd results. Below is the implemented algorithm.

Code:
SDL_Point GameMap::mapCoordinateToPoint(int x, int y) {
	SDL_Point newPoint;
	newPoint.x = (x - y) * tileHeight + (map->width / 2);
	newPoint.y = (x + y - (mapTileHeight-1)) * (tileWidth / 2) + (map->height / 2);
	return newPoint;
}
With this, I get a seemingly accurate x position, as can be seen by how the bounding rectangle bounds a tile that is in alignment with my mouse position. I am not completely sure it is right though, because the 0,60 calcs look iffy. The Y axis is definitely wrong though.



Instead of starting in the middle, I figure take a simple example
The top left corner of the map is the coordinate 0,60. If I plug in the above I get the following results:
x = (0-60) * 32 + 1920 = 0
y = (0 + 60 - (135 - 1)) * 32 + 1200 = -49 * 32 + 1200 = -1168

Given the first tile origin is the very top left corner for the map, I would expect the tile and bounding rectangle to only be a quarter visible. Thus expected x and y should be -32,-16. Definitely not right! If I subtract an extra 1 from the x coordinate, I get the expected x values (which is obviously because I had to add 1 earlier). Still, the Y coordinate is really puzzling me.

If anyone has any suggestions, I'd much appreciate it. Thanks



Jonathis is offline  
Old 08/29/2018, 14:23   #2
 
elite*gold: 0
Join Date: Oct 2007
Posts: 1,552
Received Thanks: 614


turk55 is offline  
Old 08/29/2018, 15:23   #3
 
elite*gold: 0
Join Date: Jul 2018
Posts: 15
Received Thanks: 9
Quote:
Originally Posted by turk55 View Post
Thanks for the link. Taking a look at it, the section of use here is:
Code:
void CGameMap::Cell2World(int iCellX,int iCellY,int& iWorldX,int& iWorldY)
{
	iWorldX	=_CELL_WIDTH*(iCellX-iCellY)/2+m_posOrigin.x; // _CELL_WIDTH = 64
	iWorldY	=_CELL_HEIGHT*(iCellX+iCellY)/2+m_posOrigin.y; // _CELL_HEIGHT = 32
}
If I input my values, I still don't get the right results. Assuming posOrigin is 0,0 for the top left corner, thus no current offset to the map, using the same 0,60 coordinate:
iWorldX = 64 * (0-60) / 2 = -1920
iWorldY = 32 * (0+60) / 2 = 960

What am I missing here?

-------------------------------------------------------------------------

Update:

Well, instead of trying to figure out the 'proper' equation for Y, I cheated a little and got accurate results.

If you can't find the equation, reverse engineer!

Since this gives me a valid X position
newPoint.x = ((x-1) - y) * tileHeight + (map->width / 2);

And we know that the mouse position > map coordinate is correct
int coordY = tempY / tileHeight + (map->width - tempX) / tileWidth;

Then.. just solve for Y using basic algebra!
newPoint.y = (y * tileHeight) - ((map->width - newPoint.x) * tileHeight) / tileWidth;

And voila! A valid tile. Note, I updated my draw polygon to actually just draw the tile instead of the bounding rectangle.


(Wondering how many posts I need until imbedded images start to work..)
Jonathis is offline  
Thanks
1 User
Old 08/31/2018, 09:42   #4
 
elite*gold: 0
Join Date: Feb 2009
Posts: 248
Received Thanks: 153
Code:
public Point ScreenPointToMapCoordinate(Point screenPoint)
        {
            var Y = screenPoint.Y / 32 + (this._puzzle.Width - screenPoint.X) / 64;
            var X = screenPoint.X / 64 + screenPoint.Y / 32;
            return new Point(X, Y);
        }

        public Point MapCoordinateToScreenPoint(Point mapCoordinate)
        {
            return new Point((mapCoordinate.X - mapCoordinate.Y) * 32 + this._puzzle.Width / 2
                , (mapCoordinate.X + mapCoordinate.Y - (this._mapData.Bounds.Height - 1)) * 16 + this._puzzle.Height / 2);
        }

 private void OnClick(object sender, MouseEventArgs e)
        {
         
            var npoint = new Point(this.Origin.X + e.X, this.Origin.Y + e.Y);
            var isocoords = isometricmap.ScreenPointToMapCoordinate(npoint);

...
}

public void ShowLocation(int x, int y)
        {
            var ScreenCoords = isometricmap.MapCoordinateToScreenPoint(new Point(x, y));

            this.Origin.X = ScreenCoords.X - RectangleMiddle.X;
            this.Origin.Y = ScreenCoords.Y - RectangleMiddle.Y;

            this.Origin.X = Math.Min(Math.Max(this.Origin.X, 0), Map.PuzzleBmp.Width - this.RenderSize.Width);
            this.Origin.Y = Math.Min(Math.Max(this.Origin.Y, 0), Map.PuzzleBmp.Height - this.RenderSize.Height);
            UpdateScreenRect();
        }

where:
 RectangleMiddle = new Point(panel1.Width / 2, panel1.Height / 2);

and randerSize is the panel i draw this.RenderSize = this.panel1.Size;

private void UpdateScreenRect()
        {
                if (CanDraw)
                {
                    var renderSize = new Size(Math.Min(this.panel1.Width, Map.PuzzleBmp.Width), Math.Min(this.panel1.Height, Map.PuzzleBmp.Height));
                    screenRect = new Rectangle(this.Origin.X, this.Origin.Y, this.panel1.Width, this.panel1.Height);
                    foreach (var DrawObjects in DrawingCollection.Values)
                    {
                        foreach (var obj in DrawObjects.Values)
                        {
                            if (obj.Enabled)
                                obj.UpdateScreenRect(screenRect);
                        }
                    }
                    var xCenter = (screenRect.X + screenRect.Width) / 2;
                    var yCenter = (screenRect.Y + screenRect.Height) / 2;
                    MiddleLocation = isometricmap.ScreenPointToMapCoordinate(new Point(xCenter, yCenter));
                }
            
        }
This is what i have found in my old project ... it was a educational project


teroareboss1 is offline  
Old 09/01/2018, 14:12   #5
 
elite*gold: 0
Join Date: Aug 2010
Posts: 988
Received Thanks: 1,075
Quote:
Originally Posted by Jonathis View Post
Thanks for the link. Taking a look at it, the section of use here is:
Code:
void CGameMap::Cell2World(int iCellX,int iCellY,int& iWorldX,int& iWorldY)
{
	iWorldX	=_CELL_WIDTH*(iCellX-iCellY)/2+m_posOrigin.x; // _CELL_WIDTH = 64
	iWorldY	=_CELL_HEIGHT*(iCellX+iCellY)/2+m_posOrigin.y; // _CELL_HEIGHT = 32
}
If I input my values, I still don't get the right results. Assuming posOrigin is 0,0 for the top left corner, thus no current offset to the map, using the same 0,60 coordinate:
iWorldX = 64 * (0-60) / 2 = -1920
iWorldY = 32 * (0+60) / 2 = 960

What am I missing here?
posOrigin.x = _CELL_WIDTH(64) * Map.Width / 2;
posOrigin.y = _CELL_HEIGHT(32) / 2;
{ Angelius } is offline  
Thanks
1 User
Old 09/02/2018, 23:26   #6
 
elite*gold: 0
Join Date: Mar 2005
Posts: 1,310
Received Thanks: 1,373
Quote:
Originally Posted by teroareboss1 View Post
Code:
public Point ScreenPointToMapCoordinate(Point screenPoint)
        {
            var Y = screenPoint.Y / 32 + (this._puzzle.Width - screenPoint.X) / 64;
            var X = screenPoint.X / 64 + screenPoint.Y / 32;
            return new Point(X, Y);
        }

        public Point MapCoordinateToScreenPoint(Point mapCoordinate)
        {
            return new Point((mapCoordinate.X - mapCoordinate.Y) * 32 + this._puzzle.Width / 2
                , (mapCoordinate.X + mapCoordinate.Y - (this._mapData.Bounds.Height - 1)) * 16 + this._puzzle.Height / 2);
        }

 private void OnClick(object sender, MouseEventArgs e)
        {
         
            var npoint = new Point(this.Origin.X + e.X, this.Origin.Y + e.Y);
            var isocoords = isometricmap.ScreenPointToMapCoordinate(npoint);

...
}

public void ShowLocation(int x, int y)
        {
            var ScreenCoords = isometricmap.MapCoordinateToScreenPoint(new Point(x, y));

            this.Origin.X = ScreenCoords.X - RectangleMiddle.X;
            this.Origin.Y = ScreenCoords.Y - RectangleMiddle.Y;

            this.Origin.X = Math.Min(Math.Max(this.Origin.X, 0), Map.PuzzleBmp.Width - this.RenderSize.Width);
            this.Origin.Y = Math.Min(Math.Max(this.Origin.Y, 0), Map.PuzzleBmp.Height - this.RenderSize.Height);
            UpdateScreenRect();
        }

where:
 RectangleMiddle = new Point(panel1.Width / 2, panel1.Height / 2);

and randerSize is the panel i draw this.RenderSize = this.panel1.Size;

private void UpdateScreenRect()
        {
                if (CanDraw)
                {
                    var renderSize = new Size(Math.Min(this.panel1.Width, Map.PuzzleBmp.Width), Math.Min(this.panel1.Height, Map.PuzzleBmp.Height));
                    screenRect = new Rectangle(this.Origin.X, this.Origin.Y, this.panel1.Width, this.panel1.Height);
                    foreach (var DrawObjects in DrawingCollection.Values)
                    {
                        foreach (var obj in DrawObjects.Values)
                        {
                            if (obj.Enabled)
                                obj.UpdateScreenRect(screenRect);
                        }
                    }
                    var xCenter = (screenRect.X + screenRect.Width) / 2;
                    var yCenter = (screenRect.Y + screenRect.Height) / 2;
                    MiddleLocation = isometricmap.ScreenPointToMapCoordinate(new Point(xCenter, yCenter));
                }
            
        }
This is what i have found in my old project ... it was a educational project
This code is not yours, it was stolen via a RAT on my computer years ago.
Ultimation is offline  
Thanks
2 Users
Old 09/03/2018, 00:33   #7
 
elite*gold: 12
Join Date: Jul 2011
Posts: 7,536
Received Thanks: 3,695
Quote:
Originally Posted by Ultimation View Post
This code is not yours, it was stolen via a RAT on my computer years ago.
Figured that was a little too smart for him to come up with. Nothing against him, just not his skillset. Had me surprised for a minute, but it makes sense now.
Spirited is offline  
Old 09/03/2018, 02:48   #8
 
elite*gold: 0
Join Date: Jul 2018
Posts: 15
Received Thanks: 9
Quote:
Originally Posted by { Angelius } View Post
posOrigin.x = _CELL_WIDTH(64) * Map.Width / 2;
posOrigin.y = _CELL_HEIGHT(32) / 2;
Wish I saw this before I started digging in the client to find what the calcs were in memory. Just came on to post my final findings with the chunks of code. After implementing the below, I am getting accurate results for all the maps.

First we have an amalgam of spirited's code, where the m_posOrigin x/y has the following formula
Code:
void GameMap::pointCoordinateToMapCoordinate(int x, int y) {
	int origin_x = (map_tile_width * 64 / 2);
	int origin_y = 16;
	int offset_x = origin_x - (map_width / 2);
	int offset_y = origin_y + (map_tile_height * 32 / 2) - (map_height / 2);

	int iWorldX = (offset_x + x) - origin_x;
	int iWorldY = (offset_y + y) - origin_y;

	double dWorldX = (double)iWorldX;
	double dWorldY = (double)iWorldY;
	double dCellWidth = (double)64;
	double dCellHeight = (double)32;

	double dTemp0 = (1.0*dWorldX) / (1.0*dCellWidth) + (1.0*dWorldY) / (1.0*dCellHeight);
	double dTemp1 = (1.0*dWorldY) / (1.0*dCellHeight) - (1.0*dWorldX) / (1.0*dCellWidth);
	mouseX = doubleToInt(dTemp0);
	mouseY = doubleToInt(dTemp1);
}


int GameMap::doubleToInt(double dValue) {
	if ((int)(dValue + 0.5) >(int)dValue)
		return int(dValue) + 1;
	else
		return int(dValue);
}
Next we have the Reverse function to retrieve a real x,y point on the map for placing objects/sprites etc.
Code:
SDL_Point GameMap::mapCoordinateToPoint(int x, int y) {
	int offset_x = (map_width / 2);
	int offset_y = (map_tile_height * 32 / 2) - (map_height / 2);

	SDL_Point newPoint;
	newPoint.x = ((x - y - 1) * 64 / 2) + offset_x;
	newPoint.y = ((x + y - 1) * 32 / 2) - offset_y;
	return newPoint;
}
I have fully tested both aspects of these, and cross examined (without objection) the coordinates and real points to the ones in the live game client, and it all matches up. I am a bit puzzled as to why my coord>point is different than spirited's and what Angelius references. Perhaps further operations are done to the given x,y at a later point and I am just consolidating them here? Well, I'm not going to dwell on it too much.
Jonathis is offline  
Thanks
1 User
Old 09/03/2018, 10:03   #9
 
elite*gold: 0
Join Date: Feb 2009
Posts: 248
Received Thanks: 153
Quote:
Originally Posted by Ultimation View Post
This code is not yours, it was stolen via a RAT on my computer years ago.


When i was working on the project i have used the unknownone project.Maybe this is the reason you think it was stolen from you.

teroareboss1 is offline  
Old 09/04/2018, 13:47   #10
 
elite*gold: 0
Join Date: Dec 2012
Posts: 1,723
Received Thanks: 914
Quote:
Originally Posted by teroareboss1 View Post


When i was working on the project i have used the unknownone project.Maybe this is the reason you think it was stolen from you.

You still ripped it off Unknownone and claimed it as yours from your project,when really you took it from another project and copied it into yours.

Smh.
Super Aids is offline  
Old 09/28/2018, 23:36   #11
 
elite*gold: 0
Join Date: Feb 2009
Posts: 248
Received Thanks: 153
Quote:
Originally Posted by Super Aids View Post
You still ripped it off Unknownone and claimed it as yours from your project,when really you took it from another project and copied it into yours.

Smh.
)))) nooob
teroareboss1 is offline  
Old 09/29/2018, 12:44   #12
 
elite*gold: 0
Join Date: Dec 2012
Posts: 1,723
Received Thanks: 914
Quote:
Originally Posted by teroareboss1 View Post
)))) nooob
Your stupidity was far beyond what I thought it was.

I'm sorry you got caught for being idiotic.


Super Aids is offline  
Reply

Tags
coordinates, mam, map



« Hopefully this is the right place for this... | | TORRENTS |[ VIDEOS ] C# Tutorials »

Similar Threads
CSS Map: Host_EndGame: Map coordinate extents are too large!! Check for errors!
12/11/2012 - Counter-Strike - 9 Replies
Hey, als ich das gelesen habe, dachte ich WTF??? Guckt euch die Screens an. NULL außer dem Grid. Bei Fehlersuche nur info_player_spawn, was unötig ist für CSS. Log im Anhang
COnquer coordinate in cartesian coordinate ?
02/07/2011 - CO2 Programming - 5 Replies
i m working on my minimap in pro4never proxy, i cleaning map from coquer site and put in picture box now i want to locate my char in this minimap likes in game :) but the coordinate in game are different view of classic cartesian coordinate :) some1 had module to trasform Conquer coordinate in cartesian coordinate ? or explain me why cood traslation in math not work :// :handsdown: i m working on this sistem



All times are GMT +1. The time now is 19:18.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

BTC: 33E6kMtxYa7dApCFzrS3Jb7U3NrVvo8nsK
ETH: 0xc6ec801B7563A4376751F33b0573308aDa611E05

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2019 elitepvpers All Rights Reserved.