2623 lines
52 KiB
C++
2623 lines
52 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "got/game/move_patterns.h"
|
|
#include "got/events.h"
|
|
#include "got/game/back.h"
|
|
#include "got/game/boss1.h"
|
|
#include "got/game/boss2.h"
|
|
#include "got/game/boss3.h"
|
|
#include "got/game/move.h"
|
|
#include "got/game/object.h"
|
|
#include "got/game/script.h"
|
|
#include "got/game/special_tile.h"
|
|
#include "got/vars.h"
|
|
|
|
namespace Got {
|
|
|
|
#define TILE_SOLID 80
|
|
#define TILE_FLY 140
|
|
#define TILE_SPECIAL 200
|
|
|
|
int checkSpecialMove1(int x, int y, Actor *actor);
|
|
|
|
int checkMove0(int x, int y, Actor *actor);
|
|
int checkMove1(int x, int y, Actor *actor);
|
|
|
|
int movementZero(Actor *actor);
|
|
int movementOne(Actor *actor);
|
|
int movementTwo(Actor *actor);
|
|
int movementThree(Actor *actor);
|
|
int movementFour(Actor *actor);
|
|
int movementFive(Actor *actor);
|
|
int movementSix(Actor *actor);
|
|
int movementSeven(Actor *actor);
|
|
int movementEight(Actor *actor);
|
|
int movementNine(Actor *actor);
|
|
int movementTen(Actor *actor);
|
|
int movementEleven(Actor *actor);
|
|
int movementTwelve(Actor *actor); // Horizontal straight until bump
|
|
int movementThirteen(Actor *actor); // Pause-seek (mushroom)
|
|
int movementFourteen(Actor *actor); // Move-bump-stop (boulder)
|
|
int movementFifteen(Actor *actor); // No move, no frame cycle
|
|
int movementSixteen(Actor *actor); // Tornado 1
|
|
int movementSeventeen(Actor *actor); // Tornado 2
|
|
int movementEighteen(Actor *actor); // Random-seek-bite-run
|
|
int movementNineteen(Actor *actor); // Tornado 2
|
|
int movementTwenty(Actor *actor); // Tornado 2
|
|
int movementTwentyOne(Actor *actor); // Eyeball
|
|
int movementTwentyTwo(Actor *actor); // Spear
|
|
int movementTwentyThree(Actor *actor); // Spinball cw
|
|
int movementTwentyFour(Actor *actor); // Spinball ccw
|
|
int movementTwentyFive(Actor *actor); //
|
|
int movementTwentySix(Actor *actor); //
|
|
int movementTwentySeven(Actor *actor); //
|
|
int movementTwentyEight(Actor *actor); // Tree boss
|
|
int movementTwentyNine(Actor *actor); // Horizontal or vertical (pass_val)
|
|
int movementThirty(Actor *actor); // Vertical straight
|
|
int movementThirtyOne(Actor *actor); // Drop (stalagtite)
|
|
int movementThirtyTwo(Actor *actor); // Bomb 1
|
|
int movementThirtyThree(Actor *actor); // Bomb 2
|
|
int movementThirtyFour(Actor *actor); // Gun (4-dir)
|
|
int movementThirtyFive(Actor *actor); // Gun (4-dir)
|
|
int movementThirtySix(Actor *actor); // Acid drop
|
|
int movementThirtySeven(Actor *actor); // 4-way rnd,rnd len
|
|
int movementThirtyEight(Actor *actor); // Timed darting
|
|
int movementThirtyNine(Actor *actor); // Troll 1
|
|
int movementForty(Actor *actor); // Troll 2
|
|
|
|
int (*const _movementFunc[])(Actor *actor) = {
|
|
movementZero,
|
|
movementOne,
|
|
movementTwo,
|
|
movementThree,
|
|
movementFour,
|
|
movementFive,
|
|
movementSix,
|
|
movementSeven,
|
|
movementEight,
|
|
movementNine,
|
|
movementTen,
|
|
movementEleven,
|
|
movementTwelve,
|
|
movementThirteen,
|
|
movementFourteen,
|
|
movementFifteen,
|
|
movementSixteen,
|
|
movementSeventeen,
|
|
movementEighteen,
|
|
movementNineteen,
|
|
movementTwenty,
|
|
movementTwentyOne,
|
|
movementTwentyTwo,
|
|
movementTwentyThree,
|
|
movementTwentyFour,
|
|
movementTwentyFive,
|
|
movementTwentySix,
|
|
movementTwentySeven,
|
|
movementTwentyEight,
|
|
movementTwentyNine,
|
|
movementThirty,
|
|
movementThirtyOne,
|
|
movementThirtyTwo,
|
|
movementThirtyThree,
|
|
movementThirtyFour,
|
|
movementThirtyFive,
|
|
movementThirtySix,
|
|
movementThirtySeven,
|
|
movementThirtyEight,
|
|
movementThirtyNine,
|
|
movementForty};
|
|
|
|
int specialMovementOne(Actor *actor);
|
|
int specialMovementTwo(Actor *actor);
|
|
int specialMovementThree(Actor *actor);
|
|
int specialMovementFour(Actor *actor);
|
|
int specialMovementFive(Actor *actor);
|
|
int specialMovementSix(Actor *actor);
|
|
int specialMovementSeven(Actor *actor);
|
|
int specialMovementEight(Actor *actor);
|
|
int specialMovementNine(Actor *actor);
|
|
int specialMovementTen(Actor *actor);
|
|
int specialMovementEleven(Actor *actor);
|
|
|
|
int (*specialMovementFunc[])(Actor *actor) = {
|
|
nullptr,
|
|
specialMovementOne,
|
|
specialMovementTwo,
|
|
specialMovementThree,
|
|
specialMovementFour,
|
|
specialMovementFive,
|
|
specialMovementSix,
|
|
specialMovementSeven,
|
|
specialMovementEight,
|
|
specialMovementNine,
|
|
specialMovementTen,
|
|
specialMovementEleven};
|
|
|
|
// Check Thor move
|
|
int checkMove0(const int x, const int y, Actor *actor) {
|
|
_G(thorIcon1) = 0;
|
|
_G(thorIcon2) = 0;
|
|
_G(thorIcon3) = 0;
|
|
_G(thorIcon4) = 0;
|
|
|
|
if (x < 0) {
|
|
if (_G(currentLevel) > 0) {
|
|
_G(newLevel) = _G(currentLevel) - 1;
|
|
actor->_x = 304;
|
|
actor->_lastX[0] = 304;
|
|
actor->_lastX[1] = 304;
|
|
actor->_show = 0;
|
|
actor->_moveCount = 0;
|
|
setThorVars();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (x > 306) {
|
|
if (_G(currentLevel) < 119) {
|
|
_G(newLevel) = _G(currentLevel) + 1;
|
|
actor->_x = 0;
|
|
actor->_lastX[0] = 0;
|
|
actor->_lastX[1] = 0;
|
|
actor->_show = 0;
|
|
actor->_moveCount = 0;
|
|
setThorVars();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (y < 0) {
|
|
if (_G(currentLevel) > 9) {
|
|
_G(newLevel) = _G(currentLevel) - 10;
|
|
actor->_y = 175;
|
|
actor->_lastY[0] = 175;
|
|
actor->_show = 0;
|
|
actor->_lastY[1] = 175;
|
|
actor->_moveCount = 0;
|
|
setThorVars();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (y > 175) {
|
|
if (_G(currentLevel) < 110) {
|
|
_G(newLevel) = _G(currentLevel) + 10;
|
|
actor->_y = 0;
|
|
actor->_lastY[0] = 0;
|
|
actor->_lastY[1] = 0;
|
|
actor->_show = 0;
|
|
actor->_moveCount = 0;
|
|
setThorVars();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int x1 = (x + 1) >> 4;
|
|
int y1 = (y + 8) >> 4;
|
|
int x2 = (_G(thor)->_dir > 1) ? (x + 12) >> 4 : (x + 10) >> 4;
|
|
int y2 = (y + 15) >> 4;
|
|
|
|
_G(slipFlag) = false;
|
|
|
|
// Check for cheat flying mode
|
|
if (!actor->_flying) {
|
|
byte icn1 = _G(scrn)._iconGrid[y1][x1];
|
|
byte icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
byte icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
byte icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
int ti = 0;
|
|
|
|
if (icn1 < TILE_FLY) {
|
|
_G(thorIcon1) = 1;
|
|
ti = 1;
|
|
}
|
|
|
|
if (icn2 < TILE_FLY) {
|
|
_G(thorIcon2) = 1;
|
|
ti = 1;
|
|
}
|
|
|
|
if (icn3 < TILE_FLY) {
|
|
_G(thorIcon3) = 1;
|
|
ti = 1;
|
|
}
|
|
|
|
if (icn4 < TILE_FLY) {
|
|
_G(thorIcon4) = 1;
|
|
ti = 1;
|
|
}
|
|
|
|
if (ti)
|
|
return 0;
|
|
|
|
if (icn1 > TILE_SPECIAL) {
|
|
if (!specialTileThor(y1, x1, icn1))
|
|
return 0;
|
|
icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
}
|
|
|
|
if (icn2 > TILE_SPECIAL) {
|
|
if (!specialTileThor(y2, x1, icn2))
|
|
return 0;
|
|
icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
}
|
|
|
|
if (icn3 > TILE_SPECIAL) {
|
|
if (!specialTileThor(y1, x2, icn3))
|
|
return 0;
|
|
icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
}
|
|
|
|
if (icn4 > TILE_SPECIAL && !specialTileThor(y2, x2, icn4))
|
|
return 0;
|
|
}
|
|
|
|
if (!_G(slipFlag)) {
|
|
_G(slipping) = false;
|
|
_G(slipCount) = 0;
|
|
}
|
|
|
|
if (_G(slipFlag) && !_G(slipping))
|
|
_G(slipCount++);
|
|
|
|
if (_G(slipCount) > 8)
|
|
_G(slipping) = true;
|
|
|
|
_G(slipFlag) = false;
|
|
|
|
x1 = x + 1;
|
|
y1 = y + 8;
|
|
|
|
x2 = x + 12;
|
|
y2 = y + 15;
|
|
|
|
_G(thorSpecialFlag) = false;
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
Actor *act = &_G(actor[i]);
|
|
if ((act->_solid & 128) || !act->_active)
|
|
continue;
|
|
|
|
const int x3 = act->_x + 1;
|
|
const int y3 = act->_y + 1;
|
|
|
|
if (ABS(x3 - x1) > 16 || ABS(y3 - y1) > 16)
|
|
continue;
|
|
|
|
const int x4 = act->_x + act->_sizeX - 1;
|
|
const int y4 = act->_y + act->_sizeY - 1;
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4)) {
|
|
if (act->_funcNum > 0) { // 255=explosion
|
|
if (act->_funcNum == 255)
|
|
return 0;
|
|
act->_temp1 = x;
|
|
act->_temp2 = y;
|
|
_G(thorSpecialFlag) = true;
|
|
|
|
return specialMovementFunc[act->_funcNum](act);
|
|
}
|
|
|
|
_G(thorSpecialFlag) = false;
|
|
thorDamaged(act);
|
|
if (act->_solid < 2) {
|
|
if (!act->_vulnerableCountdown && (!(act->_type & 1)))
|
|
playSound(PUNCH1, false);
|
|
|
|
if (!_G(hammer)->_active && _G(keyFlag[key_fire]))
|
|
actorDamaged(act, _G(hammer)->_hitStrength);
|
|
else
|
|
actorDamaged(act, _G(thor)->_hitStrength);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
// Check hammer move
|
|
int checkMove1(const int x, const int y, Actor *actor) {
|
|
if (x < 0 || x > 306 || y < 0 || y > 177)
|
|
return 0;
|
|
|
|
int x1 = (x + 1) >> 4;
|
|
int y1 = (y + 6) >> 4;
|
|
int x2 = (x + 10) >> 4;
|
|
int y2 = (y + 10) >> 4;
|
|
|
|
// Check for solid or fly over
|
|
int icn = TILE_FLY;
|
|
if (actor->_flying)
|
|
icn = TILE_SOLID;
|
|
|
|
const byte icn1 = _G(scrn)._iconGrid[y1][x1];
|
|
const byte icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
const byte icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
const byte icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
if (icn1 < icn || icn2 < icn || icn3 < icn || icn4 < icn) {
|
|
if (actor->_actorNum == 1 && actor->_moveType == 2)
|
|
playSound(CLANG, false);
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (icn1 > TILE_SPECIAL && !specialTile(actor, y1, x1, icn1))
|
|
return 0;
|
|
|
|
if (icn2 > TILE_SPECIAL && !specialTile(actor, y2, x1, icn2))
|
|
return 0;
|
|
|
|
if (icn3 > TILE_SPECIAL && !specialTile(actor, y1, x2, icn3))
|
|
return 0;
|
|
|
|
if (icn4 > TILE_SPECIAL && !specialTile(actor, y2, x2, icn4))
|
|
return 0;
|
|
|
|
x1 = x + 1;
|
|
y1 = y + 1;
|
|
x2 = x + 10;
|
|
y2 = y + 10;
|
|
|
|
int f = 0;
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
Actor *act = &_G(actor[i]);
|
|
if (!act->_active || act->_type == 3)
|
|
continue;
|
|
|
|
const int x3 = act->_x;
|
|
const int y3 = act->_y;
|
|
|
|
if (ABS(x3 - x1) > 16 || ABS(y3 - y1) > 16)
|
|
continue;
|
|
|
|
const int x4 = act->_x + act->_sizeX - 1;
|
|
const int y4 = act->_y + act->_sizeY - 1;
|
|
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4)) {
|
|
if (_G(bossActive) && !GAME3) {
|
|
switch (_G(area)) {
|
|
case 1:
|
|
boss1CheckHit(act, x1, y1, x2, y2, i);
|
|
break;
|
|
case 2:
|
|
boss2CheckHit(act);
|
|
break;
|
|
default:
|
|
// Area 3 boss Loki isn't checked here
|
|
break;
|
|
}
|
|
} else {
|
|
if (act->_solid == 2 && (actor->_moveType == 16 || actor->_moveType == 17))
|
|
return 0;
|
|
actorDamaged(act, actor->_hitStrength);
|
|
}
|
|
f++;
|
|
}
|
|
}
|
|
if (f && actor->_moveType == 2)
|
|
return 0;
|
|
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
// Check enemy move
|
|
int checkMove2(const int x, const int y, Actor *actor) {
|
|
if (actor->_actorNum < 3)
|
|
return checkMove1(x, y, actor);
|
|
|
|
if (x < 0 || x > (319 - actor->_sizeX) || y < 0 || y > 175)
|
|
return 0;
|
|
|
|
int x1 = (x + 1) >> 4;
|
|
int y1;
|
|
if (!actor->_funcNum)
|
|
y1 = (y + (actor->_sizeY / 2)) >> 4;
|
|
else
|
|
y1 = (y + 1) >> 4;
|
|
|
|
int x2 = ((x + actor->_sizeX) - 1) >> 4;
|
|
int y2 = ((y + actor->_sizeY) - 1) >> 4;
|
|
|
|
// Check for solid or fly over
|
|
|
|
int icn = TILE_FLY;
|
|
if (actor->_flying)
|
|
icn = TILE_SOLID;
|
|
|
|
const byte icn1 = _G(scrn)._iconGrid[y1][x1];
|
|
const byte icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
const byte icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
const byte icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
if (icn1 < icn || icn2 < icn || icn3 < icn || icn4 < icn)
|
|
return 0;
|
|
|
|
if (icn1 > TILE_SPECIAL)
|
|
if (!specialTile(actor, y1, x1, icn1))
|
|
return 0;
|
|
if (icn2 > TILE_SPECIAL)
|
|
if (!specialTile(actor, y2, x1, icn2))
|
|
return 0;
|
|
if (icn3 > TILE_SPECIAL)
|
|
if (!specialTile(actor, y1, x2, icn3))
|
|
return 0;
|
|
if (icn4 > TILE_SPECIAL)
|
|
if (!specialTile(actor, y2, x2, icn4))
|
|
return 0;
|
|
|
|
x1 = x + 1;
|
|
y1 = y + 1;
|
|
x2 = (x + actor->_sizeX) - 1;
|
|
y2 = (y + actor->_sizeY) - 1;
|
|
|
|
for (int i = 0; i < MAX_ACTORS; i++) {
|
|
Actor *act = &_G(actor[i]);
|
|
if (act->_actorNum == actor->_actorNum || act->_actorNum == 1 || !act->_active)
|
|
continue;
|
|
if (act->_type == 3)
|
|
continue; // Shot
|
|
|
|
if (i == 0) {
|
|
if (overlap(x1, y1, x2, y2, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
|
thorDamaged(actor);
|
|
return 0;
|
|
}
|
|
} else {
|
|
const int x3 = act->_x;
|
|
const int y3 = act->_y;
|
|
|
|
if (ABS(x3 - x1) > 16 || ABS(y3 - y1) > 16)
|
|
continue;
|
|
|
|
const int x4 = act->_x + act->_sizeX;
|
|
const int y4 = act->_y + act->_sizeY;
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4)) {
|
|
if (actor->_moveType == 38) {
|
|
if (act->_funcNum == 4)
|
|
_G(switchUsed) = 1;
|
|
else if (act->_funcNum == 7)
|
|
_G(switchUsed) = 2;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
// Check enemy shot move
|
|
int checkMove3(const int x, const int y, Actor *actor) {
|
|
if (x < 0 || x > (319 - actor->_sizeX) || y < 0 || y > 175)
|
|
return 0;
|
|
|
|
int x1 = (x + 1) >> 4;
|
|
int y1 = (y + (actor->_sizeY / 2)) >> 4;
|
|
int x2 = ((x + actor->_sizeX) - 1) >> 4;
|
|
int y2 = ((y + actor->_sizeY) - 1) >> 4;
|
|
|
|
// Check for solid or fly over
|
|
|
|
int icn = TILE_FLY;
|
|
if (actor->_flying)
|
|
icn = TILE_SOLID;
|
|
|
|
const byte icn1 = _G(scrn)._iconGrid[y1][x1];
|
|
const byte icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
const byte icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
const byte icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
if (icn1 < icn || icn2 < icn || icn3 < icn || icn4 < icn)
|
|
return 0;
|
|
|
|
if (icn1 > TILE_SPECIAL && !specialTile(actor, y1, x1, icn1))
|
|
return 0;
|
|
if (icn2 > TILE_SPECIAL && !specialTile(actor, y2, x1, icn2))
|
|
return 0;
|
|
if (icn3 > TILE_SPECIAL && !specialTile(actor, y1, x2, icn3))
|
|
return 0;
|
|
if (icn4 > TILE_SPECIAL && !specialTile(actor, y2, x2, icn4))
|
|
return 0;
|
|
|
|
// Check for solid or fly over
|
|
x1 = x + 1;
|
|
y1 = y + 1;
|
|
x2 = (x + actor->_sizeX) - 1;
|
|
y2 = (y + actor->_sizeY) - 1;
|
|
|
|
if (overlap(x1, y1, x2, y2, _G(thorX1), _G(thorRealY1), _G(thorX2), _G(thorY2))) {
|
|
thorDamaged(actor);
|
|
return 0;
|
|
}
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
if (i == actor->_actorNum)
|
|
continue;
|
|
|
|
Actor *act = &_G(actor[i]);
|
|
|
|
if (!act->_active)
|
|
continue;
|
|
if (act->_solid < 2)
|
|
continue;
|
|
if (act->_type == 3)
|
|
continue; // Shot
|
|
if (act->_actorNum == actor->_creator)
|
|
continue;
|
|
|
|
const int x3 = act->_x;
|
|
const int y3 = act->_y;
|
|
|
|
if (ABS(x3 - x1) > 16 || ABS(y3 - y1) > 16)
|
|
continue;
|
|
|
|
const int x4 = x3 + 15;
|
|
const int y4 = y3 + 15;
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4))
|
|
return 0;
|
|
}
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
// Flying enemies
|
|
int checkMove4(const int x, const int y, Actor *actor) {
|
|
if (x < 0 || x > (319 - actor->_sizeX) || y < 0 || y > 175)
|
|
return 0;
|
|
if (overlap(x, y, x + actor->_sizeX - 1, y + actor->_sizeY - 1,
|
|
_G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
|
if (actor->_type == 3)
|
|
thorDamaged(actor);
|
|
return 0;
|
|
}
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
#define THOR_PAD1 2
|
|
#define THOR_PAD2 4
|
|
|
|
int check_thor_move(const int x, const int y, Actor *actor) {
|
|
if (checkMove0(x, y, actor))
|
|
return 1;
|
|
|
|
if (_G(diagFlag) || _G(thorSpecialFlag))
|
|
return 0;
|
|
|
|
if (_G(thorIcon1) + _G(thorIcon2) + _G(thorIcon3) + _G(thorIcon4) > 1)
|
|
return 0;
|
|
|
|
switch (actor->_dir) {
|
|
case 0:
|
|
if (_G(thorIcon1)) {
|
|
actor->_dir = 3;
|
|
if (checkMove0(x + THOR_PAD1, y + 2, actor)) {
|
|
actor->_dir = 0;
|
|
return 1;
|
|
}
|
|
} else if (_G(thorIcon3)) {
|
|
actor->_dir = 2;
|
|
if (checkMove0(x - THOR_PAD1, y + 2, actor)) {
|
|
actor->_dir = 0;
|
|
return 1;
|
|
}
|
|
}
|
|
actor->_dir = 0;
|
|
break;
|
|
|
|
case 1:
|
|
if (_G(thorIcon2)) {
|
|
actor->_dir = 3;
|
|
if (checkMove0(x + THOR_PAD1, y - 2, actor)) {
|
|
actor->_dir = 1;
|
|
return 1;
|
|
}
|
|
} else if (_G(thorIcon4)) {
|
|
actor->_dir = 2;
|
|
if (checkMove0(x - THOR_PAD1, y - 2, actor)) {
|
|
actor->_dir = 1;
|
|
return 1;
|
|
}
|
|
}
|
|
actor->_dir = 1;
|
|
break;
|
|
|
|
case 2:
|
|
if (_G(thorIcon1)) {
|
|
if (checkMove0(x + 2, y + THOR_PAD1, actor))
|
|
return 1;
|
|
} else if (_G(thorIcon2)) {
|
|
if (checkMove0(x + 2, y - THOR_PAD1, actor))
|
|
return 1;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (_G(thorIcon3)) {
|
|
if (checkMove0(x - 2, y + THOR_PAD1, actor))
|
|
return 1;
|
|
} else if (_G(thorIcon4)) {
|
|
if (checkMove0(x - 2, y - THOR_PAD1, actor))
|
|
return 1;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Player control
|
|
int movementZero(Actor *actor) {
|
|
int d = actor->_dir;
|
|
const int oldDir = d;
|
|
|
|
setThorVars();
|
|
|
|
if (_G(hammer)->_active && _G(hammer)->_moveType == 5) {
|
|
if (overlap(_G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2),
|
|
_G(hammer)->_x, _G(hammer)->_y, _G(hammer)->_x + 13, _G(hammer)->_y + 13)) {
|
|
actorDestroyed(_G(hammer));
|
|
}
|
|
}
|
|
int x = actor->_x;
|
|
int y = actor->_y;
|
|
_G(diagFlag) = false;
|
|
if (actor->_moveCounter)
|
|
actor->_moveCounter--;
|
|
|
|
if (_G(slipping)) {
|
|
if (_G(slipCount) == 8)
|
|
playSound(FALL, true);
|
|
|
|
y += 2;
|
|
_G(slipCount--);
|
|
if (!_G(slipCount))
|
|
_G(slipping) = false;
|
|
|
|
check_thor_move(x, y, actor);
|
|
_G(thor)->_moveCountdown = 4;
|
|
return d;
|
|
}
|
|
|
|
if (_G(keyFlag[key_up]) && _G(keyFlag[key_left])) {
|
|
d = 2;
|
|
actor->_dir = d;
|
|
_G(diag) = 1;
|
|
_G(diagFlag) = true;
|
|
if (check_thor_move(x - 2, y - 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
} else if (_G(keyFlag[key_up]) && _G(keyFlag[key_right])) {
|
|
d = 3;
|
|
actor->_dir = d;
|
|
_G(diag) = 2;
|
|
_G(diagFlag) = true;
|
|
if (check_thor_move(x + 2, y - 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
} else if (_G(keyFlag[key_down]) && _G(keyFlag[key_left])) {
|
|
d = 2;
|
|
actor->_dir = d;
|
|
_G(diag) = 4;
|
|
_G(diagFlag) = true;
|
|
if (check_thor_move(x - 2, y + 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
} else if (_G(keyFlag[key_down]) && _G(keyFlag[key_right])) {
|
|
d = 3;
|
|
actor->_dir = d;
|
|
_G(diag) = 3;
|
|
_G(diagFlag) = true;
|
|
if (check_thor_move(x + 2, y + 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
}
|
|
_G(diag) = 0;
|
|
if (_G(keyFlag[key_right]) && !_G(keyFlag[key_left])) {
|
|
d = 3;
|
|
actor->_dir = d;
|
|
if (check_thor_move(x + 2, y, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
}
|
|
|
|
if (_G(keyFlag[key_left]) && !_G(keyFlag[key_right])) {
|
|
d = 2;
|
|
actor->_dir = d;
|
|
if (check_thor_move(x - 2, y, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
}
|
|
|
|
if (_G(keyFlag[key_down]) && !_G(keyFlag[key_up])) {
|
|
d = 1;
|
|
actor->_dir = d;
|
|
if (check_thor_move(x, y + 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
}
|
|
|
|
if (_G(keyFlag[key_up]) && !_G(keyFlag[key_down])) {
|
|
d = 0;
|
|
actor->_dir = d;
|
|
if (check_thor_move(x, y - 2, actor)) {
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
}
|
|
|
|
if (_G(eyeballs)) {
|
|
nextFrame(actor);
|
|
actor->_dir = oldDir;
|
|
return d;
|
|
}
|
|
|
|
actor->_moveCounter = 5;
|
|
actor->_nextFrame = 0;
|
|
actor->_dir = oldDir;
|
|
return d;
|
|
}
|
|
|
|
int checkSpecialMove1(const int x, const int y, Actor *actor) {
|
|
int x3, y3, x4, y4;
|
|
|
|
Actor *act;
|
|
|
|
if (actor->_actorNum < 3)
|
|
return checkMove1(x, y, actor);
|
|
|
|
if (x < 0 || x > 304 || y < 0 || y > 176)
|
|
return 0;
|
|
|
|
int x1 = x >> 4;
|
|
int y1 = y >> 4;
|
|
int x2 = (x + 15) >> 4;
|
|
int y2 = (y + 15) >> 4;
|
|
|
|
// Check for solid or fly over
|
|
|
|
int icn = TILE_FLY;
|
|
if (actor->_flying)
|
|
icn = TILE_SOLID;
|
|
|
|
const byte icn1 = _G(scrn)._iconGrid[y1][x1];
|
|
const byte icn2 = _G(scrn)._iconGrid[y2][x1];
|
|
const byte icn3 = _G(scrn)._iconGrid[y1][x2];
|
|
const byte icn4 = _G(scrn)._iconGrid[y2][x2];
|
|
if (icn1 < icn || icn2 < icn || icn3 < icn || icn4 < icn)
|
|
return 0;
|
|
|
|
if (icn1 > TILE_SPECIAL && !specialTile(actor, y1, x1, icn1))
|
|
return 0;
|
|
if (icn2 > TILE_SPECIAL && !specialTile(actor, y2, x1, icn2))
|
|
return 0;
|
|
if (icn3 > TILE_SPECIAL && !specialTile(actor, y1, x2, icn3))
|
|
return 0;
|
|
if (icn4 > TILE_SPECIAL && !specialTile(actor, y2, x2, icn4))
|
|
return 0;
|
|
|
|
x1 = x;
|
|
y1 = y;
|
|
x2 = (x + 15);
|
|
y2 = (y + 15);
|
|
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
act = &_G(actor[i]);
|
|
if (act->_actorNum == actor->_actorNum)
|
|
continue;
|
|
if (!act->_active)
|
|
continue;
|
|
if (act->_type == 3)
|
|
continue; //shot
|
|
x3 = act->_x;
|
|
if ((ABS(x3 - x1)) > 16)
|
|
continue;
|
|
y3 = act->_y;
|
|
if ((ABS(y3 - y1)) > 16)
|
|
continue;
|
|
x4 = act->_x + act->_sizeX;
|
|
y4 = act->_y + 15;
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4))
|
|
return 0;
|
|
}
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
act = &_G(actor[i]);
|
|
if (act->_actorNum == actor->_actorNum)
|
|
continue;
|
|
if (!act->_active)
|
|
continue;
|
|
if (act->_type == 3)
|
|
continue; // Shot
|
|
x3 = act->_x;
|
|
if ((ABS(x3 - x1)) > 16)
|
|
continue;
|
|
y3 = act->_y;
|
|
if ((ABS(y3 - y1)) > 16)
|
|
continue;
|
|
x4 = act->_x + act->_sizeX;
|
|
y4 = act->_y + act->_sizeY;
|
|
if (overlap(_G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2), x3, y3, x4, y4))
|
|
return 0;
|
|
}
|
|
actor->_x = x;
|
|
actor->_y = y;
|
|
return 1;
|
|
}
|
|
|
|
//*==========================================================================
|
|
|
|
// Block
|
|
int specialMovementOne(Actor *actor) {
|
|
if (_G(diagFlag))
|
|
return 0;
|
|
|
|
const int d = _G(thor)->_dir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
const int sd = actor->_lastDir;
|
|
actor->_lastDir = d;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
if (!checkSpecialMove1(x1, y1, actor)) {
|
|
actor->_lastDir = sd;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
if (!checkSpecialMove1(x1, y1, actor)) {
|
|
actor->_lastDir = sd;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
if (!checkSpecialMove1(x1, y1, actor)) {
|
|
actor->_lastDir = sd;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
if (!checkSpecialMove1(x1, y1, actor)) {
|
|
actor->_lastDir = sd;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
return 1;
|
|
}
|
|
|
|
// Angle
|
|
int specialMovementTwo(Actor *actor) {
|
|
const int x1 = actor->_temp1; // Calc thor pos
|
|
const int y1 = actor->_temp2;
|
|
const int x2 = x1 + 13;
|
|
const int y2 = y1 + 14;
|
|
|
|
for (int i = 3; i < MAX_ACTORS; i++) {
|
|
Actor *act = &_G(actor[i]);
|
|
if (actor->_actorNum == act->_actorNum)
|
|
continue;
|
|
if (!act->_active)
|
|
continue;
|
|
const int x3 = act->_x;
|
|
if ((ABS(x3 - x1)) > 16)
|
|
continue;
|
|
const int y3 = act->_y;
|
|
if ((ABS(y3 - y1)) > 16)
|
|
continue;
|
|
const int x4 = act->_x + act->_sizeX;
|
|
const int y4 = act->_y + act->_sizeY;
|
|
if (overlap(x1, y1, x2, y2, x3, y3, x4, y4))
|
|
return 0;
|
|
}
|
|
if (!actor->_funcPass) {
|
|
if (_G(thor)->_health < 150) {
|
|
if (!soundPlaying())
|
|
playSound(ANGEL, false);
|
|
_G(thor)->_health += 1;
|
|
}
|
|
} else if (_G(thorInfo)._magic < 150) {
|
|
if (!soundPlaying())
|
|
playSound(ANGEL, false);
|
|
_G(thorInfo)._magic += 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Yellow globe
|
|
int specialMovementThree(Actor *actor) {
|
|
if (_G(thunderSnakeCounter))
|
|
return 0;
|
|
|
|
long lind = (long)_G(currentLevel);
|
|
lind *= 1000;
|
|
lind += (long)actor->_actorNum;
|
|
executeScript(lind, _G(odin));
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Peg switch
|
|
int specialMovementFour(Actor *actor) {
|
|
if (actor->_shotCountdown != 0)
|
|
return 0;
|
|
actor->_shotCountdown = 30;
|
|
|
|
_G(switchUsed) = 1;
|
|
return 0;
|
|
}
|
|
|
|
// Boulder roll
|
|
int specialMovementFive(Actor *actor) {
|
|
int d = _G(thor)->_dir;
|
|
|
|
if (_G(diagFlag)) {
|
|
switch (_G(diag)) {
|
|
case 1:
|
|
if (_G(thorX1) < (actor->_x + 15))
|
|
d = 0;
|
|
else
|
|
d = 2;
|
|
break;
|
|
|
|
case 2:
|
|
if (_G(thorX2) < actor->_x)
|
|
d = 3;
|
|
else
|
|
d = 0;
|
|
break;
|
|
|
|
case 3:
|
|
if (_G(thorX2) > (actor->_x))
|
|
d = 1;
|
|
else
|
|
d = 3;
|
|
break;
|
|
|
|
case 4:
|
|
if (_G(thorX1) > (actor->_x + 15))
|
|
d = 2;
|
|
else
|
|
d = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
actor->_lastDir = d;
|
|
actor->_moveType = 14;
|
|
return 0;
|
|
}
|
|
|
|
int specialMovementSix(Actor *actor) {
|
|
thorDamaged(actor);
|
|
return 0;
|
|
}
|
|
|
|
int specialMovementSeven(Actor *actor) {
|
|
if (actor->_shotCountdown != 0)
|
|
return 0;
|
|
|
|
actor->_shotCountdown = 30;
|
|
|
|
_G(switchUsed) = 2;
|
|
return 0;
|
|
}
|
|
|
|
int specialMovementEight(Actor *actor) {
|
|
if (_G(thor)->_dir < 2 || _G(diagFlag))
|
|
return 0;
|
|
|
|
actor->_lastDir = _G(thor)->_dir;
|
|
actor->_moveType = 14;
|
|
return 0;
|
|
}
|
|
|
|
int specialMovementNine(Actor *actor) {
|
|
if (_G(thor)->_dir > 1 || _G(diagFlag))
|
|
return 0;
|
|
|
|
actor->_lastDir = _G(thor)->_dir;
|
|
actor->_moveType = 14;
|
|
return 0;
|
|
}
|
|
|
|
int specialMovementTen(Actor *actor) {
|
|
byte &actor_ctr = GAME1 ? actor->_temp6 : actor->_talkCounter;
|
|
|
|
if (actor_ctr) {
|
|
actor_ctr--;
|
|
return 0;
|
|
}
|
|
|
|
if (_G(thunderSnakeCounter))
|
|
return 0;
|
|
|
|
actor_ctr = 10;
|
|
actorSpeaks(actor, 0 - actor->_passValue, 0);
|
|
return 0;
|
|
}
|
|
|
|
// Red guard
|
|
int specialMovementEleven(Actor *actor) {
|
|
if (actor->_talkCounter) {
|
|
actor->_talkCounter--;
|
|
return 0;
|
|
}
|
|
|
|
const int oldType = actor->_type;
|
|
actor->_type = 4;
|
|
actorSpeaks(actor, 0, 0);
|
|
actor->_type = oldType;
|
|
actor->_talkCounter = 10;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// No movement - frame cycle
|
|
int movementOne(Actor *actor) {
|
|
nextFrame(actor);
|
|
return actor->_dir;
|
|
}
|
|
|
|
// Hammer only
|
|
int movementTwo(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
if (actor->_actorNum == 1) {
|
|
_G(hammer)->_moveType = 5;
|
|
d = reverseDirection(_G(hammer));
|
|
_G(hammer)->_dir = d;
|
|
}
|
|
if (actor->_actorNum == 2) {
|
|
actor->_active = false;
|
|
actor->_dead = 2;
|
|
_G(tornadoUsed) = false;
|
|
}
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Walk-bump-random turn
|
|
int movementThree(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Simple tracking
|
|
int movementFour(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
int f = 0;
|
|
if (x1 > _G(thorX1) - 1) {
|
|
x1 -= 2;
|
|
d = 2;
|
|
f = 1;
|
|
} else if (x1 < _G(thorX1) - 1) {
|
|
x1 += 2;
|
|
d = 3;
|
|
f = 1;
|
|
}
|
|
|
|
if (f)
|
|
f = checkMove2(x1, y1, actor);
|
|
|
|
if (!f) {
|
|
if (y1 < (_G(thorRealY1))) {
|
|
d = (_G(thorRealY1)) - y1;
|
|
if (d > 2)
|
|
d = 2;
|
|
y1 += d;
|
|
d = 1;
|
|
f = 1;
|
|
} else if (y1 > (_G(thorRealY1))) {
|
|
d = y1 - (_G(thorRealY1));
|
|
if (d > 2)
|
|
d = 2;
|
|
y1 -= d;
|
|
d = 0;
|
|
f = 1;
|
|
}
|
|
if (f)
|
|
f = checkMove2(actor->_x, y1, actor);
|
|
if (!f)
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
int movementFive(Actor *actor) {
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
int xd = 0;
|
|
int yd = 0;
|
|
int d = actor->_lastDir;
|
|
|
|
if (x1 > (_G(thor)->_x + 1))
|
|
xd = -2; //+1
|
|
else if (x1 < (_G(thor)->_x - 1))
|
|
xd = 2;
|
|
|
|
if (actor->_actorNum == 1) {
|
|
if (y1 < (_G(thorY1) - 6))
|
|
yd = 2;
|
|
else if (y1 > (_G(thorY1) - 6))
|
|
yd = -2;
|
|
} else {
|
|
if (y1 < (_G(thorRealY1) - 1))
|
|
yd = 2;
|
|
else if (y1 > (_G(thorRealY1) + 1))
|
|
yd = -2;
|
|
}
|
|
|
|
if (xd && yd) {
|
|
if (xd == -2 && ABS(yd) == 2)
|
|
d = 2;
|
|
else if (xd == 2 && ABS(yd) == 2)
|
|
d = 3;
|
|
|
|
x1 += xd;
|
|
y1 += yd;
|
|
if (checkMove2(x1, y1, actor)) {
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
} else {
|
|
if (xd == 0 && yd == 2)
|
|
d = 1;
|
|
else if (xd == 0 && yd == -2)
|
|
d = 0;
|
|
else if (xd == 2 && yd == 0)
|
|
d = 3;
|
|
else if (xd == -2 && yd == 0)
|
|
d = 2;
|
|
}
|
|
x1 = actor->_x;
|
|
y1 = actor->_y;
|
|
actor->_toggle ^= 1;
|
|
|
|
if (actor->_toggle) {
|
|
if (xd) {
|
|
x1 += xd;
|
|
if (checkMove2(x1, y1, actor)) {
|
|
if (xd > 0)
|
|
d = 3;
|
|
else
|
|
d = 2;
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
x1 = actor->_x;
|
|
}
|
|
if (yd) {
|
|
y1 += yd;
|
|
if (checkMove2(x1, y1, actor)) {
|
|
if (yd > 0)
|
|
d = 1;
|
|
else
|
|
d = 0;
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
}
|
|
} else {
|
|
if (yd) {
|
|
y1 += yd;
|
|
if (checkMove2(x1, y1, actor)) {
|
|
if (yd > 0)
|
|
d = 1;
|
|
else
|
|
d = 0;
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
y1 = actor->_y;
|
|
}
|
|
if (xd) {
|
|
x1 += xd;
|
|
if (checkMove2(x1, y1, actor)) {
|
|
if (xd > 0)
|
|
d = 3;
|
|
else
|
|
d = 2;
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
}
|
|
}
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Explosion only
|
|
int movementSix(Actor *actor) {
|
|
if (actor->_currNumShots > 0) {
|
|
actor->_nextFrame++;
|
|
if (actor->_nextFrame > 2) {
|
|
actor->_nextFrame = 0;
|
|
if (_G(bossDead))
|
|
playSound(EXPLODE, false);
|
|
}
|
|
actor->_currNumShots--;
|
|
} else {
|
|
actor->_dead = 2;
|
|
actor->_active = false;
|
|
if (!_G(bossDead) && !_G(endGame)) {
|
|
if (actor->_type == 2)
|
|
dropRandomObject(actor);
|
|
}
|
|
}
|
|
|
|
nextFrame(actor);
|
|
return 0;
|
|
}
|
|
|
|
// Walk-bump-random turn (pause also)
|
|
int movementSeven(Actor *actor) {
|
|
if (actor->_nextFrame == 0 && actor->_frameCount == actor->_frameSpeed) {
|
|
actor->_moveCountdown = 12;
|
|
actor->_lastDir = g_events->getRandomNumber(3);
|
|
}
|
|
return movementThree(actor);
|
|
}
|
|
|
|
// Follow thor
|
|
int movementEight(Actor *actor) {
|
|
if (_G(thor)->_x > 0)
|
|
actor->_x = _G(thor)->_x - 1;
|
|
else
|
|
actor->_x = _G(thor)->_x;
|
|
actor->_y = _G(thor)->_y;
|
|
nextFrame(actor);
|
|
return 0;
|
|
}
|
|
|
|
// 4-way straight (random length) change
|
|
int movementNine(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
int f = 0;
|
|
if (actor->_counter) {
|
|
actor->_counter--;
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
if (!checkMove4(x1, y1, actor))
|
|
f = 1;
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
if (!checkMove4(x1, y1, actor))
|
|
f = 1;
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
if (!checkMove4(x1, y1, actor))
|
|
f = 1;
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
if (!checkMove4(x1, y1, actor))
|
|
f = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
f = 1;
|
|
|
|
if (f == 1) {
|
|
actor->_counter = g_events->getRandomNumber(10, 99);
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Vertical straight (random length) change
|
|
int movementTen(Actor *actor) {
|
|
int lastDir = actor->_lastDir;
|
|
const int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
bool setRandomDirFl = false;
|
|
if (actor->_counter) {
|
|
if (actor->_passValue != 1)
|
|
actor->_counter--;
|
|
switch (lastDir) {
|
|
case 0:
|
|
case 2:
|
|
y1 -= 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
setRandomDirFl = true;
|
|
break;
|
|
case 1:
|
|
case 3:
|
|
y1 += 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
setRandomDirFl = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
setRandomDirFl = true;
|
|
|
|
if (setRandomDirFl) {
|
|
actor->_counter = g_events->getRandomNumber(10, 99);
|
|
lastDir = g_events->getRandomNumber(1);
|
|
}
|
|
|
|
if (lastDir > 1)
|
|
lastDir -= 2;
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = lastDir;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return lastDir;
|
|
}
|
|
|
|
// Horizontal only (bats)
|
|
int movementEleven(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
if (checkMove2(actor->_x - 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 1;
|
|
if (checkMove2(actor->_x - 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 2;
|
|
break;
|
|
|
|
case 1:
|
|
if (checkMove2(actor->_x - 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 0;
|
|
if (checkMove2(actor->_x - 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 3;
|
|
break;
|
|
|
|
case 2:
|
|
if (checkMove2(actor->_x + 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 3;
|
|
if (checkMove2(actor->_x + 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 0;
|
|
break;
|
|
|
|
case 3:
|
|
if (checkMove2(actor->_x + 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 2;
|
|
if (checkMove2(actor->_x + 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Horizontal straight until bump
|
|
int movementTwelve(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
case 2:
|
|
if (checkMove2(actor->_x - 2, actor->_y, actor))
|
|
break;
|
|
d = 3;
|
|
break;
|
|
|
|
case 1:
|
|
case 3:
|
|
if (checkMove2(actor->_x + 2, actor->_y, actor))
|
|
break;
|
|
d = 2;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Pause-seek (mushroom)
|
|
int movementThirteen(Actor *actor) {
|
|
const int d = actor->_lastDir;
|
|
|
|
if (actor->_counter == 0 && actor->_unpauseCountdown == 0) {
|
|
actor->_unpauseCountdown = 60;
|
|
return d;
|
|
}
|
|
if (actor->_unpauseCountdown > 0) {
|
|
actor->_unpauseCountdown--;
|
|
if (!actor->_unpauseCountdown)
|
|
actor->_counter = 60;
|
|
actor->_vulnerableCountdown = 5;
|
|
actor->_hitStrength = 0;
|
|
return d;
|
|
}
|
|
if (actor->_counter > 0) {
|
|
actor->_counter--;
|
|
if (!actor->_counter)
|
|
actor->_unpauseCountdown = 60;
|
|
actor->_hitStrength = 10;
|
|
return movementFive(actor);
|
|
}
|
|
return d;
|
|
}
|
|
|
|
// Move-bump-stop (boulder)
|
|
int movementFourteen(Actor *actor) {
|
|
const int d = actor->_lastDir;
|
|
actor->_dir = d;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
actor->_moveType = 15;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
actor->_moveType = 15;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
actor->_moveType = 15;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
actor->_moveType = 15;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// No movement - no frame cycle
|
|
int movementFifteen(Actor *actor) {
|
|
return actor->_dir;
|
|
}
|
|
|
|
// Tornado 1
|
|
int movementSixteen(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!checkMove1(x1, y1, actor)) {
|
|
actor->_moveType = 17;
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Tornado 2
|
|
int movementSeventeen(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
if (checkMove1(actor->_x - 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 1;
|
|
if (checkMove1(actor->_x - 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 2;
|
|
break;
|
|
|
|
case 1:
|
|
if (checkMove1(actor->_x - 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 0;
|
|
if (checkMove1(actor->_x - 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 3;
|
|
break;
|
|
|
|
case 2:
|
|
if (checkMove1(actor->_x + 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 3;
|
|
if (checkMove1(actor->_x + 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 0;
|
|
break;
|
|
|
|
case 3:
|
|
if (checkMove1(actor->_x + 2, actor->_y + 2, actor))
|
|
break;
|
|
d = 2;
|
|
if (checkMove1(actor->_x + 2, actor->_y - 2, actor))
|
|
break;
|
|
d = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// No movement - frame cycle
|
|
int movementEighteen(Actor *actor) {
|
|
int d;
|
|
|
|
if (actor->_temp5) {
|
|
actor->_temp5--;
|
|
if (!actor->_temp5)
|
|
actor->_numMoves = 1;
|
|
}
|
|
if (actor->_temp1) {
|
|
d = movementFive(actor);
|
|
actor->_rand--;
|
|
if (actor->_hitThor || !actor->_rand) {
|
|
if (actor->_hitThor) {
|
|
actor->_temp5 = 50;
|
|
actor->_numMoves = 2;
|
|
actor->_hitThor = false;
|
|
actor->_dir = d;
|
|
d = reverseDirection(actor);
|
|
}
|
|
actor->_temp1 = 0;
|
|
actor->_rand = g_events->getRandomNumber(50, 149);
|
|
}
|
|
} else {
|
|
d = movementThree(actor);
|
|
actor->_rand--;
|
|
if (!actor->_rand) {
|
|
actor->_temp5 = 0;
|
|
actor->_temp1 = 1;
|
|
actor->_rand = g_events->getRandomNumber(50, 149);
|
|
}
|
|
if (actor->_hitThor) {
|
|
actor->_temp5 = 50;
|
|
actor->_numMoves = 2;
|
|
actor->_hitThor = false;
|
|
actor->_dir = d;
|
|
d = reverseDirection(actor);
|
|
}
|
|
}
|
|
nextFrame(actor);
|
|
return d;
|
|
}
|
|
|
|
// No movement - frame cycle
|
|
int movementNineteen(Actor *actor) {
|
|
return movementSeven(actor);
|
|
}
|
|
|
|
int movementTwenty(Actor *actor) {
|
|
if (GAME1)
|
|
// Boss - snake
|
|
return boss1Movement(actor);
|
|
|
|
return movementOne(actor);
|
|
}
|
|
|
|
// No movement - frame cycle
|
|
int movementTwentyOne(Actor *actor) {
|
|
return movementThree(actor);
|
|
}
|
|
|
|
// Spear
|
|
int movementTwentyTwo(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
if (actor->_directions == 1)
|
|
d = 0;
|
|
|
|
redo:
|
|
|
|
switch (actor->_temp2) {
|
|
case 0:
|
|
if (backgroundTile(actor->_x, actor->_y) >= TILE_SOLID)
|
|
actor->_nextFrame = 1;
|
|
else {
|
|
actor->_temp2 = 6;
|
|
actor->_temp1 = 1;
|
|
goto redo;
|
|
}
|
|
actor->_temp2++;
|
|
break;
|
|
|
|
case 1:
|
|
actor->_nextFrame = 2;
|
|
actor->_temp2++;
|
|
break;
|
|
|
|
case 2:
|
|
actor->_nextFrame = 3;
|
|
actor->_hitStrength = 255;
|
|
actor->_temp2++;
|
|
actor->_temp1 = 10;
|
|
break;
|
|
|
|
case 3:
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
actor->_temp1--;
|
|
if (actor->_temp1)
|
|
break;
|
|
actor->_temp2++;
|
|
actor->_nextFrame = 2;
|
|
break;
|
|
|
|
case 4:
|
|
actor->_hitStrength = 0;
|
|
actor->_temp2++;
|
|
actor->_nextFrame = 1;
|
|
break;
|
|
|
|
case 5:
|
|
actor->_temp2++;
|
|
actor->_nextFrame = 0;
|
|
actor->_temp1 = 10;
|
|
break;
|
|
|
|
case 6:
|
|
actor->_temp1--;
|
|
if (actor->_temp1)
|
|
break;
|
|
actor->_temp2 = 0;
|
|
actor->_nextFrame = 0;
|
|
switch (d) {
|
|
case 0:
|
|
actor->_x += 16;
|
|
actor->_y += 16;
|
|
d = 3;
|
|
if (backgroundTile(actor->_x, actor->_y) < TILE_SOLID)
|
|
goto redo;
|
|
break;
|
|
|
|
case 1:
|
|
actor->_x -= 16;
|
|
actor->_y -= 16;
|
|
d = 2;
|
|
if (backgroundTile(actor->_x, actor->_y) < TILE_SOLID)
|
|
goto redo;
|
|
break;
|
|
|
|
case 2:
|
|
actor->_x += 16;
|
|
actor->_y -= 16;
|
|
d = 0;
|
|
if (backgroundTile(actor->_x, actor->_y) < TILE_SOLID)
|
|
goto redo;
|
|
break;
|
|
|
|
case 3:
|
|
actor->_x -= 16;
|
|
actor->_y += 16;
|
|
d = 1;
|
|
if (backgroundTile(actor->_x, actor->_y) < TILE_SOLID)
|
|
goto redo;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
actor->_dir = d;
|
|
actor->_lastDir = d;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return d;
|
|
}
|
|
|
|
// Spinball counter-clockwise
|
|
int movementTwentyThree(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
nextFrame(actor);
|
|
if (actor->_passValue & 2)
|
|
actor->_numMoves = 2;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
if (backgroundTile(actor->_x - 2, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 2;
|
|
actor->_x -= 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x, actor->_y - 2) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 3;
|
|
actor->_x += 2;
|
|
} else {
|
|
d = 1;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_y -= 2;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 3;
|
|
actor->_x += 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x - 2, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 2;
|
|
actor->_x -= 2;
|
|
} else {
|
|
d = 0;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_y += 2;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) >= TILE_FLY) {
|
|
d = 1;
|
|
actor->_y += 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x - 2, actor->_y) < TILE_FLY ||
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x, actor->_y - 2) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) >= TILE_FLY) {
|
|
d = 0;
|
|
actor->_y -= 2;
|
|
} else {
|
|
d = 3;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_x -= 2;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (backgroundTile(actor->_x, actor->_y - 2) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) >= TILE_FLY) {
|
|
d = 0;
|
|
actor->_y -= 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) >= TILE_FLY) {
|
|
d = 1;
|
|
actor->_y += 2;
|
|
} else {
|
|
d = 2;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_x += 2;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Spinball clockwise
|
|
int movementTwentyFour(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
nextFrame(actor);
|
|
if (actor->_passValue & 2)
|
|
actor->_numMoves = 2;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 3;
|
|
actor->_x += 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x, actor->_y - 2) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x - 2, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 2;
|
|
actor->_x -= 2;
|
|
} else {
|
|
d = 1;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_y -= 2;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (backgroundTile(actor->_x - 2, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 2;
|
|
actor->_x -= 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) >= TILE_FLY) {
|
|
d = 3;
|
|
actor->_x += 2;
|
|
} else {
|
|
d = 0;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_y += 2;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (backgroundTile(actor->_x, actor->_y - 2) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) >= TILE_FLY) {
|
|
d = 0;
|
|
actor->_y -= 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x - 2, actor->_y) < TILE_FLY ||
|
|
backgroundTile(actor->_x - 2, actor->_y + actor->_sizeY - 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) >= TILE_FLY) {
|
|
d = 1;
|
|
actor->_y += 2;
|
|
} else {
|
|
d = 3;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_x -= 2;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (backgroundTile(actor->_x, actor->_y + actor->_sizeY + 1) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y + actor->_sizeY + 1) >= TILE_FLY) {
|
|
d = 1;
|
|
actor->_y += 2;
|
|
} else {
|
|
if (backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y) < TILE_FLY ||
|
|
backgroundTile(actor->_x + actor->_sizeX + 1, actor->_y + actor->_sizeY - 1) < TILE_FLY) {
|
|
if (backgroundTile(actor->_x, actor->_y - 2) >= TILE_FLY &&
|
|
backgroundTile(actor->_x + actor->_sizeX - 1, actor->_y - 2) >= TILE_FLY) {
|
|
d = 0;
|
|
actor->_y -= 2;
|
|
} else {
|
|
d = 2;
|
|
break;
|
|
}
|
|
} else
|
|
actor->_x += 2;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
actor->_lastDir = d;
|
|
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Acid puddle
|
|
int movementTwentyFive(Actor *actor) {
|
|
if (actor->_temp2) {
|
|
actor->_temp2--;
|
|
return movementOne(actor);
|
|
}
|
|
if (!actor->_temp1) {
|
|
actor->_lastDir = g_events->getRandomNumber(3);
|
|
int i = 4;
|
|
while (i--) {
|
|
int ret = movementThree(actor);
|
|
if (ret)
|
|
return ret;
|
|
actor->_lastDir++;
|
|
if (actor->_lastDir > 3)
|
|
actor->_lastDir = 0;
|
|
}
|
|
actor->_temp1 = 16;
|
|
}
|
|
actor->_temp1--;
|
|
return movementThree(actor);
|
|
}
|
|
|
|
int movementTwentySix(Actor *actor) {
|
|
if (GAME2)
|
|
return boss2Movement(actor);
|
|
if (GAME3)
|
|
return boss3Movement(actor);
|
|
|
|
return movementOne(actor);
|
|
}
|
|
|
|
int movementTwentySeven(Actor *actor) {
|
|
if (GAME2)
|
|
return boss2Movement(actor);
|
|
|
|
return movementOne(actor);
|
|
}
|
|
|
|
void setThorVars() {
|
|
_G(thorX1) = _G(thor)->_x + 1;
|
|
_G(thorY1) = _G(thor)->_y + 8;
|
|
|
|
_G(thorRealY1) = _G(thor)->_y;
|
|
_G(thorX2) = (_G(thor)->_x + 12);
|
|
_G(thorY2) = _G(thor)->_y + 15;
|
|
}
|
|
|
|
// Fish
|
|
int movementTwentyEight(Actor *actor) {
|
|
const int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
int ret;
|
|
|
|
if (actor->_i1)
|
|
actor->_i1--;
|
|
else {
|
|
if (!actor->_temp3) {
|
|
if (!actor->_nextFrame) {
|
|
actor->_frameCount = 1;
|
|
actor->_frameSpeed = 4;
|
|
}
|
|
|
|
nextFrame(actor);
|
|
if (actor->_nextFrame == 3) {
|
|
if (actor->_currNumShots < actor->_numShotsAllowed)
|
|
actorShoots(actor, 0);
|
|
actor->_temp3 = 1;
|
|
}
|
|
} else {
|
|
const int fcount = actor->_frameCount - 1;
|
|
if (fcount <= 0) {
|
|
actor->_nextFrame--;
|
|
actor->_frameCount = actor->_frameSpeed;
|
|
if (!actor->_nextFrame) {
|
|
actor->_temp3 = 0;
|
|
actor->_frameSpeed = 4;
|
|
actor->_i1 = g_events->getRandomNumber(60, 159);
|
|
}
|
|
} else
|
|
actor->_frameCount = fcount;
|
|
}
|
|
goto done;
|
|
}
|
|
switch (actor->_temp2) {
|
|
case 0:
|
|
y1 -= 2;
|
|
break;
|
|
case 1:
|
|
y1 += 2;
|
|
break;
|
|
case 2:
|
|
x1 -= 2;
|
|
break;
|
|
case 3:
|
|
x1 += 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ret = backgroundTile(x1, y1);
|
|
if (ret != 100 && ret != 106 && ret != 110 && ret != 111 && ret != 113)
|
|
goto chg_dir;
|
|
ret = backgroundTile((x1 + actor->_sizeX) - 1, y1);
|
|
if (ret != 100 && ret != 106 && ret != 110 && ret != 111 && ret != 113)
|
|
goto chg_dir;
|
|
ret = backgroundTile(x1, (y1 + actor->_sizeY) - 1);
|
|
if (ret != 100 && ret != 106 && ret != 110 && ret != 111 && ret != 113)
|
|
goto chg_dir;
|
|
ret = backgroundTile((x1 + actor->_sizeX) - 1, (y1 + actor->_sizeY) - 1);
|
|
if (ret != 100 && ret != 106 && ret != 110 && ret != 111 && ret != 113)
|
|
goto chg_dir;
|
|
|
|
actor->_x = x1;
|
|
actor->_y = y1;
|
|
|
|
goto done;
|
|
|
|
chg_dir:
|
|
actor->_temp2 = _G(rand1) % 4;
|
|
|
|
done:
|
|
if (actor->_nextFrame) {
|
|
x1 = actor->_x;
|
|
y1 = actor->_y;
|
|
actor->_solid = 1;
|
|
checkMove2(x1, y1, actor);
|
|
actor->_x = x1;
|
|
actor->_y = y1;
|
|
} else
|
|
actor->_solid = 2;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Horizontal or vertical (pass_val)
|
|
int movementTwentyNine(Actor *actor) {
|
|
if (!actor->_passValue)
|
|
return movementThirty(actor);
|
|
|
|
return movementTwelve(actor);
|
|
}
|
|
|
|
// Vertical straight
|
|
int movementThirty(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
const int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
break;
|
|
case 1:
|
|
y1 += 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (!checkMove2(x1, y1, actor))
|
|
d ^= 1;
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Drop (stalagtite)
|
|
int movementThirtyOne(Actor *actor) {
|
|
const int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
if (actor->_temp1) {
|
|
y1 += 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
actorDestroyed(actor);
|
|
} else if (_G(thorY1) > y1 && ABS(x1 - _G(thorX1)) < 16) {
|
|
const int cx = (actor->_x + (actor->_sizeX / 2)) >> 4;
|
|
const int cy = ((actor->_y + actor->_sizeY) - 2) >> 4;
|
|
const int ty = _G(thor)->_centerY;
|
|
for (int i = cy; i <= ty; i++)
|
|
if (_G(scrn)._iconGrid[i][cx] < TILE_SOLID)
|
|
goto done;
|
|
actor->_numMoves = actor->_passValue + 1;
|
|
actor->_temp1 = 1;
|
|
}
|
|
|
|
done:
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Unused
|
|
int movementThirtyTwo(Actor *actor) {
|
|
return 0;
|
|
}
|
|
|
|
// Unused
|
|
int movementThirtyThree(Actor *actor) {
|
|
return 0;
|
|
}
|
|
|
|
// Unused
|
|
int movementThirtyFour(Actor *actor) {
|
|
return 0;
|
|
}
|
|
|
|
// Gun (single)
|
|
int movementThirtyFive(Actor *actor) {
|
|
actor->_nextFrame = actor->_lastDir;
|
|
return actor->_dir;
|
|
}
|
|
|
|
// Acid drop
|
|
int movementThirtySix(Actor *actor) {
|
|
actor->_speed = actor->_passValue;
|
|
nextFrame(actor);
|
|
if (actor->_nextFrame == 0 && actor->_frameCount == actor->_frameSpeed) {
|
|
actorAlwaysShoots(actor, 1);
|
|
_G(actor[actor->_shotActor])._x -= 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// 4-way straight (random length) change
|
|
int movementThirtySeven(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
bool check = false;
|
|
if (actor->_counter) {
|
|
actor->_counter--;
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
check = true;
|
|
break;
|
|
|
|
case 1:
|
|
y1 += 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
check = true;
|
|
break;
|
|
|
|
case 2:
|
|
x1 -= 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
check = true;
|
|
break;
|
|
|
|
case 3:
|
|
x1 += 2;
|
|
if (!checkMove2(x1, y1, actor))
|
|
check = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} else
|
|
check = true;
|
|
|
|
if (check) {
|
|
actor->_counter = g_events->getRandomNumber(10, 99);
|
|
d = g_events->getRandomNumber(3);
|
|
}
|
|
|
|
nextFrame(actor);
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Timed darting
|
|
#define TIMER actor->_i1
|
|
#define INIT_DIR actor->_temp1
|
|
#define OTHER_DIR actor->_temp2
|
|
#define FLAG actor->_temp3
|
|
#define OX actor->_i2
|
|
#define OY actor->_i3
|
|
#define CNT actor->_i4
|
|
int movementThirtyEight(Actor *actor) {
|
|
int d = actor->_lastDir;
|
|
int x1 = actor->_x;
|
|
int y1 = actor->_y;
|
|
|
|
if (!FLAG) {
|
|
FLAG = 1;
|
|
if (actor->_passValue)
|
|
TIMER = actor->_passValue * 15;
|
|
else
|
|
TIMER = g_events->getRandomNumber(5, 364);
|
|
INIT_DIR = actor->_lastDir;
|
|
OX = x1;
|
|
OY = y1;
|
|
CNT = 0;
|
|
switch (INIT_DIR) {
|
|
case 0:
|
|
OTHER_DIR = 1;
|
|
break;
|
|
case 1:
|
|
OTHER_DIR = 0;
|
|
break;
|
|
case 2:
|
|
OTHER_DIR = 3;
|
|
break;
|
|
case 3:
|
|
OTHER_DIR = 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (TIMER) {
|
|
TIMER--;
|
|
goto done;
|
|
}
|
|
|
|
switch (d) {
|
|
case 0:
|
|
y1 -= 2;
|
|
break;
|
|
case 1:
|
|
y1 += 2;
|
|
break;
|
|
case 2:
|
|
x1 -= 2;
|
|
break;
|
|
case 3:
|
|
x1 += 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (FLAG) {
|
|
case 1:
|
|
if (!checkMove2(x1, y1, actor)) {
|
|
if (CNT) {
|
|
d = OTHER_DIR;
|
|
actor->_lastDir = d;
|
|
FLAG = 2;
|
|
} else {
|
|
actor->_nextFrame = 0;
|
|
FLAG = 0;
|
|
goto done;
|
|
}
|
|
} else
|
|
CNT++;
|
|
break;
|
|
|
|
case 2:
|
|
checkMove2(x1, y1, actor);
|
|
if (x1 == OX && y1 == OY) {
|
|
FLAG = 0;
|
|
d = INIT_DIR;
|
|
actor->_lastDir = d;
|
|
actor->_nextFrame = 0;
|
|
goto done;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
nextFrame(actor);
|
|
|
|
done:
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
// Troll 1
|
|
int movementThirtyNine(Actor *actor) {
|
|
if (_G(setup)._difficultyLevel == 0) {
|
|
actor->_speed = 3;
|
|
actor->_numMoves = 1;
|
|
} else if (_G(setup)._difficultyLevel == 1) {
|
|
actor->_speed = 2;
|
|
actor->_numMoves = 1;
|
|
} else if (_G(setup)._difficultyLevel == 2) {
|
|
actor->_speed = 1;
|
|
actor->_numMoves = 1;
|
|
}
|
|
|
|
if (actor->_passValue < 5)
|
|
return movementForty(actor);
|
|
|
|
if (actor->_passValue == 10) {
|
|
if (overlap(actor->_x + 1, actor->_y + 1, actor->_x + actor->_sizeX - 1,
|
|
actor->_y + actor->_sizeY - 1, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
|
actor->_hitStrength = 255;
|
|
thorDamaged(actor);
|
|
}
|
|
return actor->_dir;
|
|
}
|
|
if (actor->_actorNum != 3)
|
|
return actor->_dir;
|
|
|
|
if (actor->_i1) {
|
|
actor->_i1--;
|
|
actor->_x -= 2;
|
|
checkMove2(actor->_x, actor->_y, actor);
|
|
_G(actor[4])._x -= 2;
|
|
_G(actor[5])._x -= 2;
|
|
_G(actor[6])._x -= 2;
|
|
}
|
|
nextFrame(actor);
|
|
if (actor->_nextFrame == 3)
|
|
actor->_nextFrame = 0;
|
|
_G(actor[4])._nextFrame = _G(actor[3])._nextFrame;
|
|
_G(actor[5])._nextFrame = 0;
|
|
_G(actor[6])._nextFrame = 0;
|
|
return actor->_dir;
|
|
}
|
|
|
|
// Troll 2
|
|
int movementForty(Actor *actor) {
|
|
if (overlap(actor->_x + 1, actor->_y + 1, actor->_x + actor->_sizeX + 3,
|
|
actor->_y + actor->_sizeY - 1, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
|
actor->_hitStrength = 150;
|
|
thorDamaged(actor);
|
|
}
|
|
int a = 5 + (actor->_passValue * 4);
|
|
const int x1 = actor->_x;
|
|
int d = actor->_lastDir;
|
|
|
|
if (actor->_lastDir == 2) {
|
|
if (backgroundTile(x1 - 2, actor->_y) >= TILE_SOLID) {
|
|
_G(actor[a]._x) -= 2;
|
|
_G(actor[a - 1])._x -= 2;
|
|
_G(actor[a - 2])._x -= 2;
|
|
_G(actor[a + 1])._x -= 2;
|
|
} else
|
|
d = 3;
|
|
} else if (backgroundTile(_G(actor[a + 1])._x + 14, _G(actor[a + 1])._y) >= TILE_SOLID) {
|
|
_G(actor[a])._x += 2;
|
|
_G(actor[a - 1])._x += 2;
|
|
_G(actor[a - 2])._x += 2;
|
|
_G(actor[a + 1])._x += 2;
|
|
} else
|
|
d = 2;
|
|
|
|
if (actor->_nextFrame == 3 && !actor->_currNumShots && actor->_frameCount == actor->_frameSpeed) {
|
|
actorAlwaysShoots(actor, 1);
|
|
_G(actor[actor->_shotActor])._x += 6;
|
|
}
|
|
|
|
nextFrame(actor);
|
|
_G(actor[a - 2])._nextFrame = actor->_nextFrame;
|
|
_G(actor[a - 1])._nextFrame = actor->_nextFrame;
|
|
_G(actor[a + 1])._nextFrame = actor->_nextFrame;
|
|
_G(actor[a - 2])._lastDir = d;
|
|
_G(actor[a - 1])._lastDir = d;
|
|
_G(actor[a + 1])._lastDir = d;
|
|
actor->_lastDir = d;
|
|
if (actor->_directions == 1)
|
|
return 0;
|
|
return d;
|
|
}
|
|
|
|
} // namespace Got
|