]> Shamusworld >> Repos - warehouse-man-deluxe/blobdiff - src/gameboard.cpp
Added/fixed editor, added play level functionality.
[warehouse-man-deluxe] / src / gameboard.cpp
index b18fe9a1e2010d016022b9b5499981ecf9030f77..0d1216f1c0bfbd1b16bfbadc2dc1ad0fb9197554 100644 (file)
@@ -15,6 +15,7 @@
 #include <string.h>
 //#include <stdio.h>   // for printf()
 #include "boards.h"
+#include "editorwidget.h"      // for Level
 
 
 GameBoard::GameBoard(int boardNumber)
@@ -31,8 +32,7 @@ GameBoard::GameBoard(int boardNumber)
        boardLength = width * height;
        board = new char[boardLength];
        initialBoard = new char[boardLength];
-//     initialX = boardToUse->x;
-//     initialY = boardToUse->y;
+       name = (const char *)&(boardToUse->state[boardLength]);
 
        for(int i=0; i<boardLength; i++)
        {
@@ -48,11 +48,49 @@ GameBoard::GameBoard(int boardNumber)
                        initialBoard[i] = GTBoxSpot;
                else if (c == '+')
                        initialBoard[i] = GTBox | GTBoxSpot;
-               else if (c == 'o')
+               else if (c == 'o' || c == '*')
                {
-                       initialBoard[i] = GTSpace;
+                       initialBoard[i] = (c == '*' ? GTBoxSpot : GTSpace);
                        initialX = i % width, initialY = i / width;
                }
+               else
+                       initialBoard[i] = GTNull;
+       }
+
+       ResetGame();
+}
+
+
+GameBoard::GameBoard(Level * level)
+{
+       Point size, corner;
+
+       EditorWidget::GetSizeAndCorner(level, size, corner);
+
+       width = size.x;
+       height = size.y;
+       boardLength = width * height;
+       board = new char[boardLength];
+       initialBoard = new char[boardLength];
+       name = level->name;
+
+       int current = 0;
+
+       for(int y=0; y<size.y; y++)
+       {
+               for(int x=0; x<size.x; x++)
+               {
+                       uint8_t tile = level->board[corner.x + x][corner.y + y];
+
+                       if (tile & GTMan)
+                       {
+                               initialX = x;
+                               initialY = y;
+                               tile &= ~GTMan;
+                       }
+
+                       initialBoard[current++] = tile;
+               }
        }
 
        ResetGame();
@@ -88,6 +126,7 @@ void GameBoard::ResetGame(void)
 {
        memcpy(board, initialBoard, boardLength);
        playerX = initialX, playerY = initialY;
+       numMoves = 0;
 }
 
 
@@ -100,7 +139,7 @@ int GameBoard::MovePlayerN(void)
        char cell1 = board[playerX + ((playerY - 1) * width)] & ~GTBoxSpot;
        char cell2 = board[playerX + ((playerY - 2) * width)] & ~GTBoxSpot;
 
-       return Move(playerY, -1, cell1, cell2);
+       return Move(0, -1, cell1, cell2);
 }
 
 
@@ -113,7 +152,7 @@ int GameBoard::MovePlayerS(void)
        char cell1 = board[playerX + ((playerY + 1) * width)] & ~GTBoxSpot;
        char cell2 = board[playerX + ((playerY + 2) * width)] & ~GTBoxSpot;
 
-       return Move(playerY, +1, cell1, cell2);
+       return Move(0, +1, cell1, cell2);
 }
 
 
@@ -126,7 +165,7 @@ int GameBoard::MovePlayerE(void)
        char cell1 = board[(playerX + 1) + (playerY * width)] & ~GTBoxSpot;
        char cell2 = board[(playerX + 2) + (playerY * width)] & ~GTBoxSpot;
 
-       return Move(playerX, +1, cell1, cell2);
+       return Move(+1, 0, cell1, cell2);
 }
 
 
@@ -139,26 +178,30 @@ int GameBoard::MovePlayerW(void)
        char cell1 = board[(playerX - 1) + (playerY * width)] & ~GTBoxSpot;
        char cell2 = board[(playerX - 2) + (playerY * width)] & ~GTBoxSpot;
 
-       return Move(playerX, -1, cell1, cell2);
+       return Move(-1, 0, cell1, cell2);
 }
 
 
-int GameBoard::Move(int & var, int direction, char cell1, char cell2)
+int GameBoard::Move(int dx, int dy, char cell1, char cell2)
 {
        // Player is moving into an unoccupied space...
        if (cell1 == GTSpace)
        {
-               var += direction;
+               playerX += dx, playerY += dy;
+               undo[numMoves].dx = dx, undo[numMoves].dy = dy, undo[numMoves].type = PMWalk;
+               numMoves++;
                return PMWalk;
        }
        // Player is pushing a box into an unoccupied space...
        else if ((cell1 == GTBox) && (cell2 == GTSpace))
        {
-               var += direction;
+               playerX += dx, playerY += dy;
                board[playerX + (playerY * width)] &= GTBoxSpot;
-               var += direction;
+               playerX += dx, playerY += dy;
                board[playerX + (playerY * width)] |= GTBox;
-               var -= direction;
+               playerX -= dx, playerY -= dy;
+               undo[numMoves].dx = dx, undo[numMoves].dy = dy, undo[numMoves].type = PMPush;
+               numMoves++;
                return PMPush;
        }
 
@@ -203,3 +246,31 @@ bool GameBoard::IsBoxWOfPlayer(void)
 }
 
 
+bool GameBoard::UndoLastMove(int & dx, int & dy, int & type)
+{
+       if (numMoves == 0)
+               return false;
+
+       numMoves--;
+       dx = undo[numMoves].dx;
+       dy = undo[numMoves].dy;
+       type = undo[numMoves].type;
+
+       // Undo the box's move (if any)
+       if (type == PMPush)
+       {
+               int boxPosition = (playerX + dx) + ((playerY + dy) * width);
+               int newBoxPosition = playerX + (playerY * width);
+
+               board[boxPosition] &= GTBoxSpot;
+//             board[newBoxPosition] &= GTBoxSpot;     // This is extraneous
+               board[newBoxPosition] |= GTBox;
+       }
+
+       // Undo the player's move
+       playerX += -dx;
+       playerY += -dy;
+
+       return true;
+}
+