PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/engines/avalanche/shootemup.cpp

http://github.com/scummvm/scummvm
C++ | 694 lines | 568 code | 95 blank | 31 comment | 163 complexity | c8712167afeb5c4b9e7c36d4c9ec46ba MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
  1. /* ScummVM - Graphic Adventure Engine
  2. *
  3. * ScummVM is the legal property of its developers, whose names
  4. * are too numerous to list here. Please refer to the COPYRIGHT
  5. * file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. /*
  23. * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
  24. * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
  25. */
  26. #include "avalanche/avalanche.h"
  27. #include "avalanche/shootemup.h"
  28. #include "common/random.h"
  29. #include "common/system.h"
  30. namespace Avalanche {
  31. const byte ShootEmUp::kStocks = 27;
  32. const byte ShootEmUp::kAvvyShoots = 86;
  33. const byte ShootEmUp::kFacingRight = 87;
  34. const byte ShootEmUp::kFacingLeft = 93;
  35. const long int ShootEmUp::kFlag = -20047;
  36. const byte ShootEmUp::kFrameDelayMax = 2;
  37. const byte ShootEmUp::kAvvyY = 150;
  38. const byte ShootEmUp::kShooting[7] = { 86, 79, 80, 81, 80, 79, 86 };
  39. const byte ShootEmUp::kTimesASecond = 18;
  40. const byte ShootEmUp::kFlashTime = 20; // If flash_time is <= this, the word "time" will flash. Should be about 20.
  41. const byte ShootEmUp::kLeftMargin = 10;
  42. const int16 ShootEmUp::kRightMargin = 605;
  43. ShootEmUp::ShootEmUp(AvalancheEngine *vm) {
  44. _vm = vm;
  45. _time = 120;
  46. for (int i = 0; i < 7; i++)
  47. _stockStatus[i] = 0;
  48. for (int i = 0; i < 99; i++) {
  49. _sprites[i]._ix = 0;
  50. _sprites[i]._iy = 0;
  51. _sprites[i]._x = kFlag;
  52. _sprites[i]._y = 0;
  53. _sprites[i]._p = 0;
  54. _sprites[i]._timeout = 0;
  55. _sprites[i]._cameo = false;
  56. _sprites[i]._cameoFrame = 0;
  57. _sprites[i]._missile = false;
  58. _sprites[i]._wipe = false;
  59. }
  60. _rectNum = 0;
  61. _avvyWas = 320;
  62. _avvyPos = 320;
  63. _avvyAnim = 1;
  64. _avvyFacing = kFacingLeft;
  65. _altWasPressedBefore = false;
  66. _throwNext = 73;
  67. _firing = false;
  68. for (int i = 0; i < 4; i++) {
  69. _running[i]._x = kFlag;
  70. _running[i]._y = 0;
  71. _running[i]._frame = 0;
  72. _running[i]._tooHigh = 0;
  73. _running[i]._lowest = 0;
  74. _running[i]._ix = 0;
  75. _running[i]._iy = 0;
  76. _running[i]._frameDelay = 0;
  77. }
  78. for (int i = 0; i < 7; i++)
  79. _hasEscaped[i] = false;
  80. _count321 = 255; // Counting down.
  81. _howManyHaveEscaped = 0;
  82. _escapeCount = 0;
  83. _escaping = false;
  84. _timeThisSecond = 0;
  85. _cp = false;
  86. _wasFacing = 0;
  87. _score = 0;
  88. _escapeStock = 0;
  89. _gotOut = false;
  90. }
  91. uint16 ShootEmUp::run() {
  92. CursorMan.showMouse(false);
  93. _vm->_graphics->saveScreen();
  94. _vm->fadeOut();
  95. _vm->_graphics->seuDrawTitle();
  96. _vm->fadeIn();
  97. _vm->_graphics->seuLoad();
  98. // Should we show the instructions?
  99. while (!_vm->shouldQuit()) {
  100. Common::Event event;
  101. _vm->getEvent(event);
  102. if (event.type == Common::EVENT_KEYDOWN) {
  103. if ((event.kbd.keycode == Common::KEYCODE_i) || (event.kbd.keycode == Common::KEYCODE_F1))
  104. instructions();
  105. break; // We don't show the instructions and simply go on with the minigame if not I or F1 was pressed.
  106. }
  107. }
  108. setup();
  109. while ((_time != 0) && (!_vm->shouldQuit())) {
  110. uint32 beginLoop = _vm->_system->getMillis();
  111. blankIt();
  112. hitPeople();
  113. plotThem();
  114. moveThem();
  115. moveAvvy();
  116. bumpFolk();
  117. peopleRunning();
  118. animate();
  119. escapeCheck();
  120. collisionCheck();
  121. updateTime();
  122. check321();
  123. readKbd();
  124. _cp = !_cp;
  125. _vm->_graphics->refreshScreen();
  126. uint32 delay = _vm->_system->getMillis() - beginLoop;
  127. if (delay <= 55)
  128. _vm->_system->delayMillis(55 - delay); // Replaces slowdown(); 55 comes from 18.2 Hz (B Flight).
  129. };
  130. _vm->fadeOut();
  131. _vm->_graphics->restoreScreen();
  132. _vm->_graphics->removeBackup();
  133. _vm->fadeIn();
  134. CursorMan.showMouse(true);
  135. return _score;
  136. }
  137. bool ShootEmUp::overlap(uint16 a1x, uint16 a1y, uint16 a2x, uint16 a2y, uint16 b1x, uint16 b1y, uint16 b2x, uint16 b2y) {
  138. // By De Morgan's law:
  139. return (a2x >= b1x) && (b2x >= a1x) && (a2y >= b1y) && (b2y >= a1y);
  140. }
  141. byte ShootEmUp::getStockNumber(byte index) {
  142. while (_hasEscaped[index]) {
  143. index++;
  144. if (index == 7)
  145. index = 0;
  146. }
  147. return index;
  148. }
  149. void ShootEmUp::blankIt() {
  150. for (int i = 0; i < _rectNum; i++)
  151. _vm->_graphics->drawFilledRectangle(_rectangles[i], kColorBlack);
  152. _rectNum = 0;
  153. }
  154. void ShootEmUp::moveThem() {
  155. for (int i = 0; i < 99; i++) {
  156. if (_sprites[i]._x != kFlag) {
  157. _sprites[i]._x += _sprites[i]._ix;
  158. _sprites[i]._y += _sprites[i]._iy;
  159. }
  160. }
  161. }
  162. void ShootEmUp::blank(Common::Rect rect) {
  163. _rectangles[_rectNum++] = rect;
  164. }
  165. void ShootEmUp::plotThem() {
  166. for (int i = 0; i < 99; i++) {
  167. if (_sprites[i]._x != kFlag) {
  168. if (_sprites[i]._cameo) {
  169. _vm->_graphics->seuDrawCameo(_sprites[i]._x, _sprites[i]._y, _sprites[i]._p, _sprites[i]._cameoFrame);
  170. if (!_cp) {
  171. _sprites[i]._cameoFrame += 2;
  172. _sprites[i]._p += 2;
  173. }
  174. } else
  175. _vm->_graphics->seuDrawPicture(_sprites[i]._x, _sprites[i]._y, _sprites[i]._p);
  176. if (_sprites[i]._wipe)
  177. blank(Common::Rect(_sprites[i]._x, _sprites[i]._y, _sprites[i]._x + _vm->_graphics->seuGetPicWidth(_sprites[i]._p), _sprites[i]._y + _vm->_graphics->seuGetPicHeight(_sprites[i]._p)));
  178. if (_sprites[i]._timeout > 0) {
  179. _sprites[i]._timeout--;
  180. if (_sprites[i]._timeout == 0)
  181. _sprites[i]._x = kFlag;
  182. }
  183. }
  184. }
  185. }
  186. void ShootEmUp::define(int16 x, int16 y, int8 p, int8 ix, int8 iy, int16 time, bool isAMissile, bool doWeWipe) {
  187. for (int i = 0; i < 99; i++) {
  188. if (_sprites[i]._x == kFlag) {
  189. _sprites[i]._x = x;
  190. _sprites[i]._y = y;
  191. _sprites[i]._p = p;
  192. _sprites[i]._ix = ix;
  193. _sprites[i]._iy = iy;
  194. _sprites[i]._timeout = time;
  195. _sprites[i]._cameo = false;
  196. _sprites[i]._missile = isAMissile;
  197. _sprites[i]._wipe = doWeWipe;
  198. return;
  199. }
  200. }
  201. }
  202. void ShootEmUp::defineCameo(int16 x, int16 y, int8 p, int16 time) {
  203. for (int i = 0; i < 99; i++) {
  204. if (_sprites[i]._x == kFlag) {
  205. _sprites[i]._x = x;
  206. _sprites[i]._y = y;
  207. _sprites[i]._p = p;
  208. _sprites[i]._ix = 0;
  209. _sprites[i]._iy = 0;
  210. _sprites[i]._timeout = time;
  211. _sprites[i]._cameo = true;
  212. _sprites[i]._cameoFrame = p + 1;
  213. _sprites[i]._missile = false;
  214. _sprites[i]._wipe = false;
  215. return;
  216. }
  217. }
  218. }
  219. void ShootEmUp::showStock(byte index) {
  220. if (_escaping && (index == _escapeStock)) {
  221. _vm->_graphics->seuDrawPicture(index * 90 + 20, 30, kStocks + 2);
  222. return;
  223. }
  224. if (_stockStatus[index] > 5)
  225. return;
  226. _vm->_graphics->seuDrawPicture(index * 90 + 20, 30, kStocks + _stockStatus[index]);
  227. _stockStatus[index] = 1 - _stockStatus[index];
  228. }
  229. void ShootEmUp::drawNumber(int number, int size, int x) {
  230. for (int i = 0; i < size - 1; i++) {
  231. int divisor = 10;
  232. for (int j = 0; j < size - 2 - i; j++)
  233. divisor *= 10;
  234. char value = number / divisor;
  235. _vm->_graphics->seuDrawPicture(x + i * 10, 0, value);
  236. number -= value * divisor;
  237. }
  238. _vm->_graphics->seuDrawPicture(x + (size - 1) * 10, 0, number % 10);
  239. }
  240. void ShootEmUp::showScore() {
  241. drawNumber(_score, 5, 40);
  242. }
  243. void ShootEmUp::showTime() {
  244. drawNumber(_time, 3, 140);
  245. }
  246. void ShootEmUp::gain(int8 howMuch) {
  247. if ((_score + howMuch) < 0) // howMuch can be negative!
  248. _score = 0;
  249. else
  250. _score += howMuch;
  251. showScore();
  252. }
  253. void ShootEmUp::newEscape() {
  254. _escapeCount = _vm->_rnd->getRandomNumber(17) * 20;
  255. _escaping = false;
  256. }
  257. void ShootEmUp::nextPage() {
  258. _vm->_graphics->drawNormalText("Press a key for next page >", _vm->_font, 8, 400, 190, kColorWhite);
  259. _vm->_graphics->refreshScreen();
  260. while (!_vm->shouldQuit()) {
  261. Common::Event event;
  262. _vm->getEvent(event);
  263. if (event.type == Common::EVENT_KEYDOWN) {
  264. break;
  265. }
  266. }
  267. _vm->_graphics->blackOutScreen();
  268. }
  269. void ShootEmUp::instructions() {
  270. _vm->_graphics->blackOutScreen();
  271. _vm->_graphics->seuDrawPicture(25, 25, kFacingRight);
  272. _vm->_graphics->drawNormalText("< Avvy, our hero, needs your help - you must move him around.", _vm->_font, 8, 60, 35, kColorWhite);
  273. _vm->_graphics->drawNormalText("(He''s too terrified to move himself!)", _vm->_font, 8, 80, 45, kColorWhite);
  274. _vm->_graphics->drawNormalText("Your task is to prevent the people in the stocks from escaping", _vm->_font, 8, 0, 75, kColorWhite);
  275. _vm->_graphics->drawNormalText("by pelting them with rotten fruit, eggs and bread. The keys are:", _vm->_font, 8, 0, 85, kColorWhite);
  276. _vm->_graphics->drawNormalText("LEFT SHIFT", _vm->_font, 8, 80, 115, kColorWhite);
  277. _vm->_graphics->drawNormalText("Move left.", _vm->_font, 8, 200, 115, kColorWhite);
  278. _vm->_graphics->drawNormalText("RIGHT SHIFT", _vm->_font, 8, 72, 135, kColorWhite);
  279. _vm->_graphics->drawNormalText("Move right.", _vm->_font, 8, 200, 135, kColorWhite);
  280. _vm->_graphics->drawNormalText("ALT", _vm->_font, 8, 136, 155, kColorWhite);
  281. _vm->_graphics->drawNormalText("Throw something.", _vm->_font, 8, 200, 155, kColorWhite);
  282. nextPage();
  283. _vm->_graphics->seuDrawPicture(25, 35, kStocks);
  284. _vm->_graphics->drawNormalText("This man is in the stocks. Your job is to stop him getting out.", _vm->_font, 8, 80, 35, kColorWhite);
  285. _vm->_graphics->drawNormalText("UNFORTUNATELY... the locks on the stocks are loose, and every", _vm->_font, 8, 88, 45, kColorWhite);
  286. _vm->_graphics->drawNormalText("so often, someone will discover this and try to get out.", _vm->_font, 8, 88, 55, kColorWhite);
  287. _vm->_graphics->seuDrawPicture(25, 85, kStocks + 2);
  288. _vm->_graphics->drawNormalText("< Someone who has found a way out!", _vm->_font, 8, 80, 85, kColorWhite);
  289. _vm->_graphics->drawNormalText("You MUST IMMEDIATELY hit people smiling like this, or they", _vm->_font, 8, 88, 95, kColorWhite);
  290. _vm->_graphics->drawNormalText("will disappear and lose you points.", _vm->_font, 8, 88, 105, kColorWhite);
  291. _vm->_graphics->seuDrawPicture(25, 125, kStocks + 5);
  292. _vm->_graphics->seuDrawPicture(25, 155, kStocks + 4);
  293. _vm->_graphics->drawNormalText("< Oh dear!", _vm->_font, 8, 80, 125, kColorWhite);
  294. nextPage();
  295. _vm->_graphics->drawNormalText("Your task is made harder by:", _vm->_font, 8, 0, 35, kColorWhite);
  296. _vm->_graphics->seuDrawPicture(25, 55, 48);
  297. _vm->_graphics->drawNormalText("< Yokels. These people will run in front of you. If you hit", _vm->_font, 8, 60, 55, kColorWhite);
  298. _vm->_graphics->drawNormalText("them, you will lose MORE points than you get hitting people", _vm->_font, 8, 68, 65, kColorWhite);
  299. _vm->_graphics->drawNormalText("in the stocks. So BEWARE!", _vm->_font, 8, 68, 75, kColorWhite);
  300. _vm->_graphics->drawNormalText("Good luck with the game!", _vm->_font, 8, 80, 125, kColorWhite);
  301. nextPage();
  302. }
  303. void ShootEmUp::setup() {
  304. _vm->_graphics->blackOutScreen();
  305. newEscape();
  306. for (int i = 0; i < 7; i++) {
  307. _stockStatus[i] = _vm->_rnd->getRandomNumber(1);
  308. showStock(i);
  309. }
  310. // Set up status line:
  311. _vm->_graphics->seuDrawPicture(0, 0, 16); // Score:
  312. showScore(); // Value of score (00000 here).
  313. _vm->_graphics->seuDrawPicture(110, 0, 19); // Time:
  314. showTime(); // Value of time.
  315. _vm->_graphics->refreshScreen();
  316. // From the original core cycle:
  317. initRunner(20, 70, 48, 54, _vm->_rnd->getRandomNumber(4) + 1, _vm->_rnd->getRandomNumber(3) - 2);
  318. initRunner(600, 70, 48, 54, _vm->_rnd->getRandomNumber(4) + 1, _vm->_rnd->getRandomNumber(3) - 2);
  319. initRunner(600, 100, 61, 67, (-(int8)_vm->_rnd->getRandomNumber(4)) + 1, _vm->_rnd->getRandomNumber(3) - 2);
  320. initRunner(20, 100, 61, 67, (-(int8)_vm->_rnd->getRandomNumber(4)) + 1, _vm->_rnd->getRandomNumber(3) - 2);
  321. }
  322. void ShootEmUp::initRunner(int16 x, int16 y, byte f1, byte f2, int8 ix, int8 iy) {
  323. for (int i = 0; i < 4; i++) {
  324. if (_running[i]._x == kFlag) {
  325. _running[i]._x = x;
  326. _running[i]._y = y;
  327. _running[i]._frame = f1;
  328. _running[i]._tooHigh = f2;
  329. _running[i]._lowest = f1;
  330. _running[i]._ix = ix;
  331. _running[i]._iy = iy;
  332. if ((ix == 0) && (iy == 0))
  333. _running[i]._ix = 2; // To stop them running on the spot!
  334. _running[i]._frameDelay = kFrameDelayMax;
  335. return;
  336. }
  337. }
  338. }
  339. void ShootEmUp::moveAvvy() {
  340. if (_avvyWas < _avvyPos)
  341. _avvyFacing = kFacingRight;
  342. else if (_avvyWas > _avvyPos)
  343. _avvyFacing = kFacingLeft;
  344. if (!_firing) {
  345. if (_avvyWas == _avvyPos)
  346. _avvyAnim = 1;
  347. else {
  348. _avvyAnim++;
  349. if (_avvyAnim == 6)
  350. _avvyAnim = 0;
  351. }
  352. }
  353. if (_avvyFacing == kAvvyShoots)
  354. define(_avvyPos, kAvvyY, kShooting[_avvyAnim], 0, 0, 1, false, true);
  355. else
  356. define(_avvyPos, kAvvyY, _avvyAnim + _avvyFacing, 0, 0, 1, false, true);
  357. _avvyWas = _avvyPos;
  358. if (_avvyFacing == kAvvyShoots) {
  359. if (_avvyAnim == 6) {
  360. _avvyFacing = _wasFacing;
  361. _avvyAnim = 0;
  362. _firing = false;
  363. } else
  364. _avvyAnim++;
  365. }
  366. }
  367. void ShootEmUp::readKbd() {
  368. Common::Event event;
  369. _vm->getEvent(event);
  370. if ((event.type == Common::EVENT_KEYUP) && ((event.kbd.keycode == Common::KEYCODE_LALT) || (event.kbd.keycode == Common::KEYCODE_RALT))) {
  371. // Don't let the player fire continuously by holding down one of the ALT keys.
  372. _altWasPressedBefore = false;
  373. return;
  374. }
  375. if (_firing) // So you can't stack up shots while the shooting animation plays.
  376. return;
  377. if (event.type == Common::EVENT_KEYDOWN) {
  378. switch (event.kbd.keycode) {
  379. case Common::KEYCODE_LALT: // Alt was pressed - shoot!
  380. case Common::KEYCODE_RALT: // Falltrough is intended.
  381. if (_altWasPressedBefore || (_count321 != 0))
  382. return;
  383. _altWasPressedBefore = true;
  384. _firing = true;
  385. define(_avvyPos + 27, kAvvyY + 5, _throwNext, 0, -2, 53, true, true);
  386. _throwNext++;
  387. if (_throwNext == 79)
  388. _throwNext = 73;
  389. _avvyAnim = 0;
  390. _wasFacing = _avvyFacing;
  391. _avvyFacing = kAvvyShoots;
  392. return;
  393. case Common::KEYCODE_RSHIFT: // Right shift: move right.
  394. _avvyPos += 5;
  395. if (_avvyPos > kRightMargin)
  396. _avvyPos = kRightMargin;
  397. return;
  398. case Common::KEYCODE_LSHIFT: // Left shift: move left.
  399. _avvyPos -= 5;
  400. if (_avvyPos < kLeftMargin)
  401. _avvyPos = kLeftMargin;
  402. return;
  403. default:
  404. break;
  405. }
  406. }
  407. }
  408. void ShootEmUp::animate() {
  409. if (_vm->_rnd->getRandomNumber(9) == 1)
  410. showStock(getStockNumber(_vm->_rnd->getRandomNumber(5)));
  411. for (int i = 0; i < 7; i++) {
  412. if (_stockStatus[i] > 5) {
  413. _stockStatus[i]--;
  414. if (_stockStatus[i] == 8) {
  415. _stockStatus[i] = 0;
  416. showStock(i);
  417. }
  418. }
  419. }
  420. }
  421. void ShootEmUp::collisionCheck() {
  422. for (int i = 0; i < 99; i++) {
  423. if ((_sprites[i]._x != kFlag) && (_sprites[i]._missile) &&
  424. (_sprites[i]._y < 60) && (_sprites[i]._timeout == 1)) {
  425. int distFromSide = (_sprites[i]._x - 20) % 90;
  426. int thisStock = (_sprites[i]._x - 20) / 90;
  427. if ((!_hasEscaped[thisStock]) && (distFromSide > 17) && (distFromSide < 34)) {
  428. _vm->_sound->playNote(999, 3);
  429. _vm->_system->delayMillis(3);
  430. define(_sprites[i]._x + 20, _sprites[i]._y, 25 + _vm->_rnd->getRandomNumber(1), 3, 1, 12, false, true); // Well done!
  431. define(thisStock * 90 + 20, 30, 30, 0, 0, 7, false, false); // Face of man
  432. defineCameo(thisStock * 90 + 20 + 10, 35, 40, 7); // Splat!
  433. define(thisStock * 90 + 20 + 20, 50, 33 + _vm->_rnd->getRandomNumber(4), 0, 2, 9, false, true); // Oof!
  434. _stockStatus[thisStock] = 17;
  435. gain(3); // Score for hitting a face.
  436. if (_escaping && (_escapeStock = thisStock)) { // Hit the escaper.
  437. _vm->_sound->playNote(1777, 1);
  438. _vm->_system->delayMillis(1);
  439. gain(5); // Bonus for hitting escaper.
  440. _escaping = false;
  441. newEscape();
  442. }
  443. } else {
  444. define(_sprites[i]._x, _sprites[i]._y, 82 + _vm->_rnd->getRandomNumber(2), 2, 2, 17, false, true); // Missed!
  445. if ((!_hasEscaped[thisStock]) && (distFromSide > 3) && (distFromSide < 43)) {
  446. define(thisStock * 90 + 20, 30, 29, 0, 0, 7, false, false); // Face of man
  447. if (distFromSide > 35)
  448. defineCameo(_sprites[i]._x - 27, 35, 40, 7); // Splat!
  449. else
  450. defineCameo(_sprites[i]._x - 7, 35, 40, 7);
  451. _stockStatus[thisStock] = 17;
  452. }
  453. }
  454. }
  455. }
  456. }
  457. void ShootEmUp::turnAround(byte who, bool randomX) {
  458. if (randomX) {
  459. int8 ix = (_vm->_rnd->getRandomNumber(4) + 1);
  460. if (_running[who]._ix > 0)
  461. _running[who]._ix = -(ix);
  462. else
  463. _running[who]._ix = ix;
  464. } else
  465. _running[who]._ix = -(_running[who]._ix);
  466. _running[who]._iy = -(_running[who]._iy);
  467. }
  468. void ShootEmUp::bumpFolk() {
  469. for (int i = 0; i < 4; i++) {
  470. if (_running[i]._x != kFlag) {
  471. for (int j = i + 1; j < 4; j++) {
  472. bool overlaps = overlap(_running[i]._x, _running[i]._y, _running[i]._x + 17, _running[i]._y + 24,
  473. _running[j]._x, _running[j]._y, _running[j]._x + 17, _running[j]._y + 24);
  474. if ((_running[i]._x != kFlag) && overlaps) {
  475. turnAround(i, false); // Opp. directions.
  476. turnAround(j, false);
  477. }
  478. }
  479. }
  480. }
  481. }
  482. void ShootEmUp::peopleRunning() {
  483. if (_count321 != 0)
  484. return;
  485. for (int i = 0; i < 4; i++) {
  486. if (_running[i]._x != kFlag) {
  487. if (((_running[i]._y + _running[i]._iy) <= 53) || ((_running[i]._y + _running[i]._iy) >= 120))
  488. _running[i]._iy = -(_running[i]._iy);
  489. byte frame = 0;
  490. if (_running[i]._ix < 0)
  491. frame = _running[i]._frame - 1;
  492. else
  493. frame = _running[i]._frame + 6;
  494. define(_running[i]._x, _running[i]._y, frame, 0, 0, 1, false, true);
  495. if (_running[i]._frameDelay == 0) {
  496. _running[i]._frame++;
  497. if (_running[i]._frame == _running[i]._tooHigh)
  498. _running[i]._frame = _running[i]._lowest;
  499. _running[i]._frameDelay = kFrameDelayMax;
  500. _running[i]._y += _running[i]._iy;
  501. } else
  502. _running[i]._frameDelay--;
  503. if (((_running[i]._x + _running[i]._ix) <= 0) || ((_running[i]._x + _running[i]._ix) >= 620))
  504. turnAround(i, true);
  505. _running[i]._x += _running[i]._ix;
  506. }
  507. }
  508. }
  509. void ShootEmUp::updateTime() {
  510. if (_count321 != 0)
  511. return;
  512. _timeThisSecond++;
  513. if (_timeThisSecond < kTimesASecond)
  514. return;
  515. _time--;
  516. showTime();
  517. _timeThisSecond = 0;
  518. if (_time <= kFlashTime) {
  519. int timeMode = 0;
  520. if ((_time % 2) == 1)
  521. timeMode = 19; // Normal 'Time:'
  522. else
  523. timeMode = 85; // Flash 'Time:'
  524. _vm->_graphics->seuDrawPicture(110, 0, timeMode);
  525. }
  526. }
  527. void ShootEmUp::hitPeople() {
  528. if (_count321 != 0)
  529. return;
  530. for (int i = 0; i < 99; i++) {
  531. if ((_sprites[i]._missile) && (_sprites[i]._x != kFlag)) {
  532. for (int j = 0; j < 4; j++) {
  533. bool overlaps = overlap(_sprites[i]._x, _sprites[i]._y, _sprites[i]._x + 7, _sprites[i]._y + 10,
  534. _running[j]._x, _running[j]._y, _running[j]._x + 17, _running[j]._y + 24);
  535. if ((_running[j]._x != kFlag) && (overlaps)) {
  536. _vm->_sound->playNote(7177, 1);
  537. _sprites[i]._x = kFlag;
  538. gain(-5);
  539. define(_running[j]._x + 20, _running[j]._y + 3, 33 + _vm->_rnd->getRandomNumber(5), 1, 3, 9, false, true); // Oof!
  540. define(_sprites[i]._x, _sprites[i]._y, 82, 1, 0, 17, false, true); // Oops!
  541. }
  542. }
  543. }
  544. }
  545. }
  546. void ShootEmUp::escapeCheck() {
  547. if (_count321 != 0)
  548. return;
  549. if (_escapeCount > 0) {
  550. _escapeCount--;
  551. return;
  552. }
  553. // Escape_count = 0; now what ?
  554. if (_escaping) {
  555. if (_gotOut) {
  556. newEscape();
  557. _escaping = false;
  558. _vm->_graphics->seuDrawPicture(_escapeStock * 90 + 20, 30, kStocks + 4);
  559. } else {
  560. _vm->_graphics->seuDrawPicture(_escapeStock * 90 + 20, 30, kStocks + 5);
  561. _escapeCount = 20;
  562. _gotOut = true;
  563. define(_escapeStock * 90 + 20, 50, 24, 0, 2, 17, false, true); // Escaped!
  564. gain(-10);
  565. _hasEscaped[_escapeStock] = true;
  566. _howManyHaveEscaped++;
  567. if (_howManyHaveEscaped == 7) {
  568. _vm->_graphics->seuDrawPicture(266, 90, 23);
  569. _time = 0;
  570. }
  571. }
  572. } else {
  573. _escapeStock = getStockNumber(_vm->_rnd->getRandomNumber(6));
  574. _escaping = true;
  575. _gotOut = false;
  576. _vm->_graphics->seuDrawPicture(_escapeStock * 90 + 20, 30, kStocks + 2); // Smiling!
  577. _escapeCount = 200;
  578. }
  579. }
  580. void ShootEmUp::check321() {
  581. if (_count321 == 0)
  582. return;
  583. _count321--;
  584. switch (_count321) {
  585. case 84:
  586. define(320, 60, 15, 2, 1, 94, false, true);
  587. break;
  588. case 169:
  589. define(320, 60, 14, 0, 1, 94, false, true);
  590. break;
  591. case 254:
  592. define(320, 60, 13, -2, 1, 94, false, true);
  593. define(0, 100, 17, 2, 0, 254, false, true);
  594. break;
  595. default:
  596. break;
  597. }
  598. }
  599. } // End of namespace Avalanche