DRONES.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:12k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /***********************************************************************
  2. File:   Drones.c
  3. Abstract:
  4.     This file contains the functions which are associated with moving and
  5.     drawing drones.
  6. Contents:
  7.     DeletePlayer() -- Free a record of type PlayerType
  8.     NewPlayer() -- Create & initialize a record of type PlayerType
  9.     RandRange() -- return a random number in a given range
  10.     InitDrones() -- Add/remove drone entries from the list of drones
  11.     MoveDrone() -- Timer callback to change drone positions in data struct
  12. ************************************************************************/
  13. #include <stdlib.h>
  14. #include "winmaze.h"
  15. #include "mazproto.h"
  16. #include <mmsystem.h>
  17. /*=====================================================================
  18. Function: DeletePlayer()
  19. Inputs: Pointer to record to delete
  20. Outputs: Returns pointer to next record in list
  21. Abstract:
  22.     Returns pointer to next element to facilitate maintenance of
  23.     linked lists
  24. ======================================================================*/
  25. PlayerType FAR *DeletePlayer(
  26.     PlayerType FAR *ptTrav
  27.     )
  28. {
  29.     PlayerType FAR *ptHold;
  30.     HGLOBAL hMem;
  31.     ptHold = NULL;
  32.     if (ptTrav != NULL) {
  33.         ptHold = ptTrav->next;
  34.         hMem = (HGLOBAL) GlobalHandle(SELECTOROF( ptTrav));
  35.         GlobalUnlock(hMem);
  36.         GlobalFree(hMem);
  37.         }
  38.     return(ptHold);
  39. }
  40. /*=====================================================================
  41. Function: NewPlayer()
  42. Inputs: Data elements of PlayerType element to be created
  43. Outputs: Pointer to newly created & initialize PlayerType record
  44. Abstract:
  45.     Needs no explanation
  46. ======================================================================*/
  47. PlayerType FAR *NewPlayer(
  48.     unsigned long ulID,     // Unique identifier for this player struct
  49.     DWORD dwPID,            // process id of window
  50.     LPSTR cUserName,        // Name of the player
  51.     LPSTR cComputerName,    // Name of the computer player is on
  52.     int ix,                 // Maze X- coordinate of player
  53.     int iy,                 // Maze Y- coordinate of player
  54.     BYTE Facing,            // Facing of player in maze
  55.     int iScore,             // Points player is reporting
  56.     int iPicNum,            // Picture number to use for player
  57.     int iGridNum,           // Home grid #
  58.     int iGridxPos,          // Home grid x-position (in grid coordinates
  59.     int iGridyPos,          // Home grid y-position (in grid coordinates
  60.     PlayerType FAR *next    // for linked list maintenance
  61.     )
  62. {
  63.     PlayerType FAR *ptRet;
  64.     HGLOBAL hMem;
  65.     hMem = GlobalAlloc(GHND,sizeof(PlayerType));
  66.     ptRet = (PlayerType FAR *) GlobalLock(hMem);
  67.     if (ptRet == NULL) {
  68.         MessageBox((HWND) NULL,GetStringRes(IDS_MALLOCFAILABT),"NewPlayer",
  69.                MB_APPLMODAL|MB_ICONEXCLAMATION);
  70.         PostMessage(hWndMain,WM_CLOSE,0,0);
  71.         }
  72.     else {
  73.         ptRet->ulID = ulID;
  74.         ptRet->dwPID = dwPID;
  75.         lstrcpy(ptRet->cUserName,cUserName);
  76.         lstrcpy(ptRet->cComputerName,cComputerName);
  77.         ptRet->Pos.ix = ix;
  78.         ptRet->Pos.iy = iy;
  79.         ptRet->Pos.Facing = Facing;
  80.         ptRet->Drawn = FALSE;
  81.         ptRet->iScore = iScore;
  82.         ptRet->iPicNum = iPicNum;
  83.         ptRet->iGridNum = iGridNum;
  84.         ptRet->pGridLoc.x = iGridxPos;
  85.         ptRet->pGridLoc.y = iGridyPos;
  86.         ptRet->next = next;
  87.         }
  88.     return(ptRet);
  89. }
  90. /*=====================================================================
  91. Function: RandRange()
  92. Inputs: Low, high end of range return value should be in
  93. Outputs: returns number between iLow and iHigh inclusive
  94. Abstract:
  95.     Since this is using rand() it is not so random for a new process.
  96. ======================================================================*/
  97. int RandRange(
  98.     int iLow,
  99.     int iHigh
  100.     )
  101. {
  102.     float f;
  103.     f = ((float) rand())/((float) RAND_MAX);
  104.     return((int) (iLow+f*(iHigh - iLow + 1)));
  105. }
  106. /*=====================================================================
  107. Function: InitDrones()
  108. Inputs: Globals only
  109. Outputs: none
  110. Abstract:
  111.     Performs PART of drone initialization whenever # of drones or their
  112.     speed is changed. This will add or delete drones from the drone list,
  113.     as required.
  114. ======================================================================*/
  115. void InitDrones(
  116.     )
  117. {
  118.     int i,iCurNumDrones;
  119.     BYTE b;
  120.     PlayerType FAR *ptTrav;
  121.     char buff[20];
  122.     b = NORTH;
  123.     //
  124.     // If the number of drones has changed, but drones were
  125.     // already active, we need to take a different course of
  126.     // action, ie add or delete drones from active drones,
  127.     // rather than creating completely new ones.
  128.     //
  129.     //
  130.     // Find number of drones currently active.
  131.     //
  132.     iCurNumDrones = 0;
  133.     ptTrav = &ptDrones;
  134.     while (ptTrav->next != NULL) {
  135.         iCurNumDrones++;
  136.         ptTrav = ptTrav->next;
  137.         }
  138.     //
  139.     // read in/ remove the drone bitmaps, as necessary
  140.     //
  141.     if (iNumDrones > 0) {
  142.         AddPic(PIC_DRONE);
  143.         }
  144.     else {
  145.         DelPic(PIC_DRONE);
  146.         }
  147.     //
  148.     // If more drones have been added, we need to create them
  149.     //
  150.     for(i=iCurNumDrones;i<iNumDrones;i++) {
  151.         sprintf(buff,GetStringRes(IDS_FMT_DRONE),i+1);
  152.         ptTrav->next = NewPlayer(i,i,buff,ptSelf.cComputerName,
  153.                     RandRange(5*X_CELLS_PER_SUBGRID,8*X_CELLS_PER_SUBGRID-1),
  154.                     RandRange(7*Y_CELLS_PER_SUBGRID,8*Y_CELLS_PER_SUBGRID-1),
  155.                     b,0,PIC_DRONE,0,0,0,ptTrav->next);
  156.         b = (BYTE) ((b*2 > 0x8) ? 0x1 : b*2);
  157.         }
  158.     //
  159.     // Or, delete drones as needed
  160.     //
  161.     for(i=iNumDrones; i < iCurNumDrones;i++) {
  162.         ptDrones.next = DeletePlayer(ptDrones.next);
  163.         }
  164.     return;
  165. }
  166. /*=====================================================================
  167. Function: MoveDrone()
  168. Inputs: Ignored except for hWnd, handle to current window
  169. Outputs:returns success/failure
  170. Abstract:
  171.     This is a timer callback function which modifies the position of the
  172.     drones in their data structures. After their positions have been changed
  173.     in their record, a message is sent to the 3-d window telling it that
  174.     drones need to be redrawn.
  175. ======================================================================*/
  176. LRESULT CALLBACK MoveDrone(
  177.     HWND hWnd,
  178.     UINT wMsg,
  179.     UINT idTimer,
  180.     DWORD dwTime
  181.     )
  182. {
  183.     int x,y;
  184.     BYTE b1,b2,dForward,dBack,dLeft,dRight;
  185.     BOOL blocked;
  186.     PlayerType FAR *ptTrav;
  187.     PositionType ptPos;
  188.     char cBuff[132];
  189.     LPRECT rUpd;
  190.     HANDLE hMem;
  191.     static DWORD dwCallCount=0;
  192.     dwCallCount++;
  193.     //
  194.     // If we're in demo mode, use this callback to move US!
  195.     //
  196.     if (bDemoMode) {
  197.         x=ptSelf.Pos.ix;
  198.         y=ptSelf.Pos.iy;
  199.         dForward = ptSelf.Pos.Facing;
  200.         dBack = BACK_TO_ABS(dForward);
  201.         dLeft = LEFT_TO_ABS(dForward);
  202.         dRight = RIGHT_TO_ABS(dForward);
  203.         b1 = bMaze[x][y];
  204.         b2 = bMaze[ADJ_X(x,dForward)][ADJ_Y(y,dForward)];
  205.         blocked = FALSE;
  206.         if ((b1&dForward)||(b2&dBack)) {
  207.             blocked = TRUE;
  208.             b2 = bMaze[ADJ_X(x,dRight)][ADJ_Y(y,dRight)];
  209.             if ((b1&dLeft)||(b2&dRight)) {
  210.                 b2 = bMaze[ADJ_X(x,dLeft)][ADJ_Y(y,dLeft)];
  211.                 if ((b1&dLeft)||(b2&dRight)) {
  212.                     x = RIGHT;
  213.                     }
  214.                 else {
  215.                     x = LEFT;
  216.                     }
  217.                 }
  218.             else {
  219.                 x = RIGHT;
  220.                 }
  221.             }
  222.         else {
  223.             x = FORWARD;
  224.             }
  225.         y = RandRange(1,11);
  226.         switch (y) {
  227.             case 8:
  228.                 x = LEFT;
  229.                 break;
  230.             case 9:
  231.                 x = RIGHT;
  232.                 break;
  233.             case 10:
  234.                 x = FORWARD;
  235.                 break;
  236.             case 11:
  237.                 x = BACK;
  238.                 break;
  239.             }
  240.         switch (x) {
  241.             case LEFT:
  242.                 PostMessage(hWndMaze,WM_KEYDOWN,VK_LEFT,0);
  243.                 break;
  244.             case RIGHT:
  245.                 PostMessage(hWndMaze,WM_KEYDOWN,VK_RIGHT,0);
  246.                 break;
  247.             case FORWARD:
  248.                 PostMessage(hWndMaze,WM_KEYDOWN,VK_UP,0);
  249.                 break;
  250.             }
  251.         if ((RandRange(1,3) == 3)&&(!blocked)) {
  252.             PostMessage(hWndMaze,WM_KEYDOWN,VK_SPACE,0);
  253.             }
  254.         }
  255.     hMem = GlobalAlloc(GHND,sizeof(RECT));
  256.     rUpd = (LPRECT) GlobalLock(hMem);
  257.     if (rUpd == NULL) {
  258.         MessageBox((HWND)NULL,GetStringRes(IDS_RECTALLOCFAIL),"MoveDrone",
  259.                MB_APPLMODAL);
  260.         PostMessage(hWndMain,WM_CLOSE,0,0);
  261.         }
  262.     rUpd->right = rMaze.left;
  263.     rUpd->left = rMaze.right;
  264.     rUpd->top = rMaze.bottom;
  265.     rUpd->bottom = rMaze.top;
  266.     ptTrav = &ptDrones;
  267.     while ((ptTrav->next != NULL)&&(!GamePaused)) {
  268.         //
  269.         // Only use every 2nd drone move in demo mode
  270.         //
  271.         if (bDemoMode && (dwCallCount % 2)) {
  272.             break;
  273.             }
  274.         ptTrav = ptTrav->next;
  275.         if (ptTrav->Drawn) {
  276.             rUpd->right = (rUpd->right > ptTrav->rDrawn.right) ? rUpd->right : ptTrav->rDrawn.right;
  277.             rUpd->left = (rUpd->left < ptTrav->rDrawn.left) ? rUpd->left : ptTrav->rDrawn.left;
  278.             rUpd->top = (rUpd->top < ptTrav->rDrawn.top) ? rUpd->top : ptTrav->rDrawn.top;
  279.             rUpd->bottom = (rUpd->bottom > ptTrav->rDrawn.bottom) ? rUpd->bottom : ptTrav->rDrawn.bottom;
  280.             ptTrav->Drawn=FALSE;
  281.             }
  282.         x=ptTrav->Pos.ix;
  283.         y=ptTrav->Pos.iy;
  284.         dForward = ptTrav->Pos.Facing;
  285.         dBack = BACK_TO_ABS(dForward);
  286.         dLeft = LEFT_TO_ABS(dForward);
  287.         dRight = RIGHT_TO_ABS(dForward);
  288.         ptPos.ix = x;
  289.         ptPos.iy = y;
  290.         ptPos.Facing = dForward;
  291.         b1 = bMaze[x][y];
  292.         b2 = bMaze[ADJ_X(x,dForward)][ADJ_Y(y,dForward)];
  293.         if ((b1&dForward)||(b2&dBack)) {
  294.             b2 = bMaze[ADJ_X(x,dLeft)][ADJ_Y(y,dLeft)];
  295.             if ((b1&dLeft)||(b2&dRight)) {
  296.                 b2 = bMaze[ADJ_X(x,dRight)][ADJ_Y(y,dRight)];
  297.                 if ((b1&dRight)||(b2&dLeft)) {
  298.                     ptPos.Facing = LEFT_TO_ABS(ptTrav->Pos.Facing);
  299.                     }
  300.                 else {
  301.                     ptPos.Facing = RIGHT_TO_ABS(ptTrav->Pos.Facing);
  302.                     }
  303.                 }
  304.             else {
  305.                 ptPos.Facing = LEFT_TO_ABS(ptTrav->Pos.Facing);
  306.                 }
  307.             }
  308.         else {
  309.             if (RandRange(1,10) == 1) {
  310.                 ptPos.Facing = LEFT_TO_ABS(ptTrav->Pos.Facing);
  311.                 }
  312.             else {
  313.                 if (RandRange(1,10) == 1) {
  314.                     ptPos.Facing = RIGHT_TO_ABS(ptTrav->Pos.Facing);
  315.                     }
  316.                 else {
  317.                     ptPos.ix = ADJ_X(ptTrav->Pos.ix,dForward);
  318.                     ptPos.iy = ADJ_Y(ptTrav->Pos.iy,dForward);
  319.                     }
  320.                 }
  321.             }
  322.         ptTrav->Pos = ptPos;
  323.         //
  324.         // If the drone has homed in on us, we are dead!
  325.         //
  326.         if ((!InSanctuary(&ptSelf.Pos))&&
  327.             (ptSelf.Pos.ix == ptPos.ix)&&(ptSelf.Pos.iy == ptPos.iy)
  328.            ) {
  329.             sprintf(cBuff,GetStringRes(IDS_FMT_RUNDOWN),ptTrav->cUserName);
  330.             PrintTextLine(cBuff);
  331.             ptSelf.iScore -=(iDroneSpeed) ? 36/iDroneSpeed/iDroneSpeed : 72;
  332.             KillSelf();
  333.             SendNetMessage(0,0,NULL,NP_SCORE);
  334.             iKilledByDrones++;
  335.             break;
  336.             }
  337.         }
  338.     PostMessage(hWndMaze,WM_COMMAND,IDM_DRAWDRONES,(DWORD) rUpd);
  339.     return(0);
  340. }