console.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:33k
源码类别:

游戏

开发平台:

Visual C++

  1. #include "global.h"
  2. #include "console.h"
  3. #include "network.h"
  4. #include "dxutil.h"
  5. #include "ddutil.h"
  6. #include "dsutil.h"
  7. #define DEFTURNSTEP 8
  8. #define DEFPROTECTTIME 600 // 20*30fps
  9. #define WAITTIMEOUT 5000 // second
  10. #define BULLET_REBOUND
  11. #define _TK_DEBUG
  12. //-----------------------------------------------------------------------------
  13. // Global variables
  14. //-----------------------------------------------------------------------------
  15. bool bRecvCmd = false;
  16. TANKCMD m_pCmd[20];
  17. CDisplay Display;
  18. CSurface *pResource, *pMapGrass, *pMapSolid, *pRes2;
  19. CSurface *pText;
  20. LPDIRECTDRAWSURFACE7 pddsSolid, pddsGrass, pddsRes, pddsRes2;
  21. CSoundManager SoundManager;
  22. CSound *pFire, *pBoom;
  23. char *szFireWave = "Wave/bfire.wav";
  24. char *szBoomWave = "Wave/lboom.wav";
  25. char fps[20] = "FPS: ";
  26. int g_FrameBig = 640, g_FrameSmall = 32, g_FrameLeft = 608,
  27. g_FrameWidth = 640, g_FrameHeight = 640, g_FrameBasis = 16;
  28. //-----------------------------------------------------------------------------
  29. // Variables defined in other files
  30. //-----------------------------------------------------------------------------
  31. extern CMsgList NetList;
  32. extern HWND hMainWnd, hChildWnd;
  33. extern unsigned int uiCurrentCmd;
  34. extern bool bFired;
  35. unsigned int cmdbuf;
  36. bool firebuf;
  37. bool bFresh = true;
  38. //-----------------------------------------------------------------------------
  39. // 
  40. //-----------------------------------------------------------------------------
  41. #ifdef _TK_DEBUG
  42. #include <time.h>
  43. #include <sys/timeb.h>
  44. #include <stdio.h>
  45. #define MAXDEBUG 128
  46. HANDLE hfile;
  47. char szDebugFile[20];
  48. void DebugOutput( int num, ... ) {
  49. char *s = new char[MAXDEBUG];
  50. s[0] = 0;
  51. // add time stamp
  52. struct _timeb tstruct;
  53. _ftime( &tstruct );
  54. _strtime( s );
  55. lstrcat(s, ":");
  56. sprintf( s+strlen(s), "%u", tstruct.millitm );
  57. lstrcat(s, ": ");
  58. // add messages
  59. va_list vl;
  60.     va_start( vl, num );
  61.     for( int i = 0; i<num ; i++ )
  62.         lstrcat( s, va_arg( vl, char * ) );
  63.     va_end( vl );
  64. lstrcat( s, "rn" );
  65. // output msg
  66. if ( hfile ) {
  67. DWORD ret;
  68. WriteFile( hfile, s, strlen(s)+1, &ret, NULL );
  69. }
  70. }
  71. #else
  72. #define DebugOutput
  73. #endif
  74. //-----------------------------------------------------------------------------
  75. // Functions defined in other files
  76. //-----------------------------------------------------------------------------
  77. bool SendMsg(int msg, LPVOID param, int size);
  78. //-----------------------------------------------------------------------------
  79. // Name: 
  80. // Desc: 
  81. //-----------------------------------------------------------------------------
  82. bool SendCmdMsg( TANKCMD * pcmds, int num, int local ) {
  83. int size = sizeof(int)*2 + num * sizeof(TANKCMD);
  84. char *param = new char[size];
  85. int *ibuf = (int *)param;
  86. ibuf[0] = local;
  87. ibuf[1] = num;
  88. memcpy( ibuf+2, pcmds, num*sizeof(TANKCMD));
  89. SendMsg( NETMSGTK_CMDINFO, param, size );
  90. delete[] param;
  91. return true;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Name: 
  95. // Desc: 
  96. //-----------------------------------------------------------------------------
  97. Console::Console() {
  98. con_version = ASIDER_GAME_TANK_VER_ALPHA3;
  99. err_code = 0;
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Name: 
  103. // Desc: 
  104. //-----------------------------------------------------------------------------
  105. Console::~Console() {
  106. #ifdef _TK_DEBUG
  107. CloseHandle( hfile );
  108. #endif
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Name: 
  112. // Desc: 
  113. //-----------------------------------------------------------------------------
  114. void Console::ErrorTrigger( unsigned int error ) {
  115. if ( error != 0 )
  116. MessageBox( NULL, "Something Error :)", "Error", MB_ICONERROR );
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Name: 
  120. // Desc: 
  121. //-----------------------------------------------------------------------------
  122. ConsoleNet::ConsoleNet() {
  123. m_dwStatus = CONSTAT_NOTHING;
  124. m_nPlayers = 0;
  125. m_nComputers = 0;
  126. m_nComPerTeam = 0;
  127. m_nLocal = 0;
  128. m_bHomeTeam = true;
  129. m_pProCounter[0] = -1;
  130. m_pProCounter[1] = -1;
  131. m_nMsgCounter = 0;
  132. m_pRiver = NULL;
  133. m_pFood = NULL;
  134. ZeroMemory( m_ppTanks, sizeof(LPVOID)*DEFTANKNUM );
  135. ZeroMemory( m_ppBullets, sizeof(LPVOID)*DEFTANKNUM );
  136. ZeroMemory( m_ppBases, sizeof(LPVOID)*2);
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Name: 
  140. // Desc: 
  141. //-----------------------------------------------------------------------------
  142. ConsoleNet::~ConsoleNet() {
  143. DELETE_ARRAY( m_pRiver );
  144. DELETE_PTR( m_pFood );
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Name: 
  148. // Desc: 
  149. //-----------------------------------------------------------------------------
  150. void ConsoleNet::ErrorTrigger( unsigned int error ) {
  151. Console::ErrorTrigger( error );
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Name: 
  155. // Desc: 
  156. //-----------------------------------------------------------------------------
  157. bool ConsoleNet::LoadMap( const char *mapname ) {
  158. return MapInfo.LoadMap( mapname );
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Name: 
  162. // Desc: 
  163. //-----------------------------------------------------------------------------
  164. bool ConsoleNet::RenderMap(  bool hometeam ) {
  165. if ( !hometeam )
  166. MapInfo.CenterRotate180();
  167. // Set class properties
  168. m_bHomeTeam = hometeam;
  169. m_dwStatus = CONSTAT_WAITBEGIN;
  170. m_nNumTanks = MapInfo.GetObjectNum( OBJTYPE_TANK );
  171. m_nNumRiver = MapInfo.BlockCounter( LAND_RIVER, NULL );
  172. m_pRiver = new CObjBlock[m_nNumRiver];
  173. MapInfo.BlockCounter( LAND_RIVER, m_pRiver );
  174. // Create bases
  175. m_ppBases[0] = new CObjBase();
  176. m_ppBases[1] = new CObjBase();
  177. m_ppBases[0]->CreateBase( MapInfo.m_ptBase[0].x, MapInfo.m_ptBase[0].y, true);
  178. m_ppBases[1]->CreateBase( MapInfo.m_ptBase[1].x, MapInfo.m_ptBase[1].y, false);
  179. // Blt blocks
  180. int x, y, xl, yl, level;
  181. RECT *prc = new RECT, *prcTrans = new RECT;
  182. SetRect( prcTrans, 0, 32, 32, 64 );
  183. for ( y = 0, yl = 0; y < MapInfo.m_cyBlocks-1; y++, yl += g_FrameSmall )
  184. for ( x = 0, xl = 0; x < MapInfo.m_cxBlocks-1; x++, xl += g_FrameSmall ) {
  185. MapInfo.BlockLocator( x, y, prc, level );
  186. if ( level == LAYER_GROUND ) {
  187. if ( FAILED( pddsSolid->BltFast( xl, yl, pddsRes, prc, 0 ) ) )
  188. return false;
  189. if ( FAILED( pddsGrass->BltFast( xl, yl, pddsRes, prcTrans, 0 ) ) )
  190. return false;
  191. }else if ( level == LAYER_TREE ) {
  192. if ( FAILED( pddsSolid->BltFast( xl, yl, pddsRes, prcTrans, 0 ) ) )
  193. return false;
  194. if ( FAILED( pddsGrass->BltFast( xl, yl, pddsRes, prc, 0 ) ) )
  195. return false;
  196. }
  197. }
  198. return true;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Name: 
  202. // Desc: 
  203. //-----------------------------------------------------------------------------
  204. bool ConsoleNet::InitDisplay( HWND hwnd ) {
  205. if ( !hwnd )
  206. return false;
  207. // Create display
  208. if ( FAILED( Display.CreateWindowedDisplay( hwnd, g_FrameBig, g_FrameBig ) ) )
  209. return false;
  210. // Create surfaces
  211. pResource = new CSurface();
  212. if ( FAILED( Display.CreateSurfaceFromBitmap( &pResource, 
  213. "Res/res3.bmp", 512, 640 ) ) )
  214. return false;
  215. pRes2 = new CSurface();
  216. if ( FAILED( Display.CreateSurfaceFromBitmap( &pRes2, 
  217. "Res/res2.bmp", 640, 480 ) ) )
  218. return false;
  219. pMapSolid = new CSurface();
  220. if ( FAILED( Display.CreateSurface( &pMapSolid, g_FrameBig, g_FrameBig ) ) )
  221. return false;
  222. pMapGrass = new CSurface();
  223. if ( FAILED( Display.CreateSurface( &pMapGrass, g_FrameBig, g_FrameBig ) ) )
  224. return false;
  225. pText = new CSurface();
  226. if ( FAILED( Display.CreateSurface( &pText, 80, 30 ) ) )
  227. return false;
  228. // Set color key
  229. pMapSolid->SetColorKey( 0 );
  230. pMapGrass->SetColorKey( 0 );
  231. pResource->SetColorKey( 0 );
  232. pRes2->SetColorKey( 0 );
  233. // Render the scene according to the map data
  234. pddsSolid = pMapSolid->GetDDrawSurface();
  235. pddsGrass = pMapGrass->GetDDrawSurface();
  236. pddsRes   = pResource->GetDDrawSurface();
  237. pddsRes2  = pRes2->GetDDrawSurface();
  238. return true;
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Name: 
  242. // Desc: 
  243. //-----------------------------------------------------------------------------
  244. bool ConsoleNet::InitSound( HWND hwnd ) {
  245. if ( FAILED(SoundManager.Initialize( hwnd, DSSCL_PRIORITY, 1, 22050, 8 )) )
  246. return false;
  247. if ( FAILED(SoundManager.Create( &pFire, szFireWave )) )
  248. return false;
  249. if ( FAILED(SoundManager.Create( &pBoom, szBoomWave )) )
  250. return false;
  251. return true;
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Name: 
  255. // Desc: 
  256. //-----------------------------------------------------------------------------
  257. bool ConsoleNet::InitObjects() {
  258. int i;
  259. for ( i=0; i<DEFTANKNUM/2; i++ ) { // !TODO: because of the map setting position
  260. m_ppTanks[i] = new CObjTank();
  261. m_ppTanks[i]->CreateTank(MapInfo.m_pTankInfo[DEFTANKNUM-1-i].posLT.x,
  262. MapInfo.m_pTankInfo[DEFTANKNUM-1-i].posLT.y,true);
  263. m_ppBullets[i] = new CObjBullet();
  264. m_ppBullets[i]->CreateBullet( NULL );
  265. m_ppTanks[i]->m_uiDirection = DIR_UP;
  266. }
  267. for ( ; i<DEFTANKNUM; i++ ) {
  268. m_ppTanks[i] = new CObjTank();
  269. m_ppTanks[i]->CreateTank(MapInfo.m_pTankInfo[DEFTANKNUM-1-i].posLT.x,
  270. MapInfo.m_pTankInfo[DEFTANKNUM-1-i].posLT.y,false);
  271. m_ppBullets[i] = new CObjBullet();
  272. m_ppBullets[i]->CreateBullet( NULL );
  273. m_ppTanks[i]->m_uiDirection = DIR_DOWN;
  274. }
  275. if ( !m_bHomeTeam ) {
  276. for ( i=0; i<DEFTANKNUM; i++ ) {
  277. MapInfo.ConvertCoord( m_ppTanks[i] );
  278. m_ppTanks[i]->m_uiDirection = 5 - m_ppTanks[i]->m_uiDirection;
  279. }
  280. }
  281. // Initialize AI command generator
  282. RECT scope;
  283. SetRect( &scope, DEFTRACKSCOPE, DEFTRACKSCOPE, DEFTRACKSCOPE, DEFTRACKSCOPE );
  284. CObjTank **pptk = m_ppTanks+m_nLocal+1;
  285. for ( i=0; i<DEFAINUM; i++ ) {
  286. m_ppAiGen[i].CreateGenerator( *(pptk+i), scope );
  287. m_ppAiGen[i].SetAim( m_ppBases[m_bHomeTeam], -1 );
  288. m_ppAiGen[i].SetAvoid( m_ppBases[1-m_bHomeTeam]->GetSurroundRect() );
  289. }
  290. // food
  291. m_pFood = new CObjFood();
  292. return true;
  293. }
  294. //-----------------------------------------------------------------------------
  295. // Name: 
  296. // Desc: 
  297. //-----------------------------------------------------------------------------
  298. bool ConsoleNet::CreateConsole( HWND hwnd, const char *mapname, bool hometeam ) {
  299. if ( !LoadMap( mapname ) || !InitDisplay( hwnd ) ||
  300. !InitSound( hwnd ) || !RenderMap( hometeam ) )
  301. return false;
  302. #ifdef _TK_DEBUG
  303. lstrcpy(szDebugFile, "debug0.txt");
  304. hfile = CreateFile( szDebugFile, GENERIC_WRITE,
  305. FILE_SHARE_READ, NULL, CREATE_ALWAYS,
  306. FILE_ATTRIBUTE_NORMAL, NULL );
  307. if ( hfile == INVALID_HANDLE_VALUE ) {
  308. lstrcpy(szDebugFile, "debug1.txt");
  309. hfile = CreateFile( szDebugFile, GENERIC_WRITE,
  310. FILE_SHARE_READ, NULL, CREATE_ALWAYS,
  311. FILE_ATTRIBUTE_NORMAL, NULL );
  312. if ( hfile == INVALID_HANDLE_VALUE ) {
  313. CloseHandle(hfile);
  314. hfile = NULL;
  315. }
  316. }
  317. #endif
  318. return true;
  319. }
  320. //-----------------------------------------------------------------------------
  321. // Name: 
  322. // Desc: 
  323. //-----------------------------------------------------------------------------
  324. void ConsoleNet::CreateAICmd() {
  325. TANKCMD *pcmd = m_pCmd+m_nLocal+1;
  326. for ( int i=0; i<DEFAINUM; i++ ) {
  327. if ( m_ppTanks[m_nLocal+1+i]->GetStat() & OBJSTAT_LIVE )
  328. *(pcmd+i) = m_ppAiGen[i].Generator( NULL, 0 );
  329. }
  330. }
  331. //-----------------------------------------------------------------------------
  332. // Name: 
  333. // Desc: 
  334. //-----------------------------------------------------------------------------
  335. void ConsoleNet::GameMain() {
  336. static int counter = 0;
  337. static DWORD start_time = 0, last_get;
  338. static DWORD frame_start = 0;
  339. DWORD end_time;
  340. if ( m_dwStatus == CONSTAT_ENDGAME )
  341. return ;
  342. // Peek and process messages
  343. if ( !NetList.IsEmpty() ) 
  344. MsgProcessor( &NetList );
  345. // Waiting
  346. if ( m_dwStatus < CONSTAT_WAITMORE ) {
  347. // TODO: here we should set a time-out event,
  348. // and display like this, " Now, connecting... "
  349. return ;
  350. } else if ( m_dwStatus == CONSTAT_WAITBEGIN ) {
  351. last_get = timeGetTime();
  352. return ;
  353. } else if ( m_dwStatus == CONSTAT_WAITPLAYER ) {
  354. if ( bFresh ) {
  355. cmdbuf = uiCurrentCmd;
  356. firebuf = bFired;
  357. bFresh = false;
  358. }
  359. if ( bRecvCmd ) {
  360. last_get = timeGetTime();
  361. m_dwStatus = CONSTAT_RUNNING;
  362. } else {
  363. end_time = timeGetTime();
  364. if( end_time - last_get > WAITTIMEOUT ) {
  365. // TODO: Record the lag
  366. // m_dwStatus = CONSTAT_WAITERROR;
  367. DebugOutput( 1, "Wait error!" );
  368. m_dwStatus = CONSTAT_WAITERROR;
  369. }
  370. return ;
  371. }
  372. }
  373. // FPS control, 1000/x in theory
  374. // x = 20, 30 fps
  375. while ( timeGetTime() - frame_start < 30 );
  376. frame_start = timeGetTime();
  377. // Running
  378. if ( m_dwStatus == CONSTAT_RUNNING ) {
  379. // Excute commands
  380. BulletsProc(); // 1- Excute bullets earlier than tanks
  381. #ifdef _DEBUG_CMDOUTPUT
  382. char temp[4];
  383. DebugOutput( 1, "*****Last Get:*****" );
  384. for ( int i=0; i<DEFTANKNUM; i++ ) {
  385. itoa(m_pCmd[i].cmd,temp,10);
  386. DebugOutput( 2, temp, "t" );
  387. }
  388. DebugOutput( 1, "rn" );
  389. #endif
  390. TanksProc(); // 2- Excute tanks
  391. FoodProc(); // 3- Excute food
  392. // Exchange command messages
  393. m_pCmd[m_nLocal].cmd = cmdbuf;
  394. m_pCmd[m_nLocal].fire = firebuf;
  395. bFresh = true;
  396. CreateAICmd();
  397. #ifdef _DEBUG_CMDOUTPUT
  398. DebugOutput( 1, "*****Generate:*****" );
  399. for ( int k=m_nLocal; k<m_nLocal+DEFAINUM+1; k++ ) {
  400. itoa(m_pCmd[k].cmd,temp,10);
  401. DebugOutput( 2, temp, "t" );
  402. }
  403. #endif
  404. SendCmdMsg( &m_pCmd[m_nLocal], DEFAINUM+1, m_nLocal ); // home-0, enemy-5
  405. // wait next message
  406. m_dwStatus = CONSTAT_WAITPLAYER;
  407. m_nMsgCounter = 0;
  408. ZeroMemory( m_pMsgFlag,sizeof(bool)*m_nPlayers);
  409. bRecvCmd = false;
  410. }
  411. // The app-window is not activated, skip refresh screen
  412. if ( !g_bActive ) 
  413. return ;
  414. // Animations, frame roller
  415. RollBlockObjects( m_pRiver, m_nNumRiver );
  416. // Redraw land layer
  417. Display.Clear(0); // level ground
  418. Display.Blt(0,0,pMapSolid->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);
  419. // objects layer
  420. BlitBullets( m_ppBullets, DEFTANKNUM );
  421. BlitTanks( m_ppTanks, DEFTANKNUM );
  422. BlitBases( m_ppBases, 2 );
  423. // Redraw grass layer, level trees
  424. Display.Blt(0,0,pMapGrass->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);
  425. BlitFood();
  426. // FPS display
  427. counter++;
  428. end_time = timeGetTime();
  429. if ( end_time - start_time >= 1000 ) {
  430. start_time = end_time;
  431. itoa( counter, fps+5, 10 );
  432. counter = 0;
  433. }
  434. pText->DrawText( NULL, "                ", 5, 5, RGB(0,0,0), RGB(0,0,0) );
  435. pText->DrawText( NULL, fps, 5, 5, RGB(0,0,0), RGB(255,0,0) );
  436. Display.Blt(0,0,pText->GetDDrawSurface(), NULL, 0);
  437. // Flip
  438. Display.Present();
  439. }
  440. //-----------------------------------------------------------------------------
  441. // Name: 
  442. // Desc: 
  443. //-----------------------------------------------------------------------------
  444. int ConsoleNet::BulletsProc() 
  445. {
  446. RECT rt_mobile;
  447. POINT step, pt_block;
  448. DWORD overland;
  449. int hit_blt, hit_tk, hit_block, hit_base;
  450. POINT ptChanged[4];
  451. for ( int i=0; i<DEFTANKNUM; i++ )
  452. {
  453. // Create bullet
  454. if ( m_pCmd[i].fire && !(m_ppTanks[i]->HaveBullet()) ) {
  455. m_ppBullets[i]->CreateBullet( m_ppTanks[i] );
  456. pFire->Play();
  457. }
  458. else if ( m_ppBullets[i]->GetStat() == OBJSTAT_CADAVER )
  459. continue;
  460. // Collision test
  461. if ( m_ppBullets[i]->GetStat() & OBJSTAT_LIVE )
  462. {
  463. // Set coltest parameters
  464. step = m_ppBullets[i]->GetDirectionUnit();
  465. rt_mobile = m_ppBullets[i]->GetNextRect();
  466. // Collistion test of bases
  467. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases, 2, -1, 
  468. m_ppBullets[i]->m_uiTeamType, true, hit_base );
  469. // Collistion test of bullets
  470. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
  471. m_ppBullets[i]->m_uiTeamType, true, hit_blt );
  472. // Collistion test of bullets and tanks
  473. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
  474. m_ppBullets[i]->m_uiTeamType, true, hit_tk );
  475. pt_block.x = rt_mobile.left;
  476. pt_block.y = rt_mobile.top;
  477. // Collistion test of tanks and blocks
  478. overland = 0;
  479. hit_block = 4; // don't need to remove blocks
  480. MapInfo.ColRToB( pt_block, WIDTH_16, step, COL_IRON, 
  481. overland, COL_BRICK, ptChanged, hit_block );
  482. // Reset and render map
  483. int level;
  484. RECT *prc = new RECT;
  485. for( int j=0; j<hit_block; j++ ) {
  486. MapInfo.BlockLocator( ptChanged[j].x, ptChanged[j].y, prc, level );
  487. // if ( level == LAYER_GROUND )
  488. pddsSolid->BltFast( ptChanged[j].x<<5, ptChanged[j].y<<5, pddsRes, prc, 0 );
  489. // else if ( level == LAYER_TREE ) 
  490. // pddsGrass->BltFast( ptChanged[i].x<<5, ptChanged[i].y<<5, pddsRes, prc, 0 );
  491. }
  492. // Boom and destroy
  493. m_ppBullets[i]->SetPos( pt_block.x, pt_block.y );
  494. if ( pt_block.x != rt_mobile.left || pt_block.y != rt_mobile.top ||
  495. hit_block > 0 ) {
  496. m_ppBullets[i]->NextStat();
  497. } else if ( hit_tk >= 0 ) {
  498. m_ppBullets[i]->Hit( m_ppTanks[hit_tk] );
  499. } else if ( hit_blt >= 0 ) {
  500. m_ppBullets[i]->Hit( m_ppBullets[hit_blt] );
  501. } else if ( hit_base >= 0 ) {
  502. if ( !( m_ppBases[hit_base]->m_ptyBlood.Minus( m_ppBullets[i]->GetAttack() ) ) )
  503. SendMsg( NETMSGTK_TEAMVICTORY, &hit_base, sizeof(int) );
  504. m_ppBullets[i]->NextStat();
  505. }
  506. }
  507. else 
  508. m_ppBullets[i]->NextStat();
  509. }
  510. return 0;
  511. }
  512. //-----------------------------------------------------------------------------
  513. // Name: 
  514. // Desc: 
  515. //-----------------------------------------------------------------------------
  516. int ConsoleNet::TanksProc()
  517. {
  518. RECT rt_mobile;
  519. POINT step, pt_block;
  520. int hit_blt, hit_tk, hit_block, hit_base;
  521. DWORD overland, blockland;
  522. bool movetest;
  523. for ( int i=0; i<DEFTANKNUM; i++ ) 
  524. {
  525. if ( m_ppTanks[i]->GetStat() & OBJSTAT_CADAVER )
  526. continue;
  527. if ( m_ppTanks[i]->GetStat() & OBJSTAT_DIE ) {
  528. m_ppTanks[i]->NextStat();
  529. pBoom->Play();
  530. continue;
  531. }
  532. // Convert direction
  533. if ( m_ppTanks[i]->IsHomeTeam() ^ m_bHomeTeam ) 
  534. m_pCmd[i].cmd = 5 - m_pCmd[i].cmd;
  535. // Direction command to excute, 
  536. if ( m_ppTanks[i]->m_uiIceDir != DIR_NONE )  // still sliding
  537. {
  538. movetest = true;
  539. //  if on ice, modify slide speed each time
  540. if ( m_pCmd[i].cmd > DIR_NONE && m_pCmd[i].cmd < DIR_MAX ) {
  541. // After all, reset main direction
  542. m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;
  543. // Affect the speed by direction
  544. if ( m_ppTanks[i]->m_uiIceDir == m_pCmd[i].cmd ) { // speed up
  545. if ( m_ppTanks[i]->m_nIceStep < MAXSPEEDONICE-2 )
  546. m_ppTanks[i]->m_nIceStep += 2;
  547. else
  548. m_ppTanks[i]->m_nIceStep = MAXSPEEDONICE;
  549. } else {
  550. if ( m_ppTanks[i]->m_uiIceDir == 5 - m_pCmd[i].cmd )  // opposite
  551. m_ppTanks[i]->m_nIceStep -= 4;
  552. else // others, no effect
  553. m_ppTanks[i]->m_nIceStep -= 2;
  554. if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
  555. movetest = false;
  556. m_ppTanks[i]->m_uiIceDir = DIR_NONE;
  557. }
  558. }
  559. } else { // natural friction
  560. m_ppTanks[i]->m_nIceStep -= 2;
  561. if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
  562. movetest = false;
  563. m_ppTanks[i]->m_uiIceDir = DIR_NONE;
  564. }
  565. }
  566. // Set coltest parameters
  567. step = m_ppTanks[i]->GetDirUnitOnIce();
  568. rt_mobile = m_ppTanks[i]->GetNextRectOnIce();
  569. }
  570. // Test command to see if it's none
  571. else if ( m_pCmd[i].cmd == DIR_NONE || m_pCmd[i].cmd == DIR_MAX )
  572. continue;
  573. else if ( m_ppTanks[i]->m_uiDirection == m_pCmd[i].cmd ) // move forward
  574. {
  575. // Set moving animation flag
  576. m_ppTanks[i]->m_bMoving = true;
  577. movetest = true;
  578. // Set coltest parameters
  579. step = m_ppTanks[i]->GetDirectionUnit();
  580. rt_mobile = m_ppTanks[i]->GetNextRect();
  581. else  // just turn around
  582. {
  583. movetest = false;
  584. bool dirtest = true;
  585. int residue;
  586. // Count a integer step
  587. rt_mobile = m_ppTanks[i]->GetRect();
  588. step = m_ppTanks[i]->GetDirectionUnit();
  589. if ( step.y != 0 ) {
  590. residue = m_ppTanks[i]->GetTop() % DEFTURNSTEP;
  591. if ( residue == 0 ) 
  592. dirtest = false;
  593. else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) { // down
  594. residue = DEFTURNSTEP - residue;
  595. rt_mobile.top += residue;
  596. rt_mobile.bottom += residue;
  597. } else { // up
  598. rt_mobile.top -= residue;
  599. rt_mobile.bottom -= residue;
  600. }
  601. } else if ( step.x != 0 ) {
  602. residue = m_ppTanks[i]->GetLeft() % DEFTURNSTEP;
  603. if ( residue == 0 ) 
  604. dirtest = false;
  605. else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) { // right
  606. residue = DEFTURNSTEP - residue;
  607. rt_mobile.left += residue;
  608. rt_mobile.right += residue;
  609. } else { // left
  610. rt_mobile.left -= residue;
  611. rt_mobile.right -= residue;
  612. }
  613. }
  614. // Test if it can move
  615. if ( dirtest ) {
  616. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
  617. m_ppTanks[i]->m_uiTeamType, false, hit_tk );
  618. if ( hit_tk < 0 )
  619. m_ppTanks[i]->SetPos( rt_mobile.left, rt_mobile.top );
  620. }
  621. // change direction
  622. m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;
  623. }
  624. // Move collision test
  625. if ( movetest ) {
  626. // Collistion test of bases
  627. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases,
  628. 2, -1, 0, false, hit_base );
  629. // Collistion test of bullets
  630. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
  631. m_ppTanks[i]->m_uiTeamType, true, hit_blt );
  632. // Collistion test of tanks
  633. MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
  634. m_ppTanks[i]->m_uiTeamType, false, hit_tk );
  635. // Collistion test of tanks and blocks
  636. pt_block.x = rt_mobile.left;
  637. pt_block.y = rt_mobile.top;
  638. overland = COL_ICE;
  639. blockland = COL_BRICK|COL_IRON;
  640. if ( !(m_ppTanks[i]->m_dwEquip & EQUIP_SHIP) )
  641. blockland |= COL_RIVER;
  642. hit_block = 0; // don't need to remove blocks
  643. MapInfo.ColRToB( pt_block, WIDTH_32, step, blockland, 
  644. overland, 0, NULL, hit_block );
  645. // Set ice flag
  646. if ( overland & COL_ICE ) {
  647. m_ppTanks[i]->m_bOnIce = true;
  648. if ( m_ppTanks[i]->m_uiIceDir == DIR_NONE ) {
  649. m_ppTanks[i]->m_nIceStep = m_ppTanks[i]->GetStep();
  650. m_ppTanks[i]->m_uiIceDir = m_ppTanks[i]->m_uiDirection;
  651. }
  652. }
  653. else {
  654. m_ppTanks[i]->m_bOnIce = false;
  655. m_ppTanks[i]->m_uiIceDir = DIR_NONE;
  656. }
  657. // Choose a fewest step
  658. if ( pt_block.x * step.x < rt_mobile.left * step.x ||
  659. pt_block.y * step.y < rt_mobile.top * step.y ) 
  660. m_ppTanks[i]->SetPos( pt_block.x, pt_block.y );
  661. else {
  662. m_ppTanks[i]->SetPos( rt_mobile.left, rt_mobile.top );
  663. if ( hit_blt >= 0 ) 
  664. m_ppBullets[hit_blt]->Hit( m_ppTanks[i] );
  665. }
  666. }
  667. } // for, tanks, num 0-9
  668. return 0;
  669. }
  670. //-----------------------------------------------------------------------------
  671. // Name: 
  672. // Desc: 
  673. //-----------------------------------------------------------------------------
  674. void ConsoleNet::FoodProc() {
  675. // Collision test
  676. if ( m_pFood->IsExsit() ) {
  677. RECT rt_eat = m_pFood->GetPermitRect();
  678. POINT step = {0,0};
  679. int hit_tk;
  680. // Collistion test of tanks
  681. MapInfo.ColRToMobile( rt_eat, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, -1,
  682. 0, false, hit_tk );
  683. if ( hit_tk >= 0 ) { // reset its property
  684. if ( m_pFood->GetFoodType() == FOOD_KEEPBASE ) {
  685. POINT pts[9];
  686. int changed = 9;
  687. int i = 1-m_ppTanks[hit_tk]->IsHomeTeam();
  688. m_pProCounter[i] = DEFPROTECTTIME;
  689. MapInfo.Protect( m_ppBases[i]->GetRect(), true, pts, changed );
  690. int level;
  691. RECT *prc = new RECT;
  692. for( int j=0; j<changed; j++ ) {
  693. MapInfo.BlockLocator( pts[j].x, pts[j].y, prc, level );
  694. pddsSolid->BltFast( pts[j].x<<5, pts[j].y<<5, pddsRes, prc, 0 );
  695. }
  696. } else {
  697. m_pFood->Benefit( m_ppTanks[hit_tk] );
  698. }
  699. m_pFood->SetExsit(false);
  700. }
  701. }
  702. if ( m_pProCounter[0] == 0 ) {
  703. POINT pts[9];
  704. int changed = 9;
  705. MapInfo.Protect( m_ppBases[0]->GetRect(), false, pts, changed );
  706. int level;
  707. RECT *prc = new RECT;
  708. for( int j=0; j<changed; j++ ) {
  709. MapInfo.BlockLocator( pts[j].x, pts[j].y, prc, level );
  710. pddsSolid->BltFast( pts[j].x<<5, pts[j].y<<5, pddsRes, prc, 0 );
  711. }
  712. }
  713. if ( m_pProCounter[0] >= 0 )
  714. m_pProCounter[0]--;
  715. if ( m_pProCounter[1] == 0 ) {
  716. POINT pts[9];
  717. int changed = 9;
  718. MapInfo.Protect( m_ppBases[1]->GetRect(), false, pts, changed );
  719. int level;
  720. RECT *prc = new RECT;
  721. for( int j=0; j<changed; j++ ) {
  722. MapInfo.BlockLocator( pts[j].x, pts[j].y, prc, level );
  723. pddsSolid->BltFast( pts[j].x<<5, pts[j].y<<5, pddsRes, prc, 0 );
  724. }
  725. }
  726. if ( m_pProCounter[1] >= 0 )
  727. m_pProCounter[1]--;
  728. }
  729. //-----------------------------------------------------------------------------
  730. // Name: 
  731. // Desc: 
  732. //-----------------------------------------------------------------------------
  733. void ConsoleNet::MsgProcessor( CMsgList *ml ) {
  734. if ( !ml ) 
  735. return ;
  736. CMsgElem *pelem,*peek;
  737. int lastmsg = 0;
  738. int *ibuf;
  739. ml->Lock();
  740. while ( !ml->IsEmpty() ) {
  741. peek = ml->Peek();
  742. if ( !peek || peek->GetMsg() == lastmsg ) {
  743. ml->UnLock();
  744. return;
  745. }
  746. pelem = ml->Pop();
  747. lastmsg = pelem->GetMsg();
  748. // Messages from server
  749. if ( pelem->GetMsgType() == MSG_NET ) {
  750. switch ( lastmsg ) 
  751. {
  752. case NETMSGTK_ANSWERSEATINFO:
  753. ibuf = (int *)(pelem->GetParam());
  754. m_nPlayers = DEFTANKNUM/(DEFAINUM+1);
  755. m_nComPerTeam = DEFAINUM;
  756. m_nLocal = ibuf[0]*(DEFAINUM+1);
  757. if ( m_nLocal >= DEFTANKNUM/2 )
  758. m_bHomeTeam = false;
  759. else
  760. m_bHomeTeam = true;
  761. m_dwStatus = CONSTAT_WAITMORE;
  762. m_pMsgFlag = new bool[m_nPlayers];
  763. ZeroMemory( m_pMsgFlag,sizeof(bool)*m_nPlayers);
  764. if ( !CreateConsole( hChildWnd, "Map/Map_02.idx", m_bHomeTeam ) ) {
  765. MessageBox( NULL, "Create Console Error!", "Sorry", MB_OK );
  766. m_dwStatus = CONSTAT_ENDGAME;
  767. DestroyWindow( hMainWnd );
  768. }
  769. break;
  770. case NETMSGTK_WAITMOREPLAYER:
  771. break;
  772. case NETMSGTK_MOREPLAYER:
  773. break;
  774. case NETMSGTK_GAMEREADY:
  775. InitObjects();
  776. SendMsg( NETMSGTK_PLAYERREADY, NULL, 0 );
  777. m_dwStatus = CONSTAT_WAITBEGIN;
  778. break;
  779. case NETMSGTK_GAMESTART:
  780. SendCmdMsg( &m_pCmd[m_nLocal], 0, m_nLocal );
  781. m_dwStatus = CONSTAT_WAITPLAYER;
  782. break;
  783. case NETMSGTK_CMDFOODDELETE:
  784. m_pFood->SetExsit(false);
  785. break;
  786. case NETMSGTK_CMDFOODCREATE:
  787. ibuf = (int *)(pelem->GetParam());
  788. if ( !m_bHomeTeam ) {
  789. ibuf[1] = g_FrameLeft - ibuf[1];
  790. ibuf[2] = g_FrameLeft - ibuf[2];
  791. }
  792. m_pFood->CreateFood(ibuf[0], ibuf[1], ibuf[2] );
  793. break;
  794. case NETMSGTK_CMDINFO:
  795. if ( m_dwStatus != CONSTAT_WAITPLAYER )
  796. ml->Push(pelem);
  797. else {
  798. ibuf = (int *)(pelem->GetParam());
  799. if ( m_pMsgFlag[ibuf[0]/(m_nComPerTeam+1)] ) {
  800. ml->Push(pelem);
  801. break;
  802. else {
  803. m_pMsgFlag[ibuf[0]/(m_nComPerTeam+1)] = true;
  804. memcpy(m_pCmd+ibuf[0], ibuf+2, sizeof(TANKCMD)*ibuf[1]);
  805. if ( ++m_nMsgCounter == (int)(m_nPlayers-1))
  806. bRecvCmd = true;
  807. #ifdef _DEBUG_CMDOUTPUT
  808. char temp[4];
  809. DebugOutput( 1, "*****Message Get:*****" );
  810. for ( int i=ibuf[0]; i<ibuf[0]+DEFAINUM+1; i++ ) {
  811. itoa(m_pCmd[i].cmd,temp,10);
  812. DebugOutput( 2, temp, "t" );
  813. }
  814. #endif
  815. }
  816. }
  817. break;
  818. case NETMSGTK_TEAMVICTORY:
  819. ibuf = (int *)(pelem->GetParam());
  820. if ( ibuf[0] ) 
  821. MessageBox( NULL, "Home Team Win!", "Congratulations", MB_OK );
  822. else
  823. MessageBox( NULL, "Enemy Team Win!", "Congratulations", MB_OK );
  824. m_dwStatus = CONSTAT_ENDGAME;
  825. DestroyWindow( hMainWnd );
  826. break;
  827. case MSGNET_RECEIVEERROR:
  828. ERRORMSG( pelem->GetParam() );
  829. break;
  830. }
  831. }
  832. // delete pelem;
  833. ml->UnLock();
  834. }
  835. //-----------------------------------------------------------------------------
  836. // Name: 
  837. // Desc: 
  838. //-----------------------------------------------------------------------------
  839. void ConsoleNet::BlitFood() {
  840. if ( m_pFood->IsExsit() ) {
  841. RECT *prc = new RECT();
  842. prc->left = 32 + m_pFood->GetFoodType() * 32;
  843. prc->top  = 256;
  844. prc->right  = prc->left + 32;
  845. prc->bottom = prc->top + 32;
  846. Display.Blt( m_pFood->GetLeft(), m_pFood->GetTop(), pddsRes, 
  847. prc, DDBLTFAST_SRCCOLORKEY);
  848. }
  849. }
  850. //-----------------------------------------------------------------------------
  851. // Name: 
  852. // Desc: 
  853. //-----------------------------------------------------------------------------
  854. void ConsoleNet::BlitTanks( CObjTank **pptks, int num ) {
  855. if ( pptks ) {
  856. RECT *prc = new RECT();
  857. int *pres;
  858. int len;
  859. DWORD time = timeGetTime();
  860. for ( int i=0; i<num; i++ ) {
  861. if ( pptks[i]->GetStat() & OBJSTAT_LIVE ) {
  862. pres = &ResArray[pptks[i]->GetFrameType()][0];
  863. prc->left = (*(pres+RESPOS_LEFT))+(pptks[i]->m_uiDirection-1) * 
  864. (*(pres+RESSIZE_WIDTH));
  865. if ( pptks[i]->IsHomeTeam() )
  866. prc->left += 256;
  867. else
  868. prc->left += 384;
  869. if ( pptks[i]->m_bMoving ) {
  870. pptks[i]->NextFrame(time);
  871. pptks[i]->m_bMoving = false;
  872. }
  873. prc->top  = *(pres+RESPOS_TOP) + pptks[i]->GetFrameCurrent()*32;
  874. prc->right  = prc->left + (*(pres+RESSIZE_WIDTH));
  875. prc->bottom = prc->top + (*(pres+RESSIZE_HEIGHT));
  876. Display.Blt( pptks[i]->GetLeft(), pptks[i]->GetTop(), pddsRes, 
  877. prc, DDBLTFAST_SRCCOLORKEY);
  878. // draw blood
  879. prc->left = 256;
  880. prc->top  = 552;
  881. prc->right  = prc->left + 31;
  882. prc->bottom = prc->top + 5;
  883. Display.Blt( pptks[i]->GetLeft(), pptks[i]->GetTop(), pddsRes, 
  884. prc, DDBLTFAST_NOCOLORKEY);
  885. len = pptks[i]->GetBloodPercent(29);
  886. prc->left = 256;
  887. prc->top  = 560;
  888. prc->right  = prc->left + len;
  889. prc->bottom = prc->top + 3;
  890. Display.Blt( pptks[i]->GetLeft()+1, pptks[i]->GetTop()+1, pddsRes, 
  891. prc, DDBLTFAST_NOCOLORKEY );
  892. else if ( pptks[i]->GetStat() & OBJSTAT_DIE ) {
  893. prc->left = 0 + 32 * pptks[i]->GetFrameCurrent();
  894. prc->top  = 544;
  895. prc->right  = prc->left + 32;
  896. prc->bottom = prc->top + 32;
  897. Display.Blt( pptks[i]->GetLeft(), pptks[i]->GetTop(), pddsRes, 
  898. prc, DDBLTFAST_SRCCOLORKEY);
  899. pptks[i]->NextFrame( time );
  900. }
  901. }
  902. }
  903. }
  904. //-----------------------------------------------------------------------------
  905. // Name: 
  906. // Desc: 
  907. //-----------------------------------------------------------------------------
  908. void ConsoleNet::BlitBullets( CObjBullet **ppbts, int num ) {
  909. if ( ppbts ) {
  910. RECT *prc = new RECT();
  911. DWORD time = timeGetTime();
  912. // int *pres;
  913. for ( int i=0; i<num; i++ ) {
  914. if ( ppbts[i]->GetStat() & OBJSTAT_LIVE ) {
  915. prc->left = 96 + 32 * ppbts[i]->m_uiDirection;
  916. prc->top  = 544;
  917. prc->right  = prc->left + 16;
  918. prc->bottom = prc->top + 16;
  919. Display.Blt( ppbts[i]->GetLeft(), ppbts[i]->GetTop(), pddsRes, 
  920. prc, DDBLTFAST_SRCCOLORKEY);
  921. }else if ( ppbts[i]->GetStat() & OBJSTAT_DIE ) {
  922. prc->left = 0 + 32 * ppbts[i]->GetFrameCurrent();
  923. prc->top  = 544;
  924. prc->right  = prc->left+32;
  925. prc->bottom = prc->top+32;
  926. Display.Blt( ppbts[i]->GetLeft()-8*(1+ppbts[i]->GetDirectionUnit().x), 
  927. ppbts[i]->GetTop()-8*(1+ppbts[i]->GetDirectionUnit().y), pddsRes, 
  928. prc, DDBLTFAST_SRCCOLORKEY);
  929. ppbts[i]->NextFrame(time);
  930. }
  931. }
  932. }
  933. }
  934. //-----------------------------------------------------------------------------
  935. // Name: 
  936. // Desc: 
  937. //-----------------------------------------------------------------------------
  938. bool ConsoleNet::BlitBases(  CObjBase **ppbs, int num ) {
  939. if ( !ppbs )
  940. return false;
  941. RECT prc;
  942. int level;
  943. for ( int i=0; i<num; i++ ) {
  944. MapInfo.ObjectLocator( ppbs[i], &prc, level );
  945. Display.Blt( ppbs[i]->GetLeft(), ppbs[i]->GetTop(), 
  946. pResource->GetDDrawSurface(), &prc, DDBLTFAST_SRCCOLORKEY);
  947. // draw blood
  948. prc.left = 256;
  949. prc.top  = 552;
  950. prc.right  = prc.left + 31;
  951. prc.bottom = prc.top + 5;
  952. Display.Blt( ppbs[i]->GetLeft(), ppbs[i]->GetTop(), pddsRes, 
  953. &prc, DDBLTFAST_NOCOLORKEY);
  954. prc.left = 256;
  955. prc.top  = 560;
  956. prc.right  = prc.left + ppbs[i]->m_ptyBlood.GetPercent(30);
  957. prc.bottom = prc.top + 3;
  958. Display.Blt( ppbs[i]->GetLeft()+1, ppbs[i]->GetTop()+1, pddsRes, 
  959. &prc, DDBLTFAST_NOCOLORKEY );
  960. }
  961. return true;
  962. }
  963. //-----------------------------------------------------------------------------
  964. // Name: 
  965. // Desc: 
  966. //-----------------------------------------------------------------------------
  967. bool ConsoleNet::RollBlockObjects( CObjBlock *poblk, int num ) {
  968. if ( !poblk || num < 0 )
  969. return false;
  970. RECT *prc = new RECT;
  971. int level;
  972. DWORD time = timeGetTime();
  973. for ( int i=0; i<num ; i++ ) {
  974. poblk[i].NextFrame( time );
  975. MapInfo.ObjBlockLocator( poblk+i, prc, level );
  976. if ( FAILED( pddsSolid->BltFast( poblk[i].GetLeft(), poblk[i].GetTop(), 
  977. pddsRes, prc, 0 ) ) )
  978. return false;
  979. }
  980. return true;
  981. }
  982. //-----------------------------------------------------------------------------
  983. // Name: 
  984. // Desc: 
  985. //-----------------------------------------------------------------------------