Initial MSVC 2008 projects workspace
This commit is contained in:
745
l2ooghelper/MapWnd.cpp
Normal file
745
l2ooghelper/MapWnd.cpp
Normal file
@@ -0,0 +1,745 @@
|
||||
#include "stdafx.h"
|
||||
#include "Resource.h"
|
||||
#include "IL2Client.h"
|
||||
#include "MapWnd.h"
|
||||
#include "GlobalMapImages.h"
|
||||
#include "logger.h"
|
||||
#include "DBLayer.h"
|
||||
|
||||
extern GlobalMapImages g_mapImg;
|
||||
|
||||
WNDPROC OriginalMapStaticProc = NULL;
|
||||
|
||||
LRESULT CALLBACK NewMapStaticProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
//const int MapWindowBrushes = 1;
|
||||
const int MapWindowPens = 8;
|
||||
const int MapWindowFonts = 1;
|
||||
|
||||
struct MapWindowStruct
|
||||
{
|
||||
IL2Client *pcl; // L2Client interface
|
||||
HDC hdcc; // compatible DC
|
||||
HBITMAP hbm; // compatible bitmap
|
||||
// gdi
|
||||
HPEN pens[MapWindowPens];
|
||||
HFONT fonts[MapWindowFonts];
|
||||
// map image
|
||||
HDC hdcImage; // NULL if not loaded
|
||||
int geo_x;
|
||||
int geo_y;
|
||||
int geo_img_w;
|
||||
int geo_img_h;
|
||||
};
|
||||
|
||||
void Map_struct_create( MapWindowStruct *st )
|
||||
{
|
||||
HPEN hpenMob = CreatePen( PS_SOLID, 1, RGB(255,0,0) );
|
||||
HPEN hpenParty = CreatePen( PS_SOLID, 1, RGB(0,255,0) );
|
||||
HPEN hpenPc = CreatePen( PS_SOLID, 1, RGB(0,0,255) );
|
||||
HPEN hpenNpc = CreatePen( PS_SOLID, 1, RGB(255,255,0) );
|
||||
HPEN hpenMoveVector = CreatePen( PS_SOLID, 1, RGB(60,60,60) );
|
||||
HPEN hpenItem = CreatePen( PS_SOLID, 1, RGB(255,128,64) );
|
||||
HPEN hpenTarget = CreatePen( PS_SOLID, 1, RGB(255,0,255) );
|
||||
HPEN hpenDeadMob = CreatePen( PS_SOLID, 1, RGB(128,128,128) );
|
||||
//
|
||||
st->pens[0] = hpenMob;
|
||||
st->pens[1] = hpenParty;
|
||||
st->pens[2] = hpenPc;
|
||||
st->pens[3] = hpenNpc;
|
||||
st->pens[4] = hpenMoveVector;
|
||||
st->pens[5] = hpenItem;
|
||||
st->pens[6] = hpenTarget;
|
||||
st->pens[7] = hpenDeadMob;
|
||||
//
|
||||
//st->fonts[0] = CreateFont( 11, 5, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
|
||||
st->fonts[0] = CreateFont( 14, 5, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
|
||||
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
/*DEFAULT_QUALITY,*/ ANTIALIASED_QUALITY,
|
||||
FF_DONTCARE, TEXT("Arial") );
|
||||
// map image
|
||||
st->hdcImage = NULL;
|
||||
st->geo_x = 0;
|
||||
st->geo_y = 0;
|
||||
st->geo_img_w = 0;
|
||||
st->geo_img_h = 0;
|
||||
}
|
||||
|
||||
void Map_struct_delete( MapWindowStruct *st )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<MapWindowPens; i++ ) DeleteObject( st->pens[i] );
|
||||
for( i=0; i<MapWindowFonts; i++ ) DeleteObject( st->fonts[i] );
|
||||
DeleteDC( st->hdcc );
|
||||
DeleteObject( (HGDIOBJ)st->hbm );
|
||||
// map image
|
||||
st->hdcImage = NULL;
|
||||
// free all struct mem
|
||||
HeapFree( GetProcessHeap(), 0, st );
|
||||
}
|
||||
|
||||
void Map_struct_check_geo_square_and_preload_image( MapWindowStruct *st, int usr_x, int usr_y );
|
||||
|
||||
void SubclassMapWindowProc( HWND hWnd, IL2Client *pcl )
|
||||
{
|
||||
if( OriginalMapStaticProc == NULL )
|
||||
{
|
||||
OriginalMapStaticProc = (WNDPROC)(LPVOID)GetWindowLongPtr( hWnd, GWLP_WNDPROC );
|
||||
//log_error( LOG_OK, "SubclassMapWindowProc: saved old, userdata: 0x%08X\n", GetWindowLongPtr( hWnd, GWLP_USERDATA ) );
|
||||
}
|
||||
//
|
||||
RECT rc;
|
||||
GetClientRect( hWnd, &rc );
|
||||
//
|
||||
MapWindowStruct *st = (MapWindowStruct *)HeapAlloc( GetProcessHeap(), 0, sizeof(MapWindowStruct) );
|
||||
st->pcl = pcl;
|
||||
st->hdcc = NULL;
|
||||
st->hbm = NULL;
|
||||
Map_struct_create( st );
|
||||
//
|
||||
SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)st );
|
||||
SetWindowLongPtr( hWnd, GWLP_WNDPROC, (LONG_PTR)(LPVOID)NewMapStaticProc );
|
||||
}
|
||||
|
||||
void NewMapStatic_OnPaint( HWND hWnd );
|
||||
void NewMapStatic_OnMouseMove( HWND hWnd, WPARAM wParam, LPARAM lParam );
|
||||
void NewMapStatic_OnLButtonUp( HWND hWnd, WPARAM wParam, LPARAM lParam );
|
||||
void NewMapStatic_ReloadImage( HWND hWnd );
|
||||
|
||||
LRESULT CALLBACK NewMapStaticProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
LRESULT ret = 0;
|
||||
switch( uMsg )
|
||||
{
|
||||
case WM_PAINT: NewMapStatic_OnPaint( hWnd ); break;
|
||||
case WM_LBUTTONDOWN: NewMapStatic_OnLButtonUp( hWnd, wParam, lParam ); break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
MapWindowStruct *st = (MapWindowStruct *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
|
||||
Map_struct_delete( st );
|
||||
ret = CallWindowProc( OriginalMapStaticProc, hWnd, uMsg, wParam, lParam );
|
||||
} break;
|
||||
case WM_USER: NewMapStatic_ReloadImage( hWnd ); break;
|
||||
default: ret = CallWindowProc( OriginalMapStaticProc, hWnd, uMsg, wParam, lParam ); break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NewMapStatic_OnPaint( HWND hWnd )
|
||||
{
|
||||
//log_error_np( LOG_OK, "WM_PAINT\n" );
|
||||
//
|
||||
RECT rc;
|
||||
GetClientRect( hWnd, &rc );
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
int cx = w/2;
|
||||
int cy = h/2;
|
||||
int min_size = h;
|
||||
if( w < min_size ) min_size = w;
|
||||
MapWindowStruct *st = (MapWindowStruct *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
|
||||
// init hdc?
|
||||
if( st->hdcc == NULL )
|
||||
{
|
||||
HDC hdc = GetDC( hWnd ); // get window hdc
|
||||
st->hdcc = CreateCompatibleDC( hdc );
|
||||
st->hbm = CreateCompatibleBitmap( hdc, w, h );
|
||||
SelectObject( st->hdcc, (HGDIOBJ)st->hbm );
|
||||
SelectObject( st->hdcc, GetStockObject( WHITE_PEN ) );
|
||||
SelectObject( st->hdcc, GetStockObject( BLACK_BRUSH ) );
|
||||
SelectObject( st->hdcc, st->fonts[0] );
|
||||
SetStretchBltMode( st->hdcc, HALFTONE ); // TODO: check StretchBlt mode
|
||||
// release window hdc
|
||||
ReleaseDC( hWnd, hdc );
|
||||
//log_error( LOG_OK, "NewMapStaticProc(): init %d x %d\n", w, h );
|
||||
st->hdcImage = NULL;
|
||||
}
|
||||
// init
|
||||
const int map_text_h = 13;
|
||||
const double max_range = 20000.0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// scale - <20>-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>2, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" <20> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
double scale = max_range * (double)st->pcl->get_MapScale() / 100.0;
|
||||
// scale_k <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20>2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
double scale_k = scale / (double)min_size;
|
||||
unsigned int nDisplayed = 0;
|
||||
unsigned int i;
|
||||
int map_dx = 0, map_dy = 0, map_dz = 0;
|
||||
UserInfo *pusr = st->pcl->get_UserInfo();
|
||||
int usr_x = pusr->x;
|
||||
int usr_y = pusr->y;
|
||||
int usr_z = pusr->z;
|
||||
int usr_xDst = pusr->xDst;
|
||||
int usr_yDst = pusr->yDst;
|
||||
int screen_dx = 0, screen_dy = 0;
|
||||
int draw_x = 0, draw_y = 0;
|
||||
int sq_w = 4;
|
||||
// map show text params
|
||||
st_MapShowParams map_show;
|
||||
st->pcl->getMapShowParams( &map_show );
|
||||
|
||||
//
|
||||
// all drawing below
|
||||
//
|
||||
// save old gdi objects
|
||||
//HBRUSH oldBrush = (HBRUSH)SelectObject( st->hdcc, GetStockObject( NULL_BRUSH ) );
|
||||
//HPEN oldPen = (HPEN)SelectObject( st->hdcc, GetStockObject( WHITE_PEN ) );
|
||||
//HFONT oldFont = (HFONT)SelectObject( st->hdcc, GetStockObject( ANSI_VAR_FONT ) );
|
||||
//
|
||||
SelectObject( st->hdcc, GetStockObject( BLACK_PEN ) );
|
||||
SelectObject( st->hdcc, GetStockObject( BLACK_BRUSH ) );
|
||||
SetBkMode( st->hdcc, TRANSPARENT );
|
||||
SetTextColor( st->hdcc, RGB(255,255,255) );
|
||||
|
||||
// map background:
|
||||
Rectangle( st->hdcc, 0, 0, w, h ); // black rect
|
||||
// if map show enabled, show
|
||||
if( map_show.realmap ) // real map
|
||||
{
|
||||
Map_struct_check_geo_square_and_preload_image( st, usr_x, usr_y );
|
||||
if( st->hdcImage && (st->geo_x>0) && (st->geo_y>0) )
|
||||
{
|
||||
// preloaded into surface, BitBlt/StretchBlt
|
||||
// scale - <20>-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>2, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" <20> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 33333 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// geoimg_scale - <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20>2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
double geoimg_scale = ((double)GlobalMapImages::GEO_BOX_L2_SIZE) / ((double)st->geo_img_w);
|
||||
// screen_geoimg_w - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD>
|
||||
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>).
|
||||
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int screen_geoimg_w = (int)( (scale / geoimg_scale) + 0.5 );
|
||||
int geo_square_l2_x = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20>2 <20><><EFBFBD><EFBFBD>
|
||||
int geo_square_l2_y = 0;
|
||||
GlobalMapImages::GetGeoSquareStartL2Coords( st->geo_x, st->geo_y, &geo_square_l2_x, &geo_square_l2_y );
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20>2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int geo_square_l2_user_dx = usr_x - geo_square_l2_x;
|
||||
int geo_square_l2_user_dy = usr_y - geo_square_l2_y;
|
||||
int geoimg_offset_x = (int)( ((double)geo_square_l2_user_dx - scale/2 ) / geoimg_scale + 0.5 );
|
||||
int geoimg_offset_y = (int)( ((double)geo_square_l2_user_dy - scale/2 ) / geoimg_scale + 0.5 );
|
||||
//
|
||||
StretchBlt( st->hdcc,
|
||||
0, 0, min_size, min_size,
|
||||
st->hdcImage,
|
||||
geoimg_offset_x, geoimg_offset_y, screen_geoimg_w, screen_geoimg_w,
|
||||
SRCCOPY );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// display all npcs
|
||||
//
|
||||
unsigned int count = 0;
|
||||
NpcArray *pnpcs = st->pcl->get_WorldNpcs();
|
||||
if( pnpcs->getCount() > 0 )
|
||||
{
|
||||
SelectObject( st->hdcc, st->pens[3] );
|
||||
nDisplayed = 0;
|
||||
pnpcs->Lock();
|
||||
count = pnpcs->getCount();
|
||||
for( i=0; i<NpcArray::NPCA_MAX_NPCS; i++ )
|
||||
{
|
||||
if( pnpcs->npcs_array[i]->isUnused() ) continue;
|
||||
nDisplayed++;
|
||||
//
|
||||
map_dx = pnpcs->npcs_array[i]->x - usr_x;
|
||||
map_dy = pnpcs->npcs_array[i]->y - usr_y;
|
||||
map_dz = pnpcs->npcs_array[i]->z - usr_z;
|
||||
if( abs( map_dz ) >= map_show.zrange )
|
||||
{
|
||||
log_error( LOG_DEBUG, "Denied display npc [%S] because map_dz is %d (zrange %d)\n",
|
||||
pnpcs->npcs_array[i]->charName, map_dz, map_show.zrange );
|
||||
continue; // not fit in zrange
|
||||
}
|
||||
//
|
||||
screen_dx = (int)( (double)map_dx / scale_k );
|
||||
screen_dy = (int)( (double)map_dy / scale_k );
|
||||
//
|
||||
SelectObject( st->hdcc, st->pens[3] ); // npc pen
|
||||
if( pnpcs->npcs_array[i]->isAttackable ) SelectObject( st->hdcc, st->pens[0] ); // mob pen
|
||||
if( pnpcs->npcs_array[i]->isAlikeDead ) SelectObject( st->hdcc, st->pens[7] ); // dead pen
|
||||
if( pnpcs->npcs_array[i]->objectID == pusr->targetObjectID ) SelectObject( st->hdcc, st->pens[6] ); // target pen
|
||||
draw_x = cx + screen_dx;
|
||||
draw_y = cy + screen_dy;
|
||||
Rectangle( st->hdcc, draw_x - 1, draw_y - 1, draw_x + sq_w, draw_y + sq_w );
|
||||
// vector?
|
||||
if( map_show.vectors )
|
||||
{
|
||||
if( pnpcs->npcs_array[i]->isMoving() )
|
||||
{
|
||||
int map_vector_dx = pnpcs->npcs_array[i]->xDst - pnpcs->npcs_array[i]->x;
|
||||
int map_vector_dy = pnpcs->npcs_array[i]->yDst - pnpcs->npcs_array[i]->y;
|
||||
int screen_vector_dx = (int)( (double)map_vector_dx / scale_k );
|
||||
int screen_vector_dy = (int)( (double)map_vector_dy / scale_k );
|
||||
SelectObject( st->hdcc, st->pens[4] );
|
||||
MoveToEx( st->hdcc, draw_x+1, draw_y+1, NULL );
|
||||
LineTo( st->hdcc, draw_x+1+screen_vector_dx, draw_y+1+screen_vector_dy );
|
||||
}
|
||||
}
|
||||
// npc name?
|
||||
bool show_text = false;
|
||||
if( (pnpcs->npcs_array[i]->isAttackable) && map_show.mobs ) show_text = true;
|
||||
if( (!pnpcs->npcs_array[i]->isAttackable) && map_show.npcs ) show_text = true;
|
||||
if( show_text )
|
||||
{
|
||||
wchar_t *text = pnpcs->npcs_array[i]->charName;
|
||||
//TextOutW( st->hdcc, draw_x, draw_y, text, wcslen( text ) );
|
||||
rc.left = draw_x - 100;
|
||||
rc.right = draw_x + 100;
|
||||
rc.bottom = draw_y;
|
||||
rc.top = rc.bottom - map_text_h;
|
||||
DrawText( st->hdcc, text, wcslen(text), &rc, DT_CENTER | DT_VCENTER );
|
||||
}
|
||||
//
|
||||
if( nDisplayed >= count ) break;
|
||||
}
|
||||
pnpcs->Unlock();
|
||||
}
|
||||
//
|
||||
// display all items
|
||||
//
|
||||
GIArray *pitems = st->pcl->get_WorldItems();
|
||||
if( pitems->getCount() > 0 )
|
||||
{
|
||||
nDisplayed = 0;
|
||||
SelectObject( st->hdcc, st->pens[5] );
|
||||
pitems->Lock();
|
||||
count = pitems->getCount();
|
||||
for( i=0; i<GIArray::GA_MAX_ITEMS; i++ )
|
||||
{
|
||||
if( pitems->gi_array[i]->isUnused() ) continue;
|
||||
nDisplayed++;
|
||||
//
|
||||
map_dx = pitems->gi_array[i]->x - usr_x;
|
||||
map_dy = pitems->gi_array[i]->y - usr_y;
|
||||
map_dz = pitems->gi_array[i]->z - usr_z;
|
||||
if( abs( map_dz ) >= map_show.zrange ) continue; // not fit in zrange
|
||||
//
|
||||
screen_dx = (int)( (double)map_dx / scale_k );
|
||||
screen_dy = (int)( (double)map_dy / scale_k );
|
||||
//
|
||||
draw_x = cx + screen_dx;
|
||||
draw_y = cy + screen_dy;
|
||||
Rectangle( st->hdcc, draw_x - 1, draw_y - 1, draw_x + sq_w, draw_y + sq_w );
|
||||
// show name?
|
||||
if( map_show.items )
|
||||
{
|
||||
wchar_t text[256] = {0};
|
||||
// itemName is no longer part og GroundItem
|
||||
//if( pitems->gi_array[i]->itemName[0] )
|
||||
// MultiByteToWideChar( CP_ACP, 0, pitems->gi_array[i]->itemName, -1, text, 255 );
|
||||
// use cached DB layer instead
|
||||
DBLayer_getItemName( pitems->gi_array[i]->itemID, text, 255 );
|
||||
if( text[0] )
|
||||
{
|
||||
rc.left = draw_x - 100;
|
||||
rc.right = draw_x + 100;
|
||||
rc.bottom = draw_y;
|
||||
rc.top = rc.bottom - map_text_h;
|
||||
DrawText( st->hdcc, text, wcslen(text), &rc, DT_CENTER | DT_VCENTER );
|
||||
}
|
||||
}
|
||||
//
|
||||
if( nDisplayed >= count ) break;
|
||||
}
|
||||
pitems->Unlock();
|
||||
}
|
||||
//
|
||||
//
|
||||
// display all players
|
||||
//
|
||||
UserParty *pparty = st->pcl->get_Party();
|
||||
CharArray *pchars = st->pcl->get_WorldChars();
|
||||
if( pchars->GetCount() > 0 )
|
||||
{
|
||||
nDisplayed = 0;
|
||||
SelectObject( st->hdcc, st->pens[2] ); // pc
|
||||
pchars->Lock();
|
||||
count = pchars->GetCount();
|
||||
for( i=0; i<CharArray::CHARARRAY_MAX_CHARS; i++ )
|
||||
{
|
||||
if( pchars->chars_array[i]->isUnused() ) continue;
|
||||
nDisplayed++;
|
||||
//
|
||||
map_dx = pchars->chars_array[i]->x - usr_x;
|
||||
map_dy = pchars->chars_array[i]->y - usr_y;
|
||||
map_dz = pchars->chars_array[i]->z - usr_z;
|
||||
if( abs( map_dz ) >= map_show.zrange ) continue; // not fit in zrange
|
||||
//
|
||||
screen_dx = (int)( (double)map_dx / scale_k );
|
||||
screen_dy = (int)( (double)map_dy / scale_k );
|
||||
//
|
||||
draw_x = cx + screen_dx;
|
||||
draw_y = cy + screen_dy;
|
||||
SelectObject( st->hdcc, st->pens[2] ); // always select pc pen beore draw
|
||||
if( pparty->isInParty( pchars->chars_array[i]->objectID, NULL ) ) SelectObject( st->hdcc, st->pens[1] ); // party
|
||||
if( pchars->chars_array[i]->objectID == pusr->targetObjectID ) SelectObject( st->hdcc, st->pens[6] ); // target
|
||||
Rectangle( st->hdcc, draw_x - 1, draw_y - 1, draw_x + sq_w, draw_y + sq_w );
|
||||
// vector?
|
||||
if( map_show.vectors )
|
||||
{
|
||||
if( pchars->chars_array[i]->isMoving() )
|
||||
{
|
||||
int map_vector_dx = pchars->chars_array[i]->xDst - pchars->chars_array[i]->x;
|
||||
int map_vector_dy = pchars->chars_array[i]->yDst - pchars->chars_array[i]->y;
|
||||
int screen_vector_dx = (int)( (double)map_vector_dx / scale_k );
|
||||
int screen_vector_dy = (int)( (double)map_vector_dy / scale_k );
|
||||
SelectObject( st->hdcc, st->pens[4] );
|
||||
MoveToEx( st->hdcc, draw_x+1, draw_y+1, NULL );
|
||||
LineTo( st->hdcc, draw_x+1+screen_vector_dx, draw_y+1+screen_vector_dy );
|
||||
}
|
||||
}
|
||||
// show name?
|
||||
if( map_show.pcs || (pchars->chars_array[i]->privateStoreType > 0) )
|
||||
{
|
||||
wchar_t *text = pchars->chars_array[i]->charName;
|
||||
//TextOutW( st->hdcc, draw_x, draw_y, text, wcslen( text ) );
|
||||
rc.left = draw_x - 100;
|
||||
rc.right = draw_x + 100;
|
||||
rc.bottom = draw_y;
|
||||
rc.top = rc.bottom - map_text_h;
|
||||
if( map_show.pcs ) DrawText( st->hdcc, text, wcslen(text), &rc, DT_CENTER | DT_VCENTER );
|
||||
if( pchars->chars_array[i]->privateStoreType > 0 )
|
||||
{
|
||||
wchar_t *storemsg = NULL;
|
||||
COLORREF textColor = RGB(255,255,255);
|
||||
switch( pchars->chars_array[i]->privateStoreType )
|
||||
{
|
||||
case L2Player::PRIVATE_STORE_BUY:
|
||||
{
|
||||
if( map_show.buyshop )
|
||||
{
|
||||
storemsg = pchars->chars_array[i]->privateStoreMsgBuy;
|
||||
textColor = RGB(255,255,151);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_SELL:
|
||||
{
|
||||
if( map_show.sellshop )
|
||||
{
|
||||
storemsg = pchars->chars_array[i]->privateStoreMsgSell;
|
||||
textColor = RGB(255,108,255);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_CRAFT:
|
||||
{
|
||||
if( map_show.craftshop )
|
||||
{
|
||||
storemsg = pchars->chars_array[i]->privateStoreMsgRecipe;
|
||||
textColor = RGB(250,204,46);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_PACKAGESALE:
|
||||
{
|
||||
if( map_show.sellshop )
|
||||
{
|
||||
storemsg = pchars->chars_array[i]->privateStoreMsgSell;
|
||||
textColor = RGB(253,80,43);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if( storemsg )
|
||||
{
|
||||
rc.top -= (map_text_h+1);
|
||||
rc.bottom -= (map_text_h+1);
|
||||
SetTextColor( st->hdcc, textColor );
|
||||
DrawText( st->hdcc, storemsg, wcslen(storemsg), &rc, DT_CENTER | DT_VCENTER );
|
||||
SetTextColor( st->hdcc, RGB(255,255,255) );
|
||||
}
|
||||
} // privateStoreType > 0
|
||||
} // show_pcs
|
||||
//
|
||||
if( nDisplayed >= count ) break;
|
||||
}
|
||||
pchars->Unlock();
|
||||
}
|
||||
//
|
||||
// display self in center
|
||||
//
|
||||
SelectObject( st->hdcc, GetStockObject( WHITE_PEN ) );
|
||||
Rectangle( st->hdcc, cx-1, cy-1, cx+sq_w, cy+sq_w );
|
||||
// user name?
|
||||
if( map_show.pcs || (pusr->privateStoreType > 0) )
|
||||
{
|
||||
wchar_t *text = pusr->charName;
|
||||
rc.left = cx - 100;
|
||||
rc.right = cx + 100;
|
||||
rc.bottom = cy;
|
||||
rc.top = rc.bottom - map_text_h;
|
||||
if( map_show.pcs ) DrawText( st->hdcc, text, wcslen(text), &rc, DT_CENTER | DT_VCENTER );
|
||||
// self shop message?
|
||||
if( pusr->privateStoreType > 0 )
|
||||
{
|
||||
wchar_t *storemsg = NULL;
|
||||
COLORREF textColor = RGB(255,255,255);
|
||||
switch( pusr->privateStoreType )
|
||||
{
|
||||
case L2Player::PRIVATE_STORE_BUY:
|
||||
{
|
||||
if( map_show.buyshop )
|
||||
{
|
||||
storemsg = pusr->privateStoreMsgBuy;
|
||||
textColor = RGB(255,255,151);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_SELL:
|
||||
{
|
||||
if( map_show.sellshop )
|
||||
{
|
||||
storemsg = pusr->privateStoreMsgSell;
|
||||
textColor = RGB(255,108,255);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_CRAFT:
|
||||
{
|
||||
if( map_show.craftshop )
|
||||
{
|
||||
storemsg = pusr->privateStoreMsgRecipe;
|
||||
textColor = RGB(250,204,46);
|
||||
}
|
||||
} break;
|
||||
case L2Player::PRIVATE_STORE_PACKAGESALE:
|
||||
{
|
||||
if( map_show.sellshop )
|
||||
{
|
||||
storemsg = pusr->privateStoreMsgSell;
|
||||
textColor = RGB(253,80,43);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if( storemsg )
|
||||
{
|
||||
rc.top -= (map_text_h+1);
|
||||
rc.bottom -= (map_text_h+1);
|
||||
SetTextColor( st->hdcc, textColor );
|
||||
DrawText( st->hdcc, storemsg, wcslen(storemsg), &rc, DT_CENTER | DT_VCENTER );
|
||||
SetTextColor( st->hdcc, RGB(255,255,255) );
|
||||
}
|
||||
} // privateStoreType > 0
|
||||
} // show_pcs
|
||||
// user move vector?
|
||||
if( map_show.vectors )
|
||||
{
|
||||
if( pusr->isMoving() )
|
||||
{
|
||||
int map_vector_dx = usr_xDst - usr_x;
|
||||
int map_vector_dy = usr_yDst - usr_y;
|
||||
int screen_vector_dx = (int)( (double)map_vector_dx / scale_k );
|
||||
int screen_vector_dy = (int)( (double)map_vector_dy / scale_k );
|
||||
SelectObject( st->hdcc, st->pens[4] );
|
||||
MoveToEx( st->hdcc, cx+1, cy+1, NULL );
|
||||
LineTo( st->hdcc, cx+1+screen_vector_dx, cy+1+screen_vector_dy );
|
||||
}
|
||||
}
|
||||
// select old GDI objects
|
||||
//SelectObject( st->hdcc, oldPen );
|
||||
//SelectObject( st->hdcc, oldBrush );
|
||||
// copy surface
|
||||
//PAINTSTRUCT ps;
|
||||
//HDC hdc = BeginPaint( hWnd, &ps );
|
||||
HDC hdc = GetDC( hWnd );
|
||||
BitBlt( hdc, 0, 0, w, h, st->hdcc, 0, 0, SRCCOPY );
|
||||
//EndPaint( hWnd, &ps );
|
||||
ReleaseDC( hWnd, hdc );
|
||||
ValidateRect( hWnd, NULL );
|
||||
}
|
||||
|
||||
bool Map_isInTargetRect( int mx, int my, int object_x, int object_y )
|
||||
{
|
||||
const int d = 40;
|
||||
int l = mx - d/4;
|
||||
int r = mx + d;
|
||||
int t = my - d/4;
|
||||
int b = my + d;
|
||||
if( (object_x>=l) && (object_x<=r) && (object_y>=t) && (object_y<=b) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NewMapStatic_OnLButtonUp( HWND hWnd, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
UNREFERENCED_PARAMETER(wParam);
|
||||
//log_error_np( LOG_OK, "WM_LBUTTONUP\n" );
|
||||
// message params
|
||||
int mx = GET_X_LPARAM(lParam);
|
||||
int my = GET_Y_LPARAM(lParam);
|
||||
// window dimensions
|
||||
RECT rc;
|
||||
GetClientRect( hWnd, &rc );
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
int cx = w/2;
|
||||
int cy = h/2;
|
||||
int min_size = h;
|
||||
if( w < min_size ) min_size = w;
|
||||
MapWindowStruct *st = (MapWindowStruct *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
|
||||
// init default scale state
|
||||
const double max_range = 20000.0;
|
||||
double scale = max_range * (double)st->pcl->get_MapScale() / 100.0;
|
||||
double scale_k = scale / (double)min_size;
|
||||
unsigned int nPassed = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int count;
|
||||
int map_dx = 0, map_dy = 0; // map_dz = 0;
|
||||
UserInfo *pusr = st->pcl->get_UserInfo();
|
||||
int usr_x = pusr->x;
|
||||
int usr_y = pusr->y;
|
||||
int usr_z = pusr->z;
|
||||
//int usr_xDst = pusr->xDst;
|
||||
//int usr_yDst = pusr->yDst;
|
||||
int screen_dx = 0, screen_dy = 0;
|
||||
//int draw_x = 0, draw_y = 0;
|
||||
//int sq_w = 4;
|
||||
// map show text params
|
||||
st_MapShowParams map_show;
|
||||
st->pcl->getMapShowParams( &map_show );
|
||||
//
|
||||
// user clicked mouse in coords mx, my relative to 0,0 of window client area
|
||||
// but we know only user's L2 map coords
|
||||
// to get real L2 map coords of user click, we must calc click delta from user coords
|
||||
//
|
||||
screen_dx = mx - cx; // if mx > cx, user moves east
|
||||
screen_dy = my - cy; // if my > cy, user moves south
|
||||
map_dx = (int)( screen_dx * scale_k );
|
||||
map_dy = (int)( screen_dy * scale_k );
|
||||
int map_x = usr_x + map_dx;
|
||||
int map_y = usr_y + map_dy;
|
||||
//log_error( LOG_OK, "m(%d,%d) screen(%d,%d) map(%d,%d)\n", mx, my, screen_dx, screen_dy, map_dx, map_dy );
|
||||
|
||||
// maybe target self?
|
||||
if( (screen_dx>-5) && (screen_dx<5) && (screen_dy>-5) && (screen_dy<5) )
|
||||
{
|
||||
st->pcl->game_Action( pusr->objectID );
|
||||
return;
|
||||
}
|
||||
|
||||
// first try to target players
|
||||
nPassed = 0;
|
||||
CharArray *ca = st->pcl->get_WorldChars();
|
||||
count = ca->GetCount();
|
||||
ca->Lock();
|
||||
for( i=0; i<count; i++ )
|
||||
{
|
||||
if( ca->chars_array[i]->isUnused() ) continue;
|
||||
nPassed++;
|
||||
// Z-range limit (if this char is not be displayed on map, it cannot be targeted)
|
||||
if( abs( ca->chars_array[i]->z - usr_z ) > map_show.zrange ) continue;
|
||||
// hit target coords?
|
||||
if( Map_isInTargetRect( map_x, map_y, ca->chars_array[i]->x, ca->chars_array[i]->y ) )
|
||||
{
|
||||
ca->Unlock();
|
||||
st->pcl->game_Action( ca->chars_array[i]->objectID );
|
||||
return;
|
||||
}
|
||||
if( nPassed >= count ) break;
|
||||
}
|
||||
ca->Unlock();
|
||||
ca = NULL;
|
||||
// if we here, PC not targeted
|
||||
|
||||
// try to target NPC / mob
|
||||
nPassed = 0;
|
||||
NpcArray *na = st->pcl->get_WorldNpcs();
|
||||
count = na->getCount();
|
||||
na->Lock();
|
||||
for( i=0; i<count; i++ )
|
||||
{
|
||||
if( na->npcs_array[i]->isUnused() ) continue;
|
||||
nPassed++;
|
||||
// Z-range limit (if this npc is not be displayed on map, it cannot be targeted)
|
||||
if( abs( na->npcs_array[i]->z - usr_z ) > map_show.zrange ) continue;
|
||||
// hit target coords?
|
||||
if( Map_isInTargetRect( map_x, map_y, na->npcs_array[i]->x, na->npcs_array[i]->y ) )
|
||||
{
|
||||
na->Unlock();
|
||||
st->pcl->game_Action( na->npcs_array[i]->objectID );
|
||||
return;
|
||||
}
|
||||
if( nPassed >= count ) break;
|
||||
}
|
||||
na->Unlock();
|
||||
na = NULL;
|
||||
// if we here, no PC/NPC/Mob targeted :(
|
||||
|
||||
// maybe try to pick up item?
|
||||
nPassed = 0;
|
||||
GIArray *ga = st->pcl->get_WorldItems();
|
||||
count = ga->getCount();
|
||||
ga->Lock();
|
||||
for( i=0; i<count; i++ )
|
||||
{
|
||||
if( ga->gi_array[i]->isUnused() ) continue;
|
||||
nPassed++;
|
||||
// Z-range limit (if this char is not be displayed on map, it cannot be targeted)
|
||||
if( abs( ga->gi_array[i]->z - usr_z ) > map_show.zrange ) continue;
|
||||
// hit target coords?
|
||||
if( Map_isInTargetRect( map_x, map_y, ga->gi_array[i]->x, ga->gi_array[i]->y ) )
|
||||
{
|
||||
ga->Unlock();
|
||||
st->pcl->game_Action( ga->gi_array[i]->objectID );
|
||||
return;
|
||||
}
|
||||
if( nPassed >= count ) break;
|
||||
}
|
||||
ga->Unlock();
|
||||
ga = NULL;
|
||||
|
||||
// nothing targeted, move ? :)
|
||||
st->pcl->game_MoveToDelta( map_dx, map_dy );
|
||||
}
|
||||
|
||||
void Map_struct_check_geo_square_and_preload_image( MapWindowStruct *st, int usr_x, int usr_y )
|
||||
{
|
||||
int cur_geo_x = 0, cur_geo_y = 0;
|
||||
GlobalMapImages::GetGeoMapSquareXYByL2Coords( usr_x, usr_y, &cur_geo_x, &cur_geo_y );
|
||||
if( (st->geo_x != cur_geo_x) || (st->geo_y != cur_geo_y) )
|
||||
{
|
||||
//
|
||||
log_error_np( LOG_OK, "Geo: square changed: %d,%d -> %d,%d\n",
|
||||
st->geo_x, st->geo_y, cur_geo_x, cur_geo_y );
|
||||
// geodata square changed! change coords
|
||||
st->geo_x = cur_geo_x;
|
||||
st->geo_y = cur_geo_y;
|
||||
// NULL current vars
|
||||
st->hdcImage = NULL;
|
||||
st->geo_img_w = 0;
|
||||
st->geo_img_h = 0;
|
||||
// load new
|
||||
g_mapImg.preloadSquare( cur_geo_x, cur_geo_y );
|
||||
if( g_mapImg.isSquareLoaded( cur_geo_x, cur_geo_y ) )
|
||||
{
|
||||
st->hdcImage = g_mapImg.getSquareHDC( cur_geo_x, cur_geo_y );
|
||||
g_mapImg.getSquareWH( cur_geo_x, cur_geo_y, st->geo_img_w, st->geo_img_h );
|
||||
log_error_np( LOG_OK, "Geo: preloaded geo square [%d_%d] img size [%d x %d]\n",
|
||||
cur_geo_x, cur_geo_y, st->geo_img_w, st->geo_img_h );
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error( LOG_WARNING, "Geo: cannot preload geo square [%d_%d]\n", cur_geo_x, cur_geo_y );
|
||||
/*char aCurDir[256];
|
||||
GetCurrentDirectoryA( 200, aCurDir );
|
||||
log_error( LOG_WARNING, "Geo: curDir [%s]\n", aCurDir );*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewMapStatic_ReloadImage( HWND hWnd )
|
||||
{
|
||||
MapWindowStruct *st = (MapWindowStruct *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
|
||||
// reload
|
||||
log_error_np( LOG_OK, "MapWindow: reload square: %d,%d\n", st->geo_x, st->geo_y );
|
||||
// NULL current vars
|
||||
st->hdcImage = NULL;
|
||||
st->geo_img_w = 0;
|
||||
st->geo_img_h = 0;
|
||||
// load new
|
||||
g_mapImg.preloadSquare( st->geo_x, st->geo_y );
|
||||
if( g_mapImg.isSquareLoaded( st->geo_x, st->geo_y ) )
|
||||
{
|
||||
st->hdcImage = g_mapImg.getSquareHDC( st->geo_x, st->geo_y );
|
||||
g_mapImg.getSquareWH( st->geo_x, st->geo_y, st->geo_img_w, st->geo_img_h );
|
||||
log_error_np( LOG_OK, "MapWindow: reloaded geo square [%d_%d] img size [%d x %d]\n",
|
||||
st->geo_x, st->geo_y, st->geo_img_w, st->geo_img_h );
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error( LOG_WARNING, "MapWindow: cannot reload geo square [%d_%d]\n", st->geo_x, st->geo_y );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user