1 /* 2 SPDX-FileCopyrightText: 2009 Ian Wadham <iandw.au@gmail.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #ifndef KGRRUNNER_H 8 #define KGRRUNNER_H 9 10 #include "kgrglobals.h" 11 12 #include <QObject> 13 #include <QElapsedTimer> // IDW 14 15 class KGrLevelPlayer; 16 class KGrLevelGrid; 17 class KGrRuleBook; 18 class KGrEnemy; 19 20 enum Situation {NotTimeYet, CaughtInBrick, MidCell, EndCell}; 21 22 /** 23 * This class provides the shared features of all runners (hero and enemies). 24 */ 25 class KGrRunner : public QObject 26 { 27 Q_OBJECT 28 public: 29 /** 30 * The constructor of the KGrRunner virtual class. 31 * 32 * @param pLevelPlayer The object that owns the runner and will destroy it 33 * if the KGoldrunner application is terminated during 34 * play. The object also provides helper functions to 35 * the runners. 36 * @param pGrid The grid on which the runner is playing. 37 * @param i The starting column-number (>=1). 38 * @param j The starting row-number (>=1). 39 * @param pSpriteId The sprite ID of the runner, as used in animation. 40 * @param pRules The rules that apply to this game and level. 41 * @param startDelay The starting-time advantage enemies give to the hero. 42 */ 43 KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid, 44 int i, int j, const int pSpriteId, 45 KGrRuleBook * pRules, const int startDelay); 46 ~KGrRunner() override; 47 48 /** 49 * Returns the exact position of a runner (in grid-points or cell 50 * sub-divisions) and the number of grid-points per cell, from which the 51 * cell's column-number and row-number can be calculated if required. 52 * 53 * @param x X-coordinate in grid-points (return by reference). 54 * @param y Y-coordinate in grid-points (return by reference). 55 * 56 * @return The number of grid-points per cell. 57 */ whereAreYou(int & x,int & y)58 inline int whereAreYou (int & x, int & y) { 59 x = gridX; y = gridY; return pointsPerCell; } 60 61 Q_SIGNALS: 62 /** 63 * Requests the KGoldrunner game to add to the human player's score. 64 * 65 * @param n The amount to add to the score. 66 */ 67 void incScore (const int n); 68 69 /** 70 * Requests the view-object to display an animation of a runner at a 71 * particular cell, cancelling and superseding any current animation. 72 * 73 * @param spriteId The ID of the sprite (hero or enemy). 74 * @param repeating If true, repeat the animation until the next signal. 75 * @param i The column-number of the cell to start at. 76 * @param j The row-number of the cell to start at. 77 * @param time The time in which to traverse one cell. 78 * @param dirn The direction of motion, or STAND. 79 * @param type The type of animation (walk, climb. etc.). 80 */ 81 void startAnimation (const int spriteId, const bool repeating, 82 const int i, const int j, const int time, 83 const Direction dirn, const AnimationType type); 84 85 protected: 86 KGrLevelPlayer * levelPlayer; 87 KGrLevelGrid * grid; 88 KGrRuleBook * rules; 89 90 int spriteId; 91 92 int gridI; 93 int gridJ; 94 int gridX; 95 int gridY; 96 int deltaX; 97 int deltaY; 98 99 int pointCtr; 100 int pointsPerCell; 101 bool turnAnywhere; 102 103 void getRules(); 104 105 Situation situation (const int scaledTime); 106 char nextCell(); 107 bool setNextMovement (const char spriteType, 108 const char cellType, 109 Direction & dir, 110 AnimationType & anim, int & interval); 111 112 bool falling; 113 KGrEnemy * onEnemy; // If standing or riding on an enemy. 114 Direction currDirection; 115 AnimationType currAnimation; 116 117 int runTime; // Time interval for hero/enemy running. 118 int fallTime; // Time interval for hero/enemy falling. 119 int enemyFallTime; // Time interval for enemy falling. 120 int trapTime; // Time interval for which an enemy can 121 // stay trapped in a brick. 122 123 int interval; // The runner's current time interval. 124 int timeLeft; // Time till the runner's next action. 125 126 bool leftRightSearch; // KGoldrunner-rules enemy search-mode. 127 128 QElapsedTimer t; // IDW 129 }; 130 131 132 /** 133 * This class models the behaviour of the hero. It inherits from KGrRunner. 134 * 135 * The hero's main functions are running, digging holes in bricks and collecting 136 * gold. If he is caught by an enemy or trapped in a closing brick, he dies. 137 * If he collects all the gold and runs to the top row, he wins the level. 138 */ 139 class KGrHero : public KGrRunner 140 { 141 Q_OBJECT 142 public: 143 /** 144 * The constructor of the KGrHero class. The parameters are the same as 145 * for the KGrRunner constructor, which does most of the work, but this 146 * constructor also initialises the hero's timing, which depends on the 147 * rules being used. 148 * 149 * @param pLevelPlayer The object that owns the hero and will destroy him 150 * if the KGoldrunner application is terminated during 151 * play. The object also provides helper functions to 152 * the hero. 153 * @param pGrid The grid on which the hero is playing. 154 * @param i The starting column-number (>=1). 155 * @param j The starting row-number (>=1). 156 * @param pSpriteId The sprite ID of the hero, as used in animation. 157 * @param pRules The rules that apply to this game and level. 158 */ 159 KGrHero (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid, 160 int i, int j, int pSpriteId, KGrRuleBook * pRules); 161 ~KGrHero() override; 162 163 /** 164 * Makes the hero run, under control of a pointer or the keyboard and 165 * guided by the layout of the grid. The method is invoked by a periodic 166 * timer and returns NORMAL status while play continues. If the hero is 167 * caught by an enemy or trapped in a brick, it returns DEAD status, or 168 * if he collects all the gold and reaches the top row, the method returns 169 * WON_LEVEL status. Otherwise it changes the hero's position as required 170 * and decides the type of animation to display (run left, climb, etc.). 171 * 172 * @param scaledTime The amount by which to adjust the time, scaled 173 * according to the current game-speed setting. Smaller 174 * times cause slower running in real-time: larger times 175 * cause faster running. 176 * 177 * @return The hero's status: NORMAL, DEAD or WON_LEVEL. 178 */ 179 HeroStatus run (const int scaledTime); 180 181 /** 182 * Decides whether the hero can dig as is required by pressing a key or a 183 * mouse-button. If OK, the KGrLevelPlayer will control the dug brick. 184 * 185 * @param dirn The direction in which to dig: L or R of the hero. 186 * @param digI The column-number of the brick (return by reference). 187 * @param digJ The row-number of the brick (return by reference). 188 * 189 * @return If true, a hole can be dug in the direction required. 190 */ 191 bool dig (const Direction dirn, int & digI, int & digJ); 192 193 /** 194 * Tells the hero whether dig while falling is allowed, or not. 195 */ setDigWhileFalling(const bool dwf)196 inline void setDigWhileFalling (const bool dwf) 197 { digWhileFalling = dwf; } 198 199 /** 200 * Tells the hero how many gold nuggets are remaining. 201 * 202 * @param nGold The number of gold nuggets remaining. 203 */ setNuggets(const int nGold)204 inline void setNuggets (const int nGold) { nuggets = nGold; } 205 206 /** 207 * Implements the author's debugging aid that shows the hero's state. 208 */ 209 void showState(); 210 211 Q_SIGNALS: 212 void soundSignal (const int n, const bool onOff = true); 213 void invalidDig(); // Warning re dig while falling. 214 215 private: 216 bool digWhileFalling; // If dig while falling is allowed. 217 int nuggets; // Number of gold pieces remaining. 218 }; 219 220 221 /** 222 * This class models the behaviour of an enemy. It inherits from KGrRunner. 223 * 224 * An enemy's main functions are running, chasing the hero and collecting or 225 * dropping gold. If he comes to a dug brick, he must fall in and give up any 226 * gold he is carrying. If he is trapped in a closing brick, he dies but 227 * reappears elsewhere on the grid. 228 */ 229 class KGrEnemy : public KGrRunner 230 { 231 Q_OBJECT 232 public: 233 /** 234 * The constructor of the KGrEnemy class. 235 * 236 * @param pLevelPlayer The object that owns the enemy and will destroy him 237 * if the KGoldrunner application is terminated during 238 * play. The object also provides helper functions to 239 * the enemies. 240 * @param pGrid The grid on which the enemy is playing. 241 * @param i The starting column-number (>=1). 242 * @param j The starting row-number (>=1). 243 * @param pSpriteId The sprite ID of the enemy, as used in animation. 244 * @param pRules The rules that apply to this game and level. 245 */ 246 KGrEnemy (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid, 247 int i, int j, int pSpriteId, KGrRuleBook * pRules); 248 ~KGrEnemy() override; 249 250 /** 251 * Makes an enemy run, guided by the position of the hero and the layout of 252 * the grid. The method is invoked by a periodic timer. If the enemy is 253 * trapped in a brick, he reappears somewhere else on the grid, depending 254 * on the rules for the game and level. While running, the enemy picks up 255 * and randomly drops gold. If he comes to a dug brick, he must fall in 256 * and give up any gold he is carrying. He can climb out after a time: or 257 * the hole might close first. Otherwise the method changes the enemy's 258 * position as required, avoids collisions and decides the type of animation 259 * to display (run left, climb, etc.). 260 * 261 * @param scaledTime The amount by which to adjust the time, scaled 262 * according to the current game-speed setting. Smaller 263 * times cause slower running in real-time: larger times 264 * cause faster running. 265 */ 266 void run (const int scaledTime); 267 268 /** 269 * Returns the direction in which the enemy is running: used for avoiding 270 * collisions with other enemies. 271 */ direction()272 inline Direction direction() { return (currDirection); } 273 274 /** 275 * Returns the ID of an enemy who already occupied the same cell (or -1). 276 */ getPrevInCell()277 inline int getPrevInCell() { return (prevInCell); } 278 279 /** 280 * Sets the ID of an enemy who already occupied the same cell (or -1). 281 * 282 * @param prevEnemy The sprite ID of the previous enemy (or -1). 283 */ setPrevInCell(const int prevEnemy)284 inline void setPrevInCell (const int prevEnemy) { 285 prevInCell = prevEnemy; } 286 287 /** 288 * Returns true if the enemy is falling. 289 */ isFalling()290 inline bool isFalling() { return falling; } 291 292 /** 293 * Implements the author's debugging aid that shows the enemy's state. 294 */ 295 void showState(); 296 297 private: 298 char rulesType; // Rules type and enemy search method. 299 300 int nuggets; // Number of gold pieces an enemy holds. 301 int birthI; // Enemy's starting position (used in 302 int birthJ; // KGoldrunner rules for re-birth). 303 int prevInCell; // ID of previous enemy in cell or -1. 304 305 void dropGold(); 306 void checkForGold(); 307 void dieAndReappear(); 308 309 void reserveCell (const int i, const int j); 310 void releaseCell (const int i, const int j); 311 }; 312 313 #endif // KGRRUNNER_H 314