Initial commit
This commit is contained in:
334
engines/got/game/back.cpp
Normal file
334
engines/got/game/back.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
/* 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/back.h"
|
||||
#include "common/file.h"
|
||||
#include "got/events.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/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
const char *OBJECT_NAMES[] = {
|
||||
"Shrub", "Child's Doll", "UNUSED", "FUTURE",
|
||||
"FUTURE", "FUTURE", "FUTURE", "FUTURE", "FUTURE",
|
||||
"FUTURE", "FUTURE", "FUTURE", "FUTURE", "FUTURE",
|
||||
"FUTURE"};
|
||||
const char *ITEM_NAMES[] = {
|
||||
"Enchanted Apple", "Lightning Power",
|
||||
"Winged Boots", "Wind Power",
|
||||
"Amulet of Protection", "Thunder Power"};
|
||||
|
||||
static const char *odinEndMessage;
|
||||
|
||||
void showLevel(const int newLevel) {
|
||||
if (_G(area) == 2 && newLevel == 105) { // Shovel Maze
|
||||
_G(thorInfo)._armor = 2; // eyeballs mode
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 1;
|
||||
} else if (_G(eyeballs) == 1) {
|
||||
_G(setup).f25 = 0;
|
||||
_G(thorInfo)._armor = 1;
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 0;
|
||||
}
|
||||
|
||||
_G(bossActive) = false;
|
||||
if (!_G(shieldOn))
|
||||
_G(actor[2])._active = false;
|
||||
_G(slipping) = false;
|
||||
|
||||
if (_G(scrn)._iconGrid[_G(thor)->_centerY][_G(thor)->_centerX] == 154)
|
||||
_G(thor)->_dir = 0;
|
||||
|
||||
// The original copied 130 bytes from _G(scrn).static_object onwards into sd_data.
|
||||
// This doesn't make sense, because that would put the ending in the middle of _staticY.
|
||||
// Plus, it follows with an entire copy of scrn into sd_data anyway, so the first
|
||||
// move seems entirely redundant.
|
||||
_G(scrn).save(_G(currentLevel));
|
||||
_G(scrn).load(_G(newLevel));
|
||||
|
||||
_G(levelMusic) = _G(scrn)._music;
|
||||
|
||||
_G(thor)->_nextFrame = 0;
|
||||
|
||||
showObjects();
|
||||
showEnemies();
|
||||
|
||||
// The original was probably shortly displaying Thor in direction 0 before switching back to its prior position.
|
||||
// This behavior wasn't noticed during initial playthrough by Dreammaster - Warning has been added so it can be checked eventually.
|
||||
if (_G(scrn)._iconGrid[_G(thor)->_centerY][_G(thor)->_centerX] == 154)
|
||||
warning("showLevel - Potential short move missing");
|
||||
|
||||
if (_G(warpFlag))
|
||||
_G(currentLevel) = newLevel - 5; // Force phase
|
||||
_G(warpFlag) = false;
|
||||
|
||||
if (_G(warpScroll)) {
|
||||
_G(warpScroll) = false;
|
||||
if (_G(thor)->_dir == 0)
|
||||
_G(currentLevel) = newLevel + 10;
|
||||
else if (_G(thor)->_dir == 1)
|
||||
_G(currentLevel) = newLevel - 10;
|
||||
else if (_G(thor)->_dir == 2)
|
||||
_G(currentLevel) = newLevel + 1;
|
||||
else if (_G(thor)->_dir == 3)
|
||||
_G(currentLevel) = newLevel - 1;
|
||||
}
|
||||
|
||||
if (!_G(setup)._scrollFlag)
|
||||
_G(currentLevel) = newLevel; // Force no scroll
|
||||
|
||||
switch (_G(newLevel) - _G(currentLevel)) {
|
||||
case 0:
|
||||
// Nothing to do
|
||||
showLevelDone();
|
||||
break;
|
||||
case -1:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_LEFT;
|
||||
break;
|
||||
case 1:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_RIGHT;
|
||||
break;
|
||||
case -10:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_UP;
|
||||
break;
|
||||
case 10:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_DOWN;
|
||||
break;
|
||||
default:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_PHASED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void showLevelDone() {
|
||||
_G(currentLevel) = _G(newLevel);
|
||||
|
||||
_G(thorInfo)._lastHealth = _G(thor)->_health;
|
||||
_G(thorInfo)._lastMagic = _G(thorInfo)._magic;
|
||||
_G(thorInfo)._lastJewels = _G(thorInfo)._jewels;
|
||||
_G(thorInfo)._lastKeys = _G(thorInfo)._keys;
|
||||
_G(thorInfo)._lastScore = _G(thorInfo)._score;
|
||||
_G(thorInfo)._lastItem = _G(thorInfo)._selectedItem;
|
||||
_G(thorInfo)._lastScreen = _G(currentLevel);
|
||||
_G(thorInfo)._lastIcon = ((_G(thor)->_x + 8) / 16) + (((_G(thor)->_y + 14) / 16) * 20);
|
||||
_G(thorInfo)._lastDir = _G(thor)->_dir;
|
||||
_G(thorInfo)._lastInventory = _G(thorInfo)._inventory;
|
||||
_G(thorInfo)._lastObject = _G(thorInfo)._object;
|
||||
_G(thorInfo)._lastObjectName = _G(thorInfo)._objectName;
|
||||
|
||||
_G(lastSetup) = _G(setup);
|
||||
|
||||
bool f = true;
|
||||
if (GAME1 && _G(newLevel) == BOSS_LEVEL1 && !_G(setup)._bossDead[0]) {
|
||||
boss1SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (GAME2 && _G(newLevel) == BOSS_LEVEL2 && !_G(setup)._bossDead[1]) {
|
||||
boss2SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (GAME3) {
|
||||
if (_G(newLevel) == BOSS_LEVEL3 && !_G(setup)._bossDead[2]) {
|
||||
boss3SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (_G(currentLevel) == ENDING_SCREEN) {
|
||||
endingScreen();
|
||||
f = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_G(startup))
|
||||
f = false;
|
||||
|
||||
if (f)
|
||||
musicPlay(_G(levelMusic), false);
|
||||
}
|
||||
|
||||
static void odin_speaks_end() {
|
||||
// In case Thor is now dead, flag as such
|
||||
if (!_G(thor)->_health) {
|
||||
_G(thor)->_show = 0;
|
||||
_G(exitFlag) = 2;
|
||||
}
|
||||
|
||||
// If there's an end message, pass it on to the view hierarchy.
|
||||
// This is used in cases like the game end where multiple
|
||||
// odinSpeaks are done in sequence
|
||||
if (odinEndMessage)
|
||||
g_events->send(GameMessage(odinEndMessage));
|
||||
}
|
||||
|
||||
void odinSpeaks(const int index, int item, const char *endMessage) {
|
||||
odinEndMessage = endMessage;
|
||||
|
||||
executeScript((long)index, _G(odin), odin_speaks_end);
|
||||
}
|
||||
|
||||
int switchIcons() {
|
||||
playSound(WOOP, false);
|
||||
|
||||
for (int y = 0; y < 12; y++) {
|
||||
for (int x = 0; x < 20; x++) {
|
||||
const int ix = x * 16;
|
||||
const int iy = y * 16;
|
||||
if (_G(scrn)._iconGrid[y][x] == 93) {
|
||||
placeTile(x, y, 144);
|
||||
} else if (_G(scrn)._iconGrid[y][x] == 144) {
|
||||
placeTile(x, y, 93);
|
||||
killEnemies(iy, ix);
|
||||
}
|
||||
|
||||
if (_G(scrn)._iconGrid[y][x] == 94) {
|
||||
placeTile(x, y, 146);
|
||||
} else if (_G(scrn)._iconGrid[y][x] == 146) {
|
||||
placeTile(x, y, 94);
|
||||
killEnemies(iy, ix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rotateArrows() {
|
||||
playSound(WOOP, false);
|
||||
|
||||
for (int y = 0; y < 12; y++) {
|
||||
for (int x = 0; x < 20; x++) {
|
||||
if (_G(scrn)._iconGrid[y][x] == 205)
|
||||
placeTile(x, y, 208);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 206)
|
||||
placeTile(x, y, 207);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 207)
|
||||
placeTile(x, y, 205);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 208)
|
||||
placeTile(x, y, 206);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void killEnemies(const int iy, const int ix) {
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
for (int i = 3; i < MAX_ACTORS; i++) {
|
||||
if (_G(actor[i])._active) {
|
||||
x1 = _G(actor[i])._x;
|
||||
y1 = _G(actor[i])._y + _G(actor[i])._sizeY - 2;
|
||||
x2 = (_G(actor[i])._x + _G(actor[i])._sizeX);
|
||||
y2 = _G(actor[i])._y + _G(actor[i])._sizeY - 1;
|
||||
|
||||
if (pointWithin(x1, y1, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y1, ix, iy, ix + 15, iy + 15)
|
||||
|| pointWithin(x1, y2, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y2, ix, iy, ix + 15, iy + 15))
|
||||
actorDestroyed(&_G(actor[i]));
|
||||
}
|
||||
}
|
||||
|
||||
x1 = _G(thor)->_x;
|
||||
y1 = _G(thor)->_y + 11;
|
||||
x2 = x1 + 13;
|
||||
y2 = y1 + 5;
|
||||
|
||||
if (pointWithin(x1, y1, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y1, ix, iy, ix + 15, iy + 15)
|
||||
|| pointWithin(x1, y2, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y2, ix, iy, ix + 15, iy + 15)) {
|
||||
if (!_G(cheats)._freezeHealth) {
|
||||
_G(thor)->_health = 0;
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeObjects(const int y, const int x) {
|
||||
const int p = (y * 20) + x;
|
||||
|
||||
if (_G(objectMap[p]) > 0) {
|
||||
_G(objectMap[p]) = 0;
|
||||
_G(objectIndex[p]) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void placeTile(const int x, const int y, const int tile) {
|
||||
_G(scrn)._iconGrid[y][x] = tile;
|
||||
removeObjects(y, x);
|
||||
}
|
||||
|
||||
int backgroundTile(int x, int y) {
|
||||
if (x < 0 || x >= 319 || y < 0 || y >= 191)
|
||||
return 0;
|
||||
|
||||
x = (x + 1) >> 4;
|
||||
y = (y + 1) >> 4;
|
||||
|
||||
return _G(scrn)._iconGrid[y][x];
|
||||
}
|
||||
|
||||
void selectItem() {
|
||||
// Only allow opening the dialog if something isn't currently going on
|
||||
if (g_engine->canSaveAutosaveCurrently()) {
|
||||
g_events->addView("SelectItem");
|
||||
}
|
||||
}
|
||||
|
||||
void actorSpeaks(const Actor *actor, int index, int item) {
|
||||
if (actor->_type != 4)
|
||||
return;
|
||||
|
||||
const int v = atoi(actor->_name);
|
||||
if (v < 1 || v > 20)
|
||||
return;
|
||||
|
||||
long lind = (long)_G(currentLevel);
|
||||
lind = lind * 1000;
|
||||
lind += (long)actor->_actorNum;
|
||||
|
||||
const Common::String str = Common::String::format("FACE%d", v);
|
||||
if (Common::File::exists(Common::Path(str))) {
|
||||
Gfx::Pics pics(str, 262);
|
||||
executeScript(lind, pics);
|
||||
} else {
|
||||
executeScript(lind, _G(odin));
|
||||
}
|
||||
|
||||
if (!_G(thor)->_health) {
|
||||
_G(thor)->_show = 0;
|
||||
_G(exitFlag) = 2;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
52
engines/got/game/back.h
Normal file
52
engines/got/game/back.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_BACK_H
|
||||
#define GOT_GAME_BACK_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern const char *OBJECT_NAMES[];
|
||||
extern const char *ITEM_NAMES[];
|
||||
|
||||
/**
|
||||
* Shows a new level
|
||||
* In the original this did some initial actors setup and rendering.
|
||||
* Now in ScummVM, it only does the setup portions, since the
|
||||
* GameContent view takes care of the scene rendering.
|
||||
*/
|
||||
extern void showLevel(int newLevel);
|
||||
extern void showLevelDone();
|
||||
extern void odinSpeaks(int index, int item, const char *endMessage = nullptr);
|
||||
extern int switchIcons();
|
||||
extern int rotateArrows();
|
||||
extern void killEnemies(int iy, int ix);
|
||||
extern void removeObjects(int y, int x);
|
||||
extern void placeTile(int x, int y, int tile);
|
||||
extern int backgroundTile(int x, int y);
|
||||
extern void selectItem();
|
||||
extern void actorSpeaks(const Actor *actor, int index, int item);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
298
engines/got/game/boss1.cpp
Normal file
298
engines/got/game/boss1.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/* 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/boss1.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static int boss1_dead();
|
||||
|
||||
int boss1Movement(Actor *actor) {
|
||||
bool f = false;
|
||||
|
||||
if (_G(bossDead))
|
||||
return boss1_dead();
|
||||
|
||||
int d = actor->_lastDir;
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (actor->_edgeCounter) {
|
||||
actor->_edgeCounter--;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 30, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
|
||||
if (actor->_temp3) { //start striking
|
||||
actor->_temp3--;
|
||||
if (!actor->_temp3)
|
||||
playSound(BOSS11, false);
|
||||
|
||||
actor->_numMoves = 6;
|
||||
|
||||
goto done0;
|
||||
}
|
||||
|
||||
// Strike
|
||||
if (actor->_temp1) {
|
||||
actor->_temp1--;
|
||||
if (actor->_x < (_G(thorX1) + 12))
|
||||
actor->_temp1 = 0;
|
||||
actor->_temp2 = 1;
|
||||
d = 2;
|
||||
actor->_x -= 2;
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 32, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
actor->_temp1 = 0;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
actor->_nextFrame = 3;
|
||||
actor->_numMoves = _G(setup)._difficultyLevel + 2;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp2) { // Retreating
|
||||
if (actor->_x < 256) {
|
||||
d = 3;
|
||||
actor->_x += 2;
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 32, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
goto done1;
|
||||
}
|
||||
actor->_numMoves = _G(setup)._difficultyLevel + 1;
|
||||
goto done0;
|
||||
}
|
||||
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
|
||||
if (actor->_x > _G(thorX1) && ABS((_G(thorY1)) - (actor->_y + 20)) < 8) {
|
||||
actor->_temp3 = 75;
|
||||
actor->_temp1 = 130;
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
|
||||
if (actor->_counter) {
|
||||
actor->_counter--;
|
||||
switch (d) {
|
||||
case 1:
|
||||
case 3:
|
||||
x1 = _G(actor[5])._x;
|
||||
y1 = _G(actor[5])._y;
|
||||
y1 += 2;
|
||||
|
||||
if (!checkMove2(x1, y1, &_G(actor[5])))
|
||||
f = true;
|
||||
else {
|
||||
actor->_x = _G(actor[5])._x;
|
||||
actor->_y = _G(actor[5])._y - 16;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 2:
|
||||
y1 -= 2;
|
||||
if (!checkMove2(x1, y1, actor))
|
||||
f = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
f = true;
|
||||
|
||||
if (f) {
|
||||
actor->_counter = g_events->getRandomNumber(10, 99);
|
||||
d = g_events->getRandomNumber(1);
|
||||
actor->_edgeCounter = 20;
|
||||
}
|
||||
|
||||
done:
|
||||
if (d > 1)
|
||||
d -= 2;
|
||||
|
||||
done0:
|
||||
nextFrame(actor);
|
||||
if (actor->_nextFrame == 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
done1:
|
||||
actor->_lastDir = d;
|
||||
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
|
||||
_G(actor[4])._lastDir = d;
|
||||
_G(actor[5])._lastDir = d;
|
||||
_G(actor[6])._lastDir = d;
|
||||
|
||||
_G(actor[4])._x = actor->_x + 16;
|
||||
_G(actor[4])._y = actor->_y;
|
||||
_G(actor[5])._x = actor->_x;
|
||||
_G(actor[5])._y = actor->_y + 16;
|
||||
_G(actor[6])._x = actor->_x + 16;
|
||||
_G(actor[6])._y = actor->_y + 16;
|
||||
_G(actor[4])._numMoves = actor->_numMoves;
|
||||
_G(actor[5])._numMoves = actor->_numMoves;
|
||||
_G(actor[6])._numMoves = actor->_numMoves;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
void boss1CheckHit(const Actor *actor, const int x1, const int y1, const int x2, const int y2, const int actorNum) {
|
||||
if (actor->_moveType == 15 && actorNum == 4) {
|
||||
if ((!_G(actor[3])._vulnerableCountdown) && (_G(actor[3])._nextFrame != 3) &&
|
||||
overlap(x1, y1, x2, y2, actor->_x + 6, actor->_y + 4, actor->_x + 14, actor->_y + 20)) {
|
||||
actorDamaged(&_G(actor[3]), _G(hammer)->_hitStrength);
|
||||
if (_G(cheat) && _G(keyFlag[GOT_Z]))
|
||||
_G(actor[3])._health = 0;
|
||||
else
|
||||
_G(actor[3])._health -= 10;
|
||||
|
||||
_G(actor[3])._moveCountdown = 50;
|
||||
_G(actor[3])._vulnerableCountdown = 100;
|
||||
playSound(BOSS13, true);
|
||||
_G(actor[3])._nextFrame = 1;
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0)
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void boss1SetupLevel() {
|
||||
setupBoss(1);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
musicPlay(5, true);
|
||||
}
|
||||
|
||||
static int boss1_dead() {
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
void boss1ClosingSequence1() {
|
||||
_G(gameOver) = true;
|
||||
musicPlay(4, true);
|
||||
odinSpeaks(1001, 13, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence2() {
|
||||
_G(thorInfo)._armor = 1;
|
||||
loadNewThor();
|
||||
_G(thor)->_dir = 1;
|
||||
_G(thor)->_nextFrame = 0;
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
odinSpeaks(1002, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence4() {
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[0] = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 4;
|
||||
showLevel(BOSS_LEVEL1);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
playSound(ANGEL, true);
|
||||
placeTile(18, 6, 148);
|
||||
placeTile(19, 6, 202);
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
|
||||
Level lvl;
|
||||
lvl.load(59);
|
||||
lvl._iconGrid[6][18] = 148;
|
||||
lvl._iconGrid[6][19] = 202;
|
||||
lvl.save(59);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss1.h
Normal file
40
engines/got/game/boss1.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_BOSS1_H
|
||||
#define GOT_GAME_BOSS1_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 1 - Snake (Jormangund)
|
||||
extern int boss1Movement(Actor *actor);
|
||||
extern void boss1CheckHit(const Actor *actor, int x1, int y1, int x2, int y2, int actorNum);
|
||||
extern void boss1SetupLevel();
|
||||
extern void boss1ClosingSequence1();
|
||||
extern void boss1ClosingSequence2();
|
||||
extern void boss1ClosingSequence3();
|
||||
extern void boss1ClosingSequence4();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
436
engines/got/game/boss2.cpp
Normal file
436
engines/got/game/boss2.cpp
Normal file
@@ -0,0 +1,436 @@
|
||||
/* 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/boss2.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const byte EXPLOSION[] = {
|
||||
61, 62, 65, 66, 69, 70, 73, 74, 77, 78,
|
||||
81, 82, 85, 86, 89, 90, 93, 94, 97, 98,
|
||||
101, 102, 105, 106, 109, 110, 113, 114, 117, 118,
|
||||
121, 122, 125, 126, 129, 130, 133, 134, 137, 138,
|
||||
141, 142, 145, 146, 149, 150, 153, 154, 157, 158,
|
||||
161, 162, 165, 166, 169, 170, 173, 174, 177, 178
|
||||
};
|
||||
|
||||
static bool expf[60];
|
||||
static byte numSkulls;
|
||||
static byte numSpikes;
|
||||
static bool dropFlag;
|
||||
static byte su[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
static int boss2MovementExplode(Actor *actor);
|
||||
static int boss2MovementShake(Actor *actor);
|
||||
static int boss2Die();
|
||||
static void bossSet(byte d, int x, int y);
|
||||
|
||||
int boss2Movement(Actor *actor) {
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
numSkulls = 3;
|
||||
numSpikes = 5;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numSkulls = 6;
|
||||
numSpikes = 8;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
numSkulls = 9;
|
||||
numSpikes = 11;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (_G(bossDead))
|
||||
return boss2Die();
|
||||
|
||||
if (actor->_i1) {
|
||||
if (actor->_i1 == 1)
|
||||
return boss2MovementExplode(actor);
|
||||
|
||||
return boss2MovementShake(actor);
|
||||
}
|
||||
|
||||
byte d = actor->_lastDir;
|
||||
int x = actor->_x;
|
||||
|
||||
if (actor->_temp6)
|
||||
actor->_temp6--;
|
||||
|
||||
if (!actor->_temp6) {
|
||||
bool f = false;
|
||||
dropFlag = false;
|
||||
|
||||
if (actor->_temp5)
|
||||
actor->_temp5--;
|
||||
|
||||
if (!actor->_temp5)
|
||||
f = true;
|
||||
else {
|
||||
if (d == 2) {
|
||||
if (x > 18)
|
||||
actor->_x -= 2;
|
||||
else
|
||||
f = true;
|
||||
} else if (d == 3) {
|
||||
if (x < 272)
|
||||
actor->_x += 2;
|
||||
else
|
||||
f = true;
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
actor->_temp5 = _G(rand1) + 60;
|
||||
if (d == 2)
|
||||
d = 3;
|
||||
else
|
||||
d = 2;
|
||||
}
|
||||
}
|
||||
|
||||
const int count = actor->_frameCount - 1;
|
||||
|
||||
if (count <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = count;
|
||||
|
||||
x = actor->_x;
|
||||
if (actor->_currNumShots < numSkulls && !dropFlag) {
|
||||
if (x == 48 || x == 112 || x == 176 || x == 240) {
|
||||
dropFlag = true;
|
||||
_G(actor[3])._temp6 = 40;
|
||||
|
||||
actorAlwaysShoots(actor, 1);
|
||||
playSound(FALL, false);
|
||||
_G(actor[actor->_shotActor])._x = actor->_x + 12;
|
||||
_G(actor[actor->_shotActor])._y = actor->_y + 32;
|
||||
_G(actor[actor->_shotActor])._temp2 = 0;
|
||||
_G(actor[actor->_shotActor])._temp3 = 4;
|
||||
_G(actor[actor->_shotActor])._temp4 = 4;
|
||||
}
|
||||
}
|
||||
|
||||
bossSet(d, x, actor->_y);
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static void bossSet(const byte d, const int x, const int y) {
|
||||
_G(actor[4])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[5])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[6])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[3])._lastDir = d;
|
||||
_G(actor[4])._lastDir = d;
|
||||
_G(actor[5])._lastDir = d;
|
||||
_G(actor[6])._lastDir = d;
|
||||
_G(actor[4])._x = x + 16;
|
||||
_G(actor[4])._y = y;
|
||||
_G(actor[5])._x = x;
|
||||
_G(actor[5])._y = y + 16;
|
||||
_G(actor[6])._x = x + 16;
|
||||
_G(actor[6])._y = y + 16;
|
||||
}
|
||||
|
||||
void boss2CheckHit(Actor *actor) {
|
||||
if (!_G(actor[3])._vulnerableCountdown) {
|
||||
actorDamaged(&_G(actor[3]), _G(hammer)->_hitStrength);
|
||||
_G(actor[3])._health -= 10;
|
||||
if (_G(actor[3])._health == 50) {
|
||||
playSound(BOSS12, true);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
|
||||
_G(actor[3])._i1 = 1;
|
||||
_G(actor[3])._i2 = 0;
|
||||
memset(expf, 0, sizeof(expf));
|
||||
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
_G(actor[3])._currNumShots = 0;
|
||||
} else
|
||||
playSound(BOSS13, true);
|
||||
|
||||
_G(actor[3])._moveCountdown = 75;
|
||||
_G(actor[3])._vulnerableCountdown = 75;
|
||||
_G(actor[3])._nextFrame = 1;
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0) {
|
||||
_G(bossDead) = true;
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void boss2SetupLevel() {
|
||||
setupBoss(2);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
|
||||
dropFlag = false;
|
||||
Common::fill(su, su + 18, 0);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
musicPlay(7, true);
|
||||
}
|
||||
|
||||
static int boss2Die() {
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
// Boss - skull (explode)
|
||||
static int boss2MovementExplode(Actor *actor) {
|
||||
nextFrame(actor);
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
actor->_vulnerableCountdown = 20;
|
||||
|
||||
if (actor->_currNumShots || _G(actor[5])._currNumShots)
|
||||
return 0;
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
actorAlwaysShoots(&_G(actor[5]), 0);
|
||||
const int an = _G(actor[5])._shotActor;
|
||||
_G(actor[an])._moveType = 9;
|
||||
|
||||
int r = _G(rand1) % 60;
|
||||
while (expf[r]) {
|
||||
r++;
|
||||
if (r > 59)
|
||||
r = 0;
|
||||
}
|
||||
expf[r] = true;
|
||||
const int x = (EXPLOSION[r] % 20) * 16;
|
||||
const int y = (EXPLOSION[r] / 20) * 16;
|
||||
_G(actor[an])._x = x;
|
||||
_G(actor[an])._y = y;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(actor[3])._i2++;
|
||||
if (_G(actor[3])._i2 > 59) {
|
||||
_G(actor[3])._i1 = 2;
|
||||
_G(actor[3])._i2 = 0;
|
||||
_G(actor[3])._numMoves = 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Boss - skull - shake
|
||||
static int boss2MovementShake(Actor *actor) {
|
||||
int rep, hx;
|
||||
|
||||
if (_G(hammer)->_active && _G(hammer)->_moveType != 5) {
|
||||
hx = _G(hammer)->_x;
|
||||
const int hy = _G(hammer)->_y;
|
||||
for (rep = 7; rep < 15; rep++) {
|
||||
if (!_G(actor[rep])._active)
|
||||
continue;
|
||||
|
||||
if (overlap(hx + 1, hy + 1, hx + 10, hy + 10, _G(actor[rep])._x, _G(actor[rep])._y,
|
||||
_G(actor[rep])._x + _G(actor[rep])._sizeX - 1, _G(actor[rep])._y + _G(actor[rep])._sizeY - 1)) {
|
||||
_G(hammer)->_moveType = 5;
|
||||
_G(hammer)->_dir = reverseDirection(_G(hammer));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (actor->_i4) {
|
||||
actor->_i4--;
|
||||
if (!actor->_i4)
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
}
|
||||
if (!actor->_i2) {
|
||||
if (actor->_x < 144)
|
||||
actor->_x += 2;
|
||||
else if (actor->_x > 144)
|
||||
actor->_x -= 2;
|
||||
else {
|
||||
actor->_i2 = 1;
|
||||
actor->_i3 = 0;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if (_G(actor[4])._currNumShots)
|
||||
goto done;
|
||||
|
||||
if (!actor->_i3) {
|
||||
actor->_i3 = g_events->getRandomNumber(2, 3);
|
||||
}
|
||||
|
||||
if (actor->_i3 == 2)
|
||||
actor->_x -= 2;
|
||||
else
|
||||
actor->_x += 2;
|
||||
|
||||
if (actor->_x < 20 || actor->_x > 270) {
|
||||
_G(thunderSnakeCounter) = 100;
|
||||
actor->_i4 = 50;
|
||||
playSound(EXPLODE, true);
|
||||
actor->_i2 = 0;
|
||||
|
||||
Common::fill(su, su + 18, 0);
|
||||
actorAlwaysShoots(&_G(actor[4]), 1);
|
||||
int an = _G(actor[4])._shotActor;
|
||||
hx = (_G(thor)->_x / 16);
|
||||
_G(actor[an])._x = _G(thor)->_x; //hx*16;
|
||||
_G(actor[an])._y = g_events->getRandomNumber(15);
|
||||
|
||||
su[hx] = 1;
|
||||
_G(actor[an])._nextFrame = g_events->getRandomNumber(3);
|
||||
for (rep = 0; rep < numSpikes; rep++) {
|
||||
while (true) {
|
||||
hx = g_events->getRandomNumber(17);
|
||||
if (!su[hx])
|
||||
break;
|
||||
}
|
||||
su[hx] = 1;
|
||||
actorAlwaysShoots(&_G(actor[4]), 1);
|
||||
an = _G(actor[4])._shotActor;
|
||||
_G(actor[an])._nextFrame = g_events->getRandomNumber(3);
|
||||
_G(actor[an])._x = 16 + hx * 16;
|
||||
_G(actor[an])._y = g_events->getRandomNumber(15);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
nextFrame(actor);
|
||||
bossSet(actor->_dir, actor->_x, actor->_y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void boss2ClosingSequence1() {
|
||||
musicPlay(6, true);
|
||||
odinSpeaks(1001, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence2() {
|
||||
_G(thorInfo)._armor = 10;
|
||||
loadNewThor();
|
||||
_G(thor)->_dir = 1;
|
||||
_G(thor)->_nextFrame = 0;
|
||||
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
odinSpeaks(1002, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence4() {
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[1] = true;
|
||||
_G(gameOver) = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 6;
|
||||
|
||||
showLevel(BOSS_LEVEL2);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
playSound(ANGEL, true);
|
||||
placeTile(18, 10, 152);
|
||||
placeTile(19, 10, 202);
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
_G(actor[7])._x = 288;
|
||||
_G(actor[7])._y = 160;
|
||||
_G(actor[8])._x = 304;
|
||||
_G(actor[8])._y = 160;
|
||||
|
||||
Level lvl;
|
||||
lvl.load(BOSS_LEVEL2);
|
||||
lvl._iconGrid[6][18] = 152;
|
||||
lvl._iconGrid[6][19] = 202;
|
||||
lvl.save(BOSS_LEVEL2);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss2.h
Normal file
40
engines/got/game/boss2.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_BOSS2_H
|
||||
#define GOT_GAME_BOSS2_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 2 - Skull (Nognir)
|
||||
extern int boss2Movement(Actor *actor);
|
||||
extern void boss2CheckHit(Actor *actor);
|
||||
extern void boss2SetupLevel();
|
||||
extern void boss2ClosingSequence1();
|
||||
extern void boss2ClosingSequence2();
|
||||
extern void boss2ClosingSequence3();
|
||||
extern void boss2ClosingSequence4();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
666
engines/got/game/boss3.cpp
Normal file
666
engines/got/game/boss3.cpp
Normal file
@@ -0,0 +1,666 @@
|
||||
/* 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/boss3.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define LFC 10
|
||||
|
||||
static const byte EXPLOSION[4][8] = {
|
||||
{126, 127, 128, 129, 130, 131, 132, 133},
|
||||
{146, 147, 148, 149, 150, 151, 152, 153},
|
||||
{166, 167, 168, 169, 170, 171, 172, 173},
|
||||
{186, 187, 188, 189, 190, 191, 192, 193}
|
||||
};
|
||||
|
||||
static int bossMode;
|
||||
static int numPods1;
|
||||
static byte podSpeed;
|
||||
static bool explosionFlag[4][8];
|
||||
static byte explosionCounter;
|
||||
|
||||
static int bossDie();
|
||||
static void boss3CheckHit();
|
||||
static void bossChangeMode();
|
||||
|
||||
static void setBoss(Actor *actor) {
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
|
||||
_G(actor[4])._lastDir = actor->_dir;
|
||||
_G(actor[5])._lastDir = actor->_dir;
|
||||
_G(actor[6])._lastDir = actor->_dir;
|
||||
_G(actor[4])._dir = actor->_dir;
|
||||
_G(actor[5])._dir = actor->_dir;
|
||||
_G(actor[6])._dir = actor->_dir;
|
||||
|
||||
_G(actor[4])._x = actor->_x + 16;
|
||||
_G(actor[4])._y = actor->_y;
|
||||
_G(actor[5])._x = actor->_x;
|
||||
_G(actor[5])._y = actor->_y + 16;
|
||||
_G(actor[6])._x = actor->_x + 16;
|
||||
_G(actor[6])._y = actor->_y + 16;
|
||||
}
|
||||
|
||||
// Boss - Loki-2
|
||||
static int boss3Movement1(Actor *actor) {
|
||||
int rx, ry, i, numPods = 0;
|
||||
int fcount;
|
||||
|
||||
actor->_numMoves = 2;
|
||||
podSpeed = 2;
|
||||
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
numPods = 3;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numPods = 5;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
numPods = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!actor->_temp1) {
|
||||
// Disappear
|
||||
actor->_dir = 1;
|
||||
actor->_frameCount = LFC;
|
||||
actor->_nextFrame = 0;
|
||||
actor->_temp1 = 1;
|
||||
actor->_i6 = 1;
|
||||
actor->_solid |= 128;
|
||||
_G(actor[4])._solid |= 128;
|
||||
_G(actor[5])._solid |= 128;
|
||||
_G(actor[6])._solid |= 128;
|
||||
playSound(EXPLODE, true);
|
||||
goto done;
|
||||
}
|
||||
if (actor->_i6) {
|
||||
// Fade out
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2) {
|
||||
actor->_i6 = 0;
|
||||
actor->_temp3 = 160;
|
||||
}
|
||||
actor->_frameCount = 3;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
goto done1;
|
||||
}
|
||||
if (actor->_temp3 > 1) {
|
||||
actor->_temp3--;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp3) {
|
||||
for (i = 0; i < numPods1; i++)
|
||||
if (_G(actor[19 + i])._active)
|
||||
goto done1;
|
||||
|
||||
while (true) {
|
||||
rx = g_events->getRandomNumber(255) + 16;
|
||||
ry = g_events->getRandomNumber(143);
|
||||
if (!overlap(rx, ry, rx + 32, ry + 32, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2)))
|
||||
break;
|
||||
}
|
||||
|
||||
actor->_x = rx;
|
||||
actor->_y = ry;
|
||||
actor->_frameCount = LFC;
|
||||
actor->_temp4 = 40;
|
||||
actor->_temp3 = 0;
|
||||
playSound(EXPLODE, true);
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp4) {
|
||||
// Fade in
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame--;
|
||||
if (actor->_nextFrame > 254) {
|
||||
actor->_nextFrame = 0;
|
||||
actor->_dir = 0;
|
||||
actor->_temp4 = 0;
|
||||
actor->_temp5 = 80;
|
||||
actor->_solid &= 0x7f;
|
||||
_G(actor[4])._solid &= 0x7f;
|
||||
_G(actor[5])._solid &= 0x7f;
|
||||
_G(actor[6])._solid &= 0x7f;
|
||||
}
|
||||
|
||||
actor->_frameCount = 3;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp5) {
|
||||
// Shoot
|
||||
actor->_temp5--;
|
||||
if (actor->_temp5 == 20) {
|
||||
actor->_nextFrame = 3;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (!actor->_temp5) {
|
||||
if (_G(actor[4])._currNumShots < _G(actor[4])._numShotsAllowed) {
|
||||
actorAlwaysShoots(&_G(actor[4]), 0);
|
||||
const byte shot_actor = _G(actor[4])._shotActor;
|
||||
_G(actor[shot_actor])._numMoves = podSpeed;
|
||||
_G(actor[shot_actor])._x = actor->_x + 8;
|
||||
_G(actor[shot_actor])._y = actor->_y + 16;
|
||||
_G(actor[shot_actor])._temp5 = 0;
|
||||
for (i = 0; i < numPods; i++)
|
||||
_G(actor[20 + i]) = _G(actor[19]);
|
||||
|
||||
numPods1 = numPods;
|
||||
actor->_temp1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->_temp5 < 31)
|
||||
goto done1;
|
||||
}
|
||||
|
||||
done:
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = LFC;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
done1:
|
||||
setBoss(actor);
|
||||
return actor->_dir;
|
||||
}
|
||||
|
||||
// Boss - Loki-1
|
||||
int boss3Movement(Actor *actor) {
|
||||
int x1, y1, ox, oy;
|
||||
int fcount;
|
||||
|
||||
|
||||
if (actor->_temp2)
|
||||
actor->_temp2--;
|
||||
if (_G(bossDead))
|
||||
return bossDie();
|
||||
boss3CheckHit();
|
||||
|
||||
if (!bossMode)
|
||||
return boss3Movement1(actor);
|
||||
numPods1 = 10;
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
actor->_numMoves = 3;
|
||||
actor->_speed = 2;
|
||||
break;
|
||||
case 1:
|
||||
actor->_numMoves = 2;
|
||||
actor->_speed = 1;
|
||||
break;
|
||||
case 2:
|
||||
actor->_numMoves = 5;
|
||||
actor->_speed = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int d = actor->_lastDir;
|
||||
actor->_temp3++;
|
||||
|
||||
int f = 0;
|
||||
if (actor->_temp4) {
|
||||
actor->_temp4--;
|
||||
if (!actor->_temp4) {
|
||||
actor->_temp3 = 0;
|
||||
_G(actor[3])._frameSpeed = 4;
|
||||
_G(actor[3])._dir = 0;
|
||||
_G(actor[3])._lastDir = 0;
|
||||
_G(actor[3])._nextFrame = 3;
|
||||
_G(actor[4])._dir = 0;
|
||||
_G(actor[4])._lastDir = 0;
|
||||
_G(actor[4])._nextFrame = 3;
|
||||
}
|
||||
goto skip_move;
|
||||
}
|
||||
|
||||
if (actor->_edgeCounter)
|
||||
actor->_edgeCounter--;
|
||||
else
|
||||
goto new_dir;
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 30, actor->_y + 30, _G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
|
||||
ox = actor->_x;
|
||||
oy = actor->_y;
|
||||
switch (actor->_temp5) {
|
||||
case 0:
|
||||
x1 = _G(actor[3])._x;
|
||||
y1 = _G(actor[3])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1 + 16, y1, &_G(actor[4])))
|
||||
f = 1;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 1:
|
||||
x1 = _G(actor[5])._x;
|
||||
y1 = _G(actor[5])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[5]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1 + 16, y1, &_G(actor[6])))
|
||||
f = 1;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
case 2:
|
||||
x1 = _G(actor[3])._x - 2;
|
||||
y1 = _G(actor[3])._y;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1, y1 + 16, &_G(actor[5])))
|
||||
f = 1;
|
||||
actor->_x = ox - 2;
|
||||
break;
|
||||
case 3:
|
||||
x1 = _G(actor[4])._x + 2;
|
||||
y1 = _G(actor[4])._y;
|
||||
if (!checkMove2(x1, y1, &_G(actor[4]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1, y1 + 16, &_G(actor[6])))
|
||||
f = 1;
|
||||
actor->_x = ox + 2;
|
||||
break;
|
||||
case 4: //ul
|
||||
x1 = _G(actor[3])._x - 2;
|
||||
y1 = _G(actor[3])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox - 2;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 5:
|
||||
x1 = _G(actor[4])._x + 2;
|
||||
y1 = _G(actor[4])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[4]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox + 2;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 6:
|
||||
x1 = _G(actor[6])._x + 2;
|
||||
y1 = _G(actor[6])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[6]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox + 2;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
case 7:
|
||||
x1 = _G(actor[5])._x - 2;
|
||||
y1 = _G(actor[5])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[5]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox - 2;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = 30;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
skip_move:
|
||||
|
||||
setBoss(actor);
|
||||
if (!f)
|
||||
goto done;
|
||||
|
||||
new_dir:
|
||||
if (actor->_temp3 < 120)
|
||||
goto new_dir1;
|
||||
|
||||
_G(actor[3])._frameSpeed = 8;
|
||||
_G(actor[3])._nextFrame = 3;
|
||||
_G(actor[4])._nextFrame = 3;
|
||||
actor->_temp4 = 120;
|
||||
actorAlwaysShoots(actor, 0);
|
||||
_G(actor[actor->_shotActor])._x = actor->_x + 8;
|
||||
_G(actor[actor->_shotActor])._y = actor->_y - 8;
|
||||
_G(actor[actor->_shotActor])._temp1 = g_events->getRandomNumber(90, 189);
|
||||
_G(actor[actor->_shotActor])._temp5 = 30;
|
||||
_G(actor[actor->_shotActor])._speed = 2;
|
||||
playSound(BOSS12, true);
|
||||
|
||||
new_dir1:
|
||||
actor->_temp5 = _G(rand1) % 8;
|
||||
actor->_edgeCounter = _G(rand2) + 60;
|
||||
|
||||
done:
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
static void boss3CheckHit() {
|
||||
if (_G(actor[3])._solid & 128) {
|
||||
for (int rep = 3; rep < 7; rep++)
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
if (_G(actor[3])._magicHit || _G(actor[4])._magicHit || _G(actor[5])._magicHit || _G(actor[6])._magicHit) {
|
||||
if (!_G(actor[3])._temp2) {
|
||||
actorDamaged(&_G(actor[3]), 10);
|
||||
|
||||
if (_G(cheat) && _G(keyFlag[GOT_Z]))
|
||||
_G(actor[3])._health -= 50;
|
||||
else
|
||||
_G(actor[3])._health -= 10;
|
||||
|
||||
_G(actor[3])._moveCountdown = 50;
|
||||
|
||||
_G(actor[3])._vulnerableCountdown = 50;
|
||||
playSound(BOSS13, true);
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0) {
|
||||
_G(bossDead) = true;
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 50) {
|
||||
bossChangeMode();
|
||||
_G(actor[3])._temp1 = 0;
|
||||
_G(actor[3])._temp2 = 0;
|
||||
_G(actor[3])._temp3 = 0;
|
||||
_G(actor[3])._temp4 = 0;
|
||||
_G(actor[3])._temp5 = 0;
|
||||
_G(actor[3])._i6 = 0;
|
||||
_G(actor[3])._moveCountdown = 2;
|
||||
} else {
|
||||
_G(actor[3])._temp2 = 40;
|
||||
}
|
||||
}
|
||||
for (int rep = 3; rep < 7; rep++)
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void bossChangeMode() {
|
||||
if (!_G(bossIntro2)) {
|
||||
Gfx::Pics loki("FACE18", 262);
|
||||
executeScript(1003, loki);
|
||||
_G(bossIntro2) = true;
|
||||
}
|
||||
|
||||
bossMode = 0;
|
||||
}
|
||||
|
||||
void boss3SetupLevel() {
|
||||
setupBoss(3);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
|
||||
if (!_G(bossIntro1)) {
|
||||
Gfx::Pics loki("FACE18", 262);
|
||||
executeScript(1002, loki);
|
||||
_G(bossIntro1) = true;
|
||||
}
|
||||
|
||||
musicPlay(7, true);
|
||||
_G(appleDropCounter) = 0;
|
||||
bossMode = 1;
|
||||
}
|
||||
|
||||
static int bossDie() {
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
void boss3ClosingSequence1() {
|
||||
musicPlay(6, true);
|
||||
odinSpeaks(1001, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss3ClosingSequence2() {
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss3ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[2] = true;
|
||||
_G(gameOver) = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 6;
|
||||
showLevel(BOSS_LEVEL3);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
_G(exitFlag) = 0;
|
||||
musicPause();
|
||||
|
||||
_G(newLevel) = ENDING_SCREEN;
|
||||
_G(thor)->_x = 152;
|
||||
_G(thor)->_y = 160;
|
||||
_G(thor)->_dir = 1;
|
||||
}
|
||||
|
||||
void endingScreen() {
|
||||
for (int i = 3; i < MAX_ACTORS; i++)
|
||||
_G(actor[i])._moveType = 1;
|
||||
|
||||
musicPlay(6, true);
|
||||
|
||||
memset(explosionFlag, 0, sizeof(explosionFlag));
|
||||
_G(endGame) = 1;
|
||||
|
||||
_G(explosionRow) = 0;
|
||||
explosionCounter = 0;
|
||||
|
||||
_G(actor[34]) = _G(explosion);
|
||||
_G(actor[34])._active = false;
|
||||
_G(actor[34])._speed = 2;
|
||||
_G(actor[34])._moveCountdown = _G(actor[34])._speed;
|
||||
_G(actor[34])._currNumShots = 3; // Used to reverse explosion
|
||||
_G(actor[34])._vulnerableCountdown = 255;
|
||||
_G(actor[34])._i2 = 6;
|
||||
}
|
||||
|
||||
// Explode
|
||||
int endgame_one() {
|
||||
if (_G(actor[34])._i2) {
|
||||
_G(actor[34])._i2--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_G(actor[34])._i2 = 6;
|
||||
playSound(EXPLODE, true);
|
||||
|
||||
int r = _G(rand1) % 32;
|
||||
while (explosionFlag[r / 8][r % 8]) {
|
||||
r++;
|
||||
if (r > 31)
|
||||
r = 0;
|
||||
}
|
||||
explosionFlag[r / 8][r % 8] = true;
|
||||
int x = (EXPLOSION[r / 8][r % 8] % 20) * 16;
|
||||
int y = (EXPLOSION[r / 8][r % 8] / 20) * 16;
|
||||
_G(actor[34])._x = x;
|
||||
_G(actor[34])._y = y;
|
||||
_G(actor[34])._active = true;
|
||||
_G(actor[34])._nextFrame = 0;
|
||||
_G(actor[34])._currNumShots = 3;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(endGame++);
|
||||
if (_G(endGame) > 32) {
|
||||
_G(actor[34])._active = false;
|
||||
_G(endGame) = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Explode
|
||||
int endGameMovement() {
|
||||
if (!_G(endGame))
|
||||
return 0;
|
||||
if (explosionCounter > 3) {
|
||||
endgame_one();
|
||||
return 0;
|
||||
}
|
||||
if (_G(actor[34])._i2) {
|
||||
_G(actor[34])._i2--;
|
||||
return 0;
|
||||
}
|
||||
_G(actor[34])._i2 = 6;
|
||||
playSound(EXPLODE, true);
|
||||
|
||||
int r = _G(rand1) % 8;
|
||||
while (explosionFlag[_G(explosionRow)][r]) {
|
||||
r++;
|
||||
if (r > 7)
|
||||
r = 0;
|
||||
}
|
||||
explosionFlag[_G(explosionRow)][r] = true;
|
||||
const int x = (EXPLOSION[_G(explosionRow)][r] % 20) * 16;
|
||||
const int y = (EXPLOSION[_G(explosionRow)][r] / 20) * 16;
|
||||
_G(actor[34])._x = x;
|
||||
_G(actor[34])._y = y;
|
||||
_G(actor[34])._active = true;
|
||||
_G(actor[34])._nextFrame = 0;
|
||||
_G(actor[34])._currNumShots = 3;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
_G(scrn)._iconGrid[(y / 16) - 4][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(endGame++);
|
||||
if (_G(endGame) > 8) {
|
||||
_G(endGame) = 1;
|
||||
_G(explosionRow++);
|
||||
explosionCounter++;
|
||||
if (explosionCounter > 3) {
|
||||
memset(explosionFlag, 0, sizeof(explosionFlag));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss3.h
Normal file
40
engines/got/game/boss3.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_BOSS3_H
|
||||
#define GOT_GAME_BOSS3_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 3 - Loki
|
||||
extern int boss3Movement(Actor *actor);
|
||||
extern void boss3SetupLevel();
|
||||
extern void endingScreen();
|
||||
extern void boss3ClosingSequence1();
|
||||
extern void boss3ClosingSequence2();
|
||||
extern void boss3ClosingSequence3();
|
||||
extern int endGameMovement();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
118
engines/got/game/init.cpp
Normal file
118
engines/got/game/init.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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/init.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/utils/file.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void setupPlayer() {
|
||||
_G(thorInfo).clear();
|
||||
_G(thorInfo)._inventory = 0;
|
||||
if (_G(area) > 1)
|
||||
_G(thorInfo)._inventory |= APPLE_MAGIC + LIGHTNING_MAGIC;
|
||||
if (_G(area) > 2)
|
||||
_G(thorInfo)._inventory |= BOOTS_MAGIC + WIND_MAGIC;
|
||||
|
||||
_G(thor)->_health = 150;
|
||||
_G(thorInfo)._magic = _G(area) > 1 ? 150 : 0;
|
||||
_G(thorInfo)._jewels = 0;
|
||||
_G(thorInfo)._score = 0;
|
||||
_G(thorInfo)._keys = 0;
|
||||
_G(thorInfo)._lastItem = 0;
|
||||
_G(thorInfo)._object = 0;
|
||||
_G(thorInfo)._objectName = nullptr;
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
_G(thorInfo)._lastIcon = (6 * 20) + 8;
|
||||
_G(thorInfo)._lastScreen = 23;
|
||||
_G(thor)->_dir = 1;
|
||||
|
||||
switch (_G(area)) {
|
||||
case 1:
|
||||
_G(thor)->_x = 152;
|
||||
_G(thor)->_y = 96;
|
||||
break;
|
||||
case 2:
|
||||
_G(thor)->_x = 32;
|
||||
_G(thor)->_y = 32;
|
||||
break;
|
||||
case 3:
|
||||
_G(thor)->_x = 272;
|
||||
_G(thor)->_y = 80;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void initGame() {
|
||||
if (_G(area) == 2)
|
||||
_G(thorInfo)._armor = 1;
|
||||
if (_G(area) == 3)
|
||||
_G(thorInfo)._armor = 10;
|
||||
loadStandardActors();
|
||||
setupPlayer();
|
||||
|
||||
if (_G(demo)) {
|
||||
g_vars->setArea(1);
|
||||
_G(thor)->_health = 100;
|
||||
_G(thorInfo)._magic = 100;
|
||||
_G(thorInfo)._jewels = 463;
|
||||
_G(thorInfo)._score = 12455;
|
||||
_G(setup)._difficultyLevel = 0;
|
||||
_G(thorInfo)._inventory = 1 + 2;
|
||||
_G(currentLevel) = 54;
|
||||
_G(thorInfo)._selectedItem = 2;
|
||||
|
||||
File f("DEMO");
|
||||
_G(demoKeys).clear();
|
||||
for (int i = 0; i < DEMO_LEN; ++i)
|
||||
_G(demoKeys).push(f.readByte());
|
||||
|
||||
// Drop the first six bytes off. This comprises of
|
||||
// the "part I" display in the original, and ScummVM
|
||||
// doesn't do demo key processing until the game view
|
||||
for (int i = 0; i < 6; ++i)
|
||||
_G(demoKeys).pop();
|
||||
}
|
||||
|
||||
_G(thor)->_moveCountdown = 6;
|
||||
|
||||
// Load level data
|
||||
_G(newLevel) = _G(currentLevel);
|
||||
_G(scrn).load(_G(currentLevel));
|
||||
showLevel(_G(currentLevel));
|
||||
|
||||
g_vars->resetEndGameFlags();
|
||||
_G(startup) = false;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
34
engines/got/game/init.h
Normal file
34
engines/got/game/init.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_INIT_H
|
||||
#define GOT_GAME_INIT_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
/**
|
||||
* Handles in-game initialization the first time
|
||||
*/
|
||||
extern void initGame();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
80
engines/got/game/main.cpp
Normal file
80
engines/got/game/main.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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 "common/memstream.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/vars.h"
|
||||
#include "got/gfx/image.h" // loadNewThor
|
||||
|
||||
namespace Got {
|
||||
|
||||
void setupLoad() {
|
||||
_G(thor)->_active = true;
|
||||
_G(newLevel) = _G(thorInfo)._lastScreen;
|
||||
_G(thor)->_x = (_G(thorInfo)._lastIcon % 20) * 16;
|
||||
_G(thor)->_y = ((_G(thorInfo)._lastIcon / 20) * 16) - 1;
|
||||
if (_G(thor)->_x < 1)
|
||||
_G(thor)->_x = 1;
|
||||
if (_G(thor)->_y < 0)
|
||||
_G(thor)->_y = 0;
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
_G(thor)->_dir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_lastDir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_health = _G(thorInfo)._lastHealth;
|
||||
_G(thorInfo)._magic = _G(thorInfo)._lastMagic;
|
||||
_G(thorInfo)._jewels = _G(thorInfo)._lastJewels;
|
||||
_G(thorInfo)._keys = _G(thorInfo)._lastKeys;
|
||||
_G(thorInfo)._score = _G(thorInfo)._lastScore;
|
||||
_G(thorInfo)._selectedItem = _G(thorInfo)._lastItem;
|
||||
_G(thorInfo)._inventory = _G(thorInfo)._lastInventory;
|
||||
_G(thorInfo)._object = _G(thorInfo)._lastObject;
|
||||
_G(thorInfo)._objectName = _G(thorInfo)._lastObjectName;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(thor)->_vulnerableCountdown = 60;
|
||||
_G(thor)->_show = 60;
|
||||
_G(appleFlag) = false;
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(shieldOn) = false;
|
||||
_G(actor[1])._active = false;
|
||||
_G(actor[2])._active = false;
|
||||
_G(thor)->_moveCountdown = 6;
|
||||
|
||||
_G(scrn).load(_G(newLevel));
|
||||
|
||||
_G(currentLevel) = _G(newLevel);
|
||||
showLevel(_G(newLevel));
|
||||
|
||||
if (_G(area) == 2 && _G(currentLevel) == 105) { // Shovel Maze
|
||||
_G(thorInfo)._armor = 2; // eyeballs mode
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void pause(int delay) {
|
||||
g_system->delayMillis(delay);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
32
engines/got/game/main.h
Normal file
32
engines/got/game/main.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_MAIN_H
|
||||
#define GOT_GAME_MAIN_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void setupLoad();
|
||||
extern void pause(int delay);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
380
engines/got/game/move.cpp
Normal file
380
engines/got/game/move.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/* 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.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/shot_movement.h"
|
||||
#include "got/game/shot_pattern.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void nextFrame(Actor *actor) {
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
}
|
||||
|
||||
bool pointWithin(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
return ((x >= x1) && (x <= x2) && (y >= y1) && (y <= y2));
|
||||
}
|
||||
|
||||
bool overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
if ((x1 >= x3) && (x1 <= x4) && (y1 >= y3) && (y1 <= y4))
|
||||
return true;
|
||||
if ((x2 >= x3) && (x2 <= x4) && (y2 >= y3) && (y2 <= y4))
|
||||
return true;
|
||||
if ((x1 >= x3) && (x1 <= x4) && (y2 >= y3) && (y2 <= y4))
|
||||
return true;
|
||||
if ((x2 >= x3) && (x2 <= x4) && (y1 >= y3) && (y1 <= y4))
|
||||
return true;
|
||||
if ((x3 >= x1) && (x3 <= x2) && (y3 >= y1) && (y3 <= y2))
|
||||
return true;
|
||||
if ((x4 >= x1) && (x4 <= x2) && (y4 >= y1) && (y4 <= y2))
|
||||
return true;
|
||||
if ((x3 >= x1) && (x3 <= x2) && (y4 >= y1) && (y4 <= y2))
|
||||
return true;
|
||||
if ((x4 >= x1) && (x4 <= x2) && (y3 >= y1) && (y3 <= y2))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int reverseDirection(Actor *actor) {
|
||||
if (actor->_dir == 1)
|
||||
return 0;
|
||||
if (actor->_dir == 2)
|
||||
return 3;
|
||||
if (actor->_dir == 3)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void thorShoots() {
|
||||
if (!_G(hammer)->_active && (!_G(hammer)->_dead) && (!_G(thor)->_shotCountdown)) {
|
||||
playSound(SWISH, false);
|
||||
_G(thor)->_shotCountdown = 20;
|
||||
_G(hammer)->_active = true;
|
||||
_G(hammer)->_dir = _G(thor)->_dir;
|
||||
_G(hammer)->_lastDir = _G(thor)->_dir;
|
||||
_G(hammer)->_x = _G(thor)->_x;
|
||||
_G(hammer)->_y = _G(thor)->_y + 2;
|
||||
_G(hammer)->_moveType = 2;
|
||||
_G(hammer)->_nextFrame = 0;
|
||||
_G(hammer)->_lastX[0] = _G(hammer)->_x;
|
||||
_G(hammer)->_lastX[1] = _G(hammer)->_x;
|
||||
_G(hammer)->_lastY[0] = _G(hammer)->_y;
|
||||
_G(hammer)->_lastY[1] = _G(hammer)->_y;
|
||||
}
|
||||
}
|
||||
|
||||
int killGoodGuy() {
|
||||
if (!_G(killGoodGuyInform) && !_G(thunderSnakeCounter)) {
|
||||
odinSpeaks(2010, 0);
|
||||
_G(killGoodGuyInform) = true;
|
||||
}
|
||||
|
||||
addScore(-1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void actorDamaged(Actor *actor, int damage) {
|
||||
if (!_G(setup)._difficultyLevel)
|
||||
damage *= 2;
|
||||
else if (_G(setup)._difficultyLevel == 2)
|
||||
damage /= 2;
|
||||
|
||||
if (!actor->_vulnerableCountdown && actor->_type != 3 && (actor->_solid & 0x7f) != 2) {
|
||||
actor->_vulnerableCountdown = STAMINA;
|
||||
if (damage >= actor->_health) {
|
||||
if (actor->_type != 4) {
|
||||
addScore(actor->_initHealth * 10);
|
||||
|
||||
} else {
|
||||
killGoodGuy();
|
||||
}
|
||||
|
||||
actorDestroyed(actor);
|
||||
} else {
|
||||
actor->_show = 10;
|
||||
actor->_health -= damage;
|
||||
actor->_moveCountdown += 8;
|
||||
}
|
||||
} else if (!actor->_vulnerableCountdown) {
|
||||
actor->_vulnerableCountdown = STAMINA;
|
||||
|
||||
if (actor->_funcNum == 4) {
|
||||
switchIcons();
|
||||
}
|
||||
if (actor->_funcNum == 7) {
|
||||
rotateArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void thorDamaged(Actor *actor) {
|
||||
actor->_hitThor = true;
|
||||
|
||||
// If we're invincible, ignore any damage
|
||||
if (_G(cheats)._freezeHealth)
|
||||
return;
|
||||
|
||||
if (GAME3 && actor->_funcNum == 11) {
|
||||
if (actor->_talkCounter) {
|
||||
actor->_talkCounter--;
|
||||
return;
|
||||
}
|
||||
|
||||
const int currType = actor->_type;
|
||||
actor->_type = 4;
|
||||
actorSpeaks(actor, 0, 0);
|
||||
actor->_type = currType;
|
||||
actor->_talkCounter = 30;
|
||||
return;
|
||||
}
|
||||
|
||||
int damage = actor->_hitStrength;
|
||||
if (damage != 255) {
|
||||
if (!_G(setup)._difficultyLevel)
|
||||
damage /= 2;
|
||||
else if (_G(setup)._difficultyLevel == 2)
|
||||
damage *= 2;
|
||||
}
|
||||
if ((!_G(thor)->_vulnerableCountdown && !_G(shieldOn)) || damage == 255) {
|
||||
if (damage >= _G(thor)->_health) {
|
||||
_G(thor)->_vulnerableCountdown = 40;
|
||||
_G(thor)->_show = 0;
|
||||
_G(thor)->_health = 0;
|
||||
_G(exitFlag) = 2;
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
} else if (damage) {
|
||||
_G(thor)->_vulnerableCountdown = 40;
|
||||
_G(sound).playSound(OW, false);
|
||||
_G(thor)->_show = 10;
|
||||
_G(thor)->_health -= damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void actorDestroyed(Actor *actor) {
|
||||
if (actor->_actorNum > 2) {
|
||||
const int curPage = _G(pge);
|
||||
|
||||
const int x = actor->_lastX[curPage ^ 1];
|
||||
const int y = actor->_lastY[curPage ^ 1];
|
||||
const int x1 = actor->_lastX[curPage];
|
||||
const int y1 = actor->_lastY[curPage];
|
||||
const int r = actor->_dropRating;
|
||||
const int n = actor->_actorNum;
|
||||
const int t = actor->_type;
|
||||
|
||||
if (actor->_funcNum == 255)
|
||||
actor->copyFixedAndPics(_G(explosion));
|
||||
else
|
||||
actor->copyFixedAndPics(_G(sparkle));
|
||||
|
||||
actor->_type = t;
|
||||
actor->_actorNum = n;
|
||||
actor->_dropRating = r;
|
||||
actor->_x = x;
|
||||
actor->_y = y;
|
||||
actor->_lastX[curPage] = x1;
|
||||
actor->_lastX[curPage ^ 1] = x;
|
||||
actor->_lastY[curPage] = y1;
|
||||
actor->_lastY[curPage ^ 1] = y;
|
||||
actor->_moveCountdown = actor->_speed;
|
||||
actor->_active = true;
|
||||
actor->_currNumShots = 3; // used to reverse explosion
|
||||
actor->_vulnerableCountdown = 255;
|
||||
} else {
|
||||
actor->_dead = 2;
|
||||
actor->_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
int _actor_shoots(Actor *actor, int dir) {
|
||||
const int t = actor->_shotType - 1;
|
||||
for (int i = MAX_ENEMIES + 3; i < MAX_ACTORS; i++) {
|
||||
if ((!_G(actor[i])._active) && (!_G(actor[i])._dead)) {
|
||||
Actor *act = &_G(actor[i]);
|
||||
*act = _G(shot[t]);
|
||||
int cx, cy;
|
||||
|
||||
if (actor->_sizeY < act->_sizeY)
|
||||
cy = actor->_y - ((act->_sizeY - actor->_sizeY) / 2);
|
||||
else
|
||||
cy = actor->_y + ((actor->_sizeY - act->_sizeY) / 2);
|
||||
|
||||
if (actor->_sizeX < act->_sizeX)
|
||||
cx = actor->_x - ((act->_sizeX - actor->_sizeX) / 2);
|
||||
else
|
||||
cx = actor->_x + ((actor->_sizeX - act->_sizeX) / 2);
|
||||
|
||||
if (cy > 174)
|
||||
cy = 174;
|
||||
|
||||
if (cx > 304)
|
||||
cx = 304;
|
||||
|
||||
act->_x = cx;
|
||||
act->_y = cy;
|
||||
act->_lastDir = dir;
|
||||
act->_nextFrame = 0;
|
||||
act->_dir = dir;
|
||||
if (act->_directions == 1)
|
||||
act->_dir = 0;
|
||||
else if (act->_directions == 4 && act->_framesPerDirection == 1) {
|
||||
act->_nextFrame = dir;
|
||||
act->_dir = 0;
|
||||
}
|
||||
act->_frameCount = act->_frameSpeed;
|
||||
act->_moveCountdown = act->_speed;
|
||||
act->_lastX[0] = cx;
|
||||
act->_lastX[1] = cx;
|
||||
act->_lastX[0] = actor->_x;
|
||||
act->_lastX[1] = actor->_x;
|
||||
act->_lastY[0] = cy;
|
||||
act->_lastY[1] = cy;
|
||||
act->_active = true;
|
||||
act->_creator = actor->_actorNum;
|
||||
act->_moveCount = act->_numMoves;
|
||||
act->_dead = 0;
|
||||
actor->_shotActor = i;
|
||||
actor->_currNumShots++;
|
||||
actor->_shotCountdown = 20;
|
||||
_G(shotOk) = false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void actorAlwaysShoots(Actor *actor, int dir) {
|
||||
_actor_shoots(actor, dir);
|
||||
}
|
||||
|
||||
int actorShoots(Actor *actor, int dir) {
|
||||
const int cx = (actor->_x + (actor->_sizeX / 2)) >> 4;
|
||||
const int cy = ((actor->_y + actor->_sizeY) - 2) >> 4;
|
||||
|
||||
const int tx = _G(thor)->_centerX;
|
||||
const int ty = _G(thor)->_centerY;
|
||||
|
||||
int icn = 140;
|
||||
|
||||
if (_G(shot[actor->_shotType - 1])._flying)
|
||||
icn = 80;
|
||||
|
||||
switch (dir) {
|
||||
case 0:
|
||||
for (int i = ty + 1; i <= cy; i++) {
|
||||
if (_G(scrn)._iconGrid[i][cx] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = cy; i <= ty; i++) {
|
||||
if (_G(scrn)._iconGrid[i][cx] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i = tx; i < cx; i++) {
|
||||
if (_G(scrn)._iconGrid[cy][i] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (int i = cx; i < tx; i++) {
|
||||
if (_G(scrn)._iconGrid[cy][i] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return _actor_shoots(actor, dir);
|
||||
}
|
||||
|
||||
void moveActor(Actor *actor) {
|
||||
if (actor->_vulnerableCountdown != 0)
|
||||
actor->_vulnerableCountdown--;
|
||||
if (actor->_shotCountdown != 0)
|
||||
actor->_shotCountdown--;
|
||||
if (actor->_show != 0)
|
||||
actor->_show--;
|
||||
|
||||
if (!actor->_shotCountdown && _G(shotOk) && actor->_numShotsAllowed && actor->_currNumShots < actor->_numShotsAllowed) {
|
||||
shotPatternFunc[actor->_shotPattern](actor);
|
||||
}
|
||||
|
||||
const int scount = actor->_moveCountdown - 1;
|
||||
if (scount <= 0) {
|
||||
if (!actor->_moveCounter)
|
||||
actor->_moveCountdown = actor->_speed;
|
||||
else
|
||||
actor->_moveCountdown = (actor->_speed << 1);
|
||||
|
||||
int i;
|
||||
|
||||
if (actor->_type == 3)
|
||||
i = shotMovementFunc[actor->_moveType](actor);
|
||||
else
|
||||
i = _movementFunc[actor->_moveType](actor);
|
||||
|
||||
if (actor->_directions == 2)
|
||||
i &= 1;
|
||||
|
||||
if (i != actor->_dir)
|
||||
actor->_dir = i;
|
||||
|
||||
if (actor->_moveType == 0 && _G(currentLevel) != _G(newLevel) && _G(shieldOn)) {
|
||||
_G(actor[2])._x = actor->_x - 2;
|
||||
if (_G(actor[2])._x < 0)
|
||||
_G(actor[2])._x = 0;
|
||||
_G(actor[2])._y = actor->_y;
|
||||
_G(actor[2])._lastX[0] = _G(actor[2])._x;
|
||||
_G(actor[2])._lastX[1] = _G(actor[2])._x;
|
||||
_G(actor[2])._lastY[0] = _G(actor[2])._y;
|
||||
_G(actor[2])._lastY[1] = _G(actor[2])._y;
|
||||
}
|
||||
} else
|
||||
actor->_moveCountdown = scount;
|
||||
|
||||
actor->_x &= 0xfffe;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
43
engines/got/game/move.h
Normal file
43
engines/got/game/move.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_MOVE_H
|
||||
#define GOT_GAME_MOVE_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void nextFrame(Actor *actor);
|
||||
extern bool pointWithin(int x, int y, int x1, int y1, int x2, int y2);
|
||||
extern bool overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
|
||||
extern int reverseDirection(Actor *actor);
|
||||
extern void thorShoots();
|
||||
extern void thorDamaged(Actor *actor);
|
||||
extern void actorDestroyed(Actor *actor);
|
||||
extern int actorShoots(Actor *actor, int dir);
|
||||
extern void actorAlwaysShoots(Actor *actor, int dir);
|
||||
extern void actorDamaged(Actor *actor, int damage);
|
||||
extern void moveActor(Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
2622
engines/got/game/move_patterns.cpp
Normal file
2622
engines/got/game/move_patterns.cpp
Normal file
File diff suppressed because it is too large
Load Diff
37
engines/got/game/move_patterns.h
Normal file
37
engines/got/game/move_patterns.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_MOVE_PATTERNS_H
|
||||
#define GOT_GAME_MOVE_PATTERNS_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const _movementFunc[]) (Actor *actor);
|
||||
int checkMove2(int x, int y, Actor *actor);
|
||||
int checkMove3(int x, int y, Actor *actor);
|
||||
int checkMove4(int x, int y, Actor *actor);
|
||||
void setThorVars();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
437
engines/got/game/object.cpp
Normal file
437
engines/got/game/object.cpp
Normal file
@@ -0,0 +1,437 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property _G(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 _G(of) the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 _G(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 _G(of)
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy _G(of) the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "got/game/object.h"
|
||||
#include "got/data/flags.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void notEnoughMagic();
|
||||
void cannotCarryMore();
|
||||
|
||||
void showObjects() {
|
||||
Common::fill(_G(objectMap), _G(objectMap) + TILES_COUNT, 0);
|
||||
Common::fill(_G(objectIndex), _G(objectIndex) + TILES_COUNT, 0);
|
||||
|
||||
for (int i = 0; i < OBJECTS_COUNT; i++) {
|
||||
if (_G(scrn)._staticObject[i]) {
|
||||
const int p = _G(scrn)._staticX[i] + (_G(scrn)._staticY[i] * TILES_X);
|
||||
_G(objectIndex[p]) = i;
|
||||
_G(objectMap[p]) = _G(scrn)._staticObject[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pickUpObject(int p) {
|
||||
switch (_G(objectMap[p])) {
|
||||
case 1: // Red jewel
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(10);
|
||||
break;
|
||||
case 2: // Blue jewel
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(1);
|
||||
break;
|
||||
case 3: // Red potion
|
||||
if (_G(thorInfo)._magic >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addMagic(10);
|
||||
break;
|
||||
case 4: // Blue potion
|
||||
if (_G(thorInfo)._magic >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addMagic(3);
|
||||
break;
|
||||
case 5: // Good apple
|
||||
if (_G(thor)->_health >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
playSound(GULP, false);
|
||||
addHealth(5);
|
||||
break;
|
||||
case 6: // Bad apple
|
||||
playSound(OW, false);
|
||||
addHealth(-10);
|
||||
break;
|
||||
case 7: // Key (reset on exit)
|
||||
addKeys(1);
|
||||
break;
|
||||
case 8: // Treasure
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(50);
|
||||
break;
|
||||
case 9: // Trophy
|
||||
addScore(100);
|
||||
break;
|
||||
case 10: // Crown
|
||||
addScore(1000);
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
if (_G(objectMap[p]) == 13 && HERMIT_HAS_DOLL)
|
||||
return;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
_G(actor[2])._active = false;
|
||||
_G(shieldOn) = false;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(thorInfo)._inventory |= 64;
|
||||
_G(thorInfo)._selectedItem = 7;
|
||||
_G(thorInfo)._object = _G(objectMap[p]) - 11;
|
||||
_G(thorInfo)._objectName = OBJECT_NAMES[_G(thorInfo)._object - 1];
|
||||
odinSpeaks((_G(objectMap[p]) - 12) + 501, _G(objectMap[p]) - 1);
|
||||
break;
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32: {
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
_G(shieldOn) = false;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(actor[2])._active = false;
|
||||
const int s = 1 << (_G(objectMap[p]) - 27);
|
||||
_G(thorInfo)._inventory |= s;
|
||||
odinSpeaks((_G(objectMap[p]) - 27) + 516, _G(objectMap[p]) - 1);
|
||||
_G(thorInfo)._selectedItem = _G(objectMap[p]) - 26;
|
||||
addMagic(150);
|
||||
fillScore(5);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
playSound(YAH, false);
|
||||
_G(objectMap[p]) = 0;
|
||||
|
||||
// Reset so it doesn't reappear on reentry to screen
|
||||
if (_G(objectIndex[p]) < 30)
|
||||
_G(scrn)._staticObject[_G(objectIndex[p])] = 0;
|
||||
|
||||
_G(objectIndex[p]) = 0;
|
||||
}
|
||||
|
||||
void dropRandomObject(Actor *actor) {
|
||||
int objId;
|
||||
|
||||
const int rnd1 = g_events->getRandomNumber(99);
|
||||
const int rnd2 = g_events->getRandomNumber(99);
|
||||
|
||||
if (rnd1 < 25)
|
||||
objId = 5; // Apple
|
||||
else if (rnd1 & 1) {
|
||||
// Jewels
|
||||
if (rnd2 < 10)
|
||||
objId = 1; // Red
|
||||
else
|
||||
objId = 2; // Blue
|
||||
} else {
|
||||
// Potion
|
||||
if (rnd2 < 10)
|
||||
objId = 3; // Red
|
||||
else
|
||||
objId = 4; // Blue
|
||||
}
|
||||
|
||||
dropObject(actor, objId);
|
||||
}
|
||||
|
||||
bool dropObject(Actor *actor, const int objId) {
|
||||
const int p = (actor->_x + (actor->_sizeX / 2)) / 16 + (((actor->_y + (actor->_sizeY / 2)) / 16) * 20);
|
||||
if (!_G(objectMap[p]) && _G(scrn)._iconGrid[p / 20][p % 20] >= 140) { //nothing there and solid
|
||||
_G(objectMap[p]) = objId;
|
||||
_G(objectIndex[p]) = 27 + actor->_actorNum; //actor is 3-15
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useApple(int flag) {
|
||||
if (_G(thor)->_health == 150)
|
||||
return false;
|
||||
|
||||
if (flag && _G(thorInfo)._magic > 0) {
|
||||
if (!_G(appleFlag)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-2);
|
||||
addHealth(1);
|
||||
playSound(ANGEL, false);
|
||||
} else if (_G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-2);
|
||||
addHealth(1);
|
||||
if (!soundPlaying())
|
||||
playSound(ANGEL, false);
|
||||
}
|
||||
_G(appleFlag) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
_G(appleFlag) = false;
|
||||
if (flag)
|
||||
notEnoughMagic();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useThunder(int flag) {
|
||||
if (flag && _G(thorInfo)._magic > 29) {
|
||||
if (!_G(thunderSnakeCounter)) {
|
||||
addMagic(-30);
|
||||
playSound(THUNDER, false);
|
||||
_G(thunderSnakeCounter) = 60;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flag && !_G(thunderSnakeCounter))
|
||||
notEnoughMagic();
|
||||
|
||||
if (_G(thunderSnakeCounter))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useBoots(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 0) {
|
||||
if (_G(thor)->_numMoves == 1 || _G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
|
||||
_G(thor)->_numMoves = 2;
|
||||
_G(hammer)->_numMoves = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
notEnoughMagic();
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
|
||||
} else {
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useShield(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic) {
|
||||
if (!_G(shieldOn)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
setupMagicItem(1);
|
||||
|
||||
_G(actor[2]) = _G(magicItem[1]);
|
||||
setupActor(&_G(actor[2]), 2, 0, _G(thor)->_x, _G(thor)->_y);
|
||||
_G(actor[2])._moveCountdown = 1;
|
||||
_G(actor[2])._speed = 1;
|
||||
_G(shieldOn) = true;
|
||||
} else if (_G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
notEnoughMagic();
|
||||
}
|
||||
|
||||
if (_G(shieldOn)) {
|
||||
_G(actor[2])._dead = 2;
|
||||
_G(actor[2])._active = false;
|
||||
_G(shieldOn) = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useLightning(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 14) {
|
||||
addMagic(-15);
|
||||
g_events->send("Game", GameMessage("THROW_LIGHTNING"));
|
||||
} else {
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool useTornado(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 10) {
|
||||
if (!_G(tornadoUsed) && !_G(actor[2])._dead && _G(magicCounter) > 20) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-10);
|
||||
setupMagicItem(0);
|
||||
_G(actor[2]) = _G(magicItem[0]);
|
||||
|
||||
setupActor(&_G(actor[2]), 2, 0, _G(thor)->_x, _G(thor)->_y);
|
||||
_G(actor[2])._lastDir = _G(thor)->_dir;
|
||||
_G(actor[2])._moveType = 16;
|
||||
_G(tornadoUsed) = true;
|
||||
playSound(WIND, false);
|
||||
}
|
||||
} else if (!_G(tornadoUsed)) {
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
if (_G(magicCounter) > 8) {
|
||||
if (_G(tornadoUsed)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
}
|
||||
if (_G(thorInfo)._magic < 1) {
|
||||
actorDestroyed(&_G(actor[2]));
|
||||
_G(tornadoUsed) = false;
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useObject(int flag) {
|
||||
if (!flag || !(_G(thorInfo)._inventory & 64))
|
||||
return false;
|
||||
|
||||
odinSpeaks((_G(thorInfo)._object - 1) + 5501, _G(thorInfo)._object - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void useItem() {
|
||||
bool ret = false;
|
||||
|
||||
const int kf = _G(keyFlag[key_magic]);
|
||||
|
||||
if (!kf && _G(tornadoUsed)) {
|
||||
actorDestroyed(&_G(actor[2]));
|
||||
_G(tornadoUsed) = false;
|
||||
}
|
||||
|
||||
const bool mf = _G(magicMissingInform);
|
||||
switch (_G(thorInfo)._selectedItem) {
|
||||
case 1:
|
||||
ret = useApple(kf);
|
||||
break;
|
||||
case 2:
|
||||
ret = useLightning(kf);
|
||||
break;
|
||||
case 3:
|
||||
ret = useBoots(kf);
|
||||
break;
|
||||
case 4:
|
||||
ret = useTornado(kf);
|
||||
break;
|
||||
case 5:
|
||||
ret = useShield(kf);
|
||||
break;
|
||||
case 6:
|
||||
ret = useThunder(kf);
|
||||
break;
|
||||
case 7:
|
||||
ret = useObject(kf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (kf) {
|
||||
if (!ret && !_G(useItemFlag)) {
|
||||
if (mf)
|
||||
playSound(BRAAPP, false);
|
||||
_G(useItemFlag) = true;
|
||||
}
|
||||
} else {
|
||||
_G(useItemFlag) = false;
|
||||
}
|
||||
}
|
||||
|
||||
void notEnoughMagic() {
|
||||
if (_G(magicMissingInform))
|
||||
return;
|
||||
|
||||
odinSpeaks(2006, 0);
|
||||
_G(magicMissingInform) = true;
|
||||
}
|
||||
|
||||
void cannotCarryMore() {
|
||||
if (_G(cantCarryInform))
|
||||
return;
|
||||
|
||||
odinSpeaks(2007, 0);
|
||||
_G(cantCarryInform) = true;
|
||||
}
|
||||
|
||||
void deleteObject() {
|
||||
_G(thorInfo)._inventory &= 0xbf;
|
||||
_G(thorInfo)._selectedItem = 1;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
38
engines/got/game/object.h
Normal file
38
engines/got/game/object.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_OBJECT_H
|
||||
#define GOT_GAME_OBJECT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void showObjects();
|
||||
extern void pickUpObject(int p);
|
||||
extern void dropRandomObject(Actor *actor);
|
||||
extern bool dropObject(Actor *actor, int objId);
|
||||
extern void deleteObject();
|
||||
extern void useItem();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
1265
engines/got/game/script.cpp
Normal file
1265
engines/got/game/script.cpp
Normal file
File diff suppressed because it is too large
Load Diff
127
engines/got/game/script.h
Normal file
127
engines/got/game/script.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_SCRIPT_H
|
||||
#define GOT_GAME_SCRIPT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
#include "got/gfx/gfx_pics.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
typedef void (*ScriptEndFn)();
|
||||
|
||||
enum ScriptPause {
|
||||
SCRIPT_READY, SCRIPT_PAUSED, SCRIPT_RESUMING
|
||||
};
|
||||
|
||||
class Scripts {
|
||||
public:
|
||||
Scripts();
|
||||
~Scripts();
|
||||
|
||||
void executeScript(long index, const Gfx::Pics &speakerIcon, ScriptEndFn endFn = nullptr);
|
||||
void pause();
|
||||
void resume();
|
||||
void setAskResponse(int option);
|
||||
void runIfResuming();
|
||||
|
||||
private:
|
||||
ScriptEndFn _endFn = nullptr;
|
||||
long _numVar[26] = {}; // numeric variables
|
||||
char _strVar[26][81] = {}; // string vars
|
||||
char _lineLabel[32][9] = {}; // line label look up table
|
||||
char *_linePtr[32] = {}; // line label pointers
|
||||
char *_newPtr = nullptr;
|
||||
int _numLabels = 0; // number of labels
|
||||
char *_gosubStack[32] = {}; // stack for GOSUB return addresses
|
||||
int _gosubPtr = 0; // GOSUB stack pointer
|
||||
char *_forStack[11] = {}; // FOR stack
|
||||
long _forVal[11] = {}; // current FOR value
|
||||
int8 _forVar[11] = {}; // ending FOR value (target var)
|
||||
int8 _forPtr = 0; // FOR stack pointer
|
||||
char *_buffPtr = nullptr; // pointer to current command
|
||||
char *_buffEnd = nullptr; // pointer to end of buffer
|
||||
char *_buffer = nullptr; // buffer space (alloc'ed)
|
||||
long _scrIndex = 0;
|
||||
Gfx::Pics _scrPic;
|
||||
long _lValue = 0;
|
||||
long _lTemp = 0;
|
||||
char _tempS[255] = {};
|
||||
ScriptPause _paused = SCRIPT_READY;
|
||||
int _askVar = -1;
|
||||
|
||||
private:
|
||||
int readScriptFile();
|
||||
void scriptError(int err_num);
|
||||
int getCommand();
|
||||
int skipColon();
|
||||
int calcValue();
|
||||
int getNextValue();
|
||||
int calcString(int mode);
|
||||
void getStr();
|
||||
int getInternalVariable();
|
||||
int execCommand(int num);
|
||||
int getLine(char *src, char *dst);
|
||||
void scriptEntry() {}
|
||||
void scriptExit();
|
||||
|
||||
int cmd_goto();
|
||||
int cmd_if();
|
||||
int cmd_run();
|
||||
int cmd_addJewels();
|
||||
int cmd_addHealth();
|
||||
int cmd_addMagic();
|
||||
int cmd_addKeys();
|
||||
int cmd_addScore();
|
||||
int cmd_say(int mode, int type);
|
||||
int cmd_ask();
|
||||
int cmd_sound();
|
||||
int cmd_setTile();
|
||||
int cmd_itemGive();
|
||||
int cmd_itemTake();
|
||||
int cmd_setFlag();
|
||||
int cmd_ltoa();
|
||||
int cmd_pause();
|
||||
int cmd_visible();
|
||||
int cmd_random();
|
||||
int cmd_exec();
|
||||
|
||||
void scr_func1();
|
||||
void scr_func2();
|
||||
void scr_func3();
|
||||
void scr_func4();
|
||||
void scr_func5();
|
||||
|
||||
typedef void (Scripts:: *ScrFunction)();
|
||||
static ScrFunction scr_func[5];
|
||||
|
||||
void runScript(bool firstTime = true);
|
||||
void scriptLoop();
|
||||
|
||||
};
|
||||
|
||||
extern void executeScript(long index, const Gfx::Pics &speakerIcon,
|
||||
ScriptEndFn endFn = nullptr);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
734
engines/got/game/shot_movement.cpp
Normal file
734
engines/got/game/shot_movement.cpp
Normal file
@@ -0,0 +1,734 @@
|
||||
/* 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/shot_movement.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/object.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int shotMovementNone(Actor *actor);
|
||||
int shotMovementOne(Actor *actor);
|
||||
int shotMovementTwo(Actor *actor);
|
||||
int shotMovementThree(Actor *actor);
|
||||
int shotMovementFour(Actor *actor);
|
||||
int shotMovementFive(Actor *actor);
|
||||
int shotMovementSix(Actor *actor);
|
||||
int shotMovementSeven(Actor *actor);
|
||||
int shotMovementEight(Actor *actor);
|
||||
int shotMovementNine(Actor *actor);
|
||||
int shotMovementTen(Actor *actor);
|
||||
int shotMovementEleven(Actor *actor);
|
||||
int shotMovementTwelve(Actor *actor);
|
||||
int shotMovementThirteen(Actor *actor);
|
||||
|
||||
int (*const shotMovementFunc[])(Actor *actor) = {
|
||||
shotMovementNone,
|
||||
shotMovementOne,
|
||||
shotMovementTwo,
|
||||
shotMovementThree,
|
||||
shotMovementFour,
|
||||
shotMovementFive,
|
||||
shotMovementSix,
|
||||
shotMovementSeven,
|
||||
shotMovementEight,
|
||||
shotMovementNine,
|
||||
shotMovementTen,
|
||||
shotMovementEleven,
|
||||
shotMovementTwelve,
|
||||
shotMovementThirteen
|
||||
};
|
||||
|
||||
void next_shot_frame(Actor *actor) {
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1) {
|
||||
actor->_nextFrame = actor->_lastDir;
|
||||
actor->_dir = 0;
|
||||
} else {
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
}
|
||||
}
|
||||
|
||||
// Boss - snake
|
||||
int shotMovementNone(Actor *actor) {
|
||||
actor->_temp3--;
|
||||
if (!actor->_temp3) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
}
|
||||
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
int shotMovementOne(Actor *actor) {
|
||||
int x1 = 0, y1 = 0;
|
||||
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
switch (d) {
|
||||
case 0:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y - 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y + 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x1 = actor->_x - 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x1 = actor->_x + 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!checkMove3(x1, y1, actor)) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1)
|
||||
return 0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int shotMovementTwo(Actor *actor) {
|
||||
int x1 = 0, y1 = 0;
|
||||
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
switch (d) {
|
||||
case 0:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y - 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y + 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x1 = actor->_x - 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x1 = actor->_x + 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!checkMove4(x1, y1, actor)) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Serpent fire
|
||||
int shotMovementThree(Actor *actor) {
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
actor->_x -= 2;
|
||||
actor->_temp3--;
|
||||
actor->_temp4--;
|
||||
|
||||
if (overlap(_G(thorX1) - 1, _G(thorY1) - 1, _G(thorX2) + 1, _G(thorY2) + 1,
|
||||
actor->_x, actor->_y, actor->_x + 15, actor->_y + 15)) {
|
||||
actor->_moveType = 0;
|
||||
actor->_speed = 6;
|
||||
thorDamaged(actor);
|
||||
actor->_x += 2;
|
||||
}
|
||||
if (!actor->_temp4) {
|
||||
actor->_temp4 = actor->_temp5;
|
||||
actor->_speed++;
|
||||
if (actor->_speed > 6)
|
||||
actor->_moveType = 0;
|
||||
}
|
||||
if (!actor->_temp3) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Wraith balls
|
||||
int shotMovementFour(Actor *actor) {
|
||||
if (actor->_temp1) {
|
||||
actor->_temp1--;
|
||||
if (!actor->_temp1) {
|
||||
actorDestroyed(actor);
|
||||
_G(appleDropCounter++);
|
||||
if (_G(appleDropCounter) == 4) {
|
||||
if (dropObject(actor, 5))
|
||||
_G(appleDropCounter) = 0;
|
||||
else
|
||||
_G(appleDropCounter) = 3;
|
||||
} else
|
||||
dropObject(actor, 3);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (overlap(_G(thor)->_x - 1, _G(thor)->_y - 1, _G(thorX2) + 1, _G(thorY2) + 1,
|
||||
actor->_x, actor->_y, actor->_x + 15, actor->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
actorDestroyed(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
int yd = 0;
|
||||
int xd = 0;
|
||||
int d = actor->_lastDir;
|
||||
|
||||
if ((x1 > (_G(thorX1)) + 1))
|
||||
xd = -2;
|
||||
else if ((x1 < (_G(thorX1)) - 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 (checkMove3(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 (checkMove3(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 (checkMove3(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 (checkMove3(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 (checkMove3(x1, y1, actor)) {
|
||||
if (xd > 0)
|
||||
d = 3;
|
||||
else
|
||||
d = 2;
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
checkMove3(actor->_x, actor->_y, actor);
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// No move, frame cycle
|
||||
int shotMovementFive(Actor *actor) {
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Wraith spots
|
||||
int shotMovementSix(Actor *actor) {
|
||||
actor->_temp1--;
|
||||
if (!actor->_temp1) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
#define YV actor->_i1
|
||||
#define YC actor->_i2
|
||||
#define BC actor->_i3
|
||||
#define YD actor->_i4
|
||||
#define XD actor->_i5
|
||||
#define XC actor->_i6
|
||||
#define IV 100
|
||||
#define IC 50
|
||||
|
||||
// Skull drop
|
||||
int shotMovementSeven(Actor *actor) {
|
||||
if (actor->_temp3) {
|
||||
actor->_temp3--;
|
||||
goto done;
|
||||
}
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
|
||||
actor->_temp2++;
|
||||
if (actor->_temp2 > 2) {
|
||||
if (actor->_temp4)
|
||||
actor->_temp4--;
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
actor->_temp3 = actor->_temp4;
|
||||
|
||||
actor->_y += 2;
|
||||
if (actor->_y > 160 - 36) {
|
||||
actor->_x += (4 - g_events->getRandomNumber(8));
|
||||
actor->_moveType = 8;
|
||||
YV = IV;
|
||||
YC = 0;
|
||||
BC = IC;
|
||||
YD = 0;
|
||||
XC = 3;
|
||||
if (actor->_x < 150)
|
||||
XD = 1;
|
||||
else
|
||||
XD = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull bounce
|
||||
int shotMovementEight(Actor *actor) {
|
||||
int x = actor->_x;
|
||||
int y = actor->_y;
|
||||
|
||||
XC--;
|
||||
if (!XC) {
|
||||
XC = 3;
|
||||
if (XD)
|
||||
x += 2;
|
||||
else
|
||||
x -= 2;
|
||||
}
|
||||
YC += YV;
|
||||
if (YC > (IV - 1)) {
|
||||
if (!YD) {
|
||||
YV -= 8;
|
||||
YC -= IV;
|
||||
y -= 2;
|
||||
} else {
|
||||
YV += 8;
|
||||
YC -= IV;
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
if (YV < 0) {
|
||||
YV = 0;
|
||||
BC = 1;
|
||||
}
|
||||
if (YV > IV) {
|
||||
YV = IV;
|
||||
BC = 1;
|
||||
}
|
||||
BC--;
|
||||
if (!BC) {
|
||||
BC = IC;
|
||||
if (YD)
|
||||
YV = IV;
|
||||
YD ^= 1;
|
||||
}
|
||||
if (y > 164)
|
||||
y = 164;
|
||||
// 8 311
|
||||
if (x < 1 || x > (319 - actor->_sizeX)) {
|
||||
if (!actor->_dead)
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
}
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
actor->_x = x;
|
||||
actor->_y = y;
|
||||
|
||||
//done:
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull explode
|
||||
int shotMovementNine(Actor *actor) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame == 3) {
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
return 0;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull - stalagtites
|
||||
int shotMovementTen(Actor *actor) {
|
||||
bool check = false;
|
||||
actor->_y += 2;
|
||||
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
check = true;
|
||||
}
|
||||
if (actor->_y > 160 || check) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef YD
|
||||
#undef XD
|
||||
#define YA actor->_i1
|
||||
#define XA actor->_i2
|
||||
#define YD actor->_i3
|
||||
#define XD actor->_i4
|
||||
#define DIR actor->_i5
|
||||
#define CNT actor->_i6
|
||||
|
||||
void calc_angle(const int x1, const int y1, const int x2, const int y2, Actor *actor) {
|
||||
if (x1 < x2) {
|
||||
XA = -2;
|
||||
XD = x2 - x1;
|
||||
} else if (x1 > x2) {
|
||||
XA = 2;
|
||||
XD = x1 - x2;
|
||||
} else {
|
||||
XA = 0;
|
||||
XD = 0;
|
||||
}
|
||||
|
||||
if (y1 < y2) {
|
||||
YA = -2;
|
||||
YD = y2 - y1;
|
||||
} else if (y1 > y2) {
|
||||
YA = 2;
|
||||
YD = y1 - y2;
|
||||
} else {
|
||||
YA = 0;
|
||||
YD = 0;
|
||||
}
|
||||
|
||||
if (YD >= XD)
|
||||
DIR = 1;
|
||||
else
|
||||
DIR = 0;
|
||||
CNT = 0;
|
||||
}
|
||||
|
||||
// Angle throw
|
||||
int shotMovementEleven(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp1) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp1 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkMove3(x1, y1, actor)) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
} else
|
||||
nextFrame(actor);
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Angle throw Loki
|
||||
int shotMovementTwelve(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp5) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp5 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (x1 < 16 || x1 > 287 || y1 < 16 || y1 > 159) {
|
||||
calc_angle(g_events->getRandomNumber(319),
|
||||
g_events->getRandomNumber(191), x1, y1, actor);
|
||||
actor->_moveType = 13;
|
||||
actor->_temp4 = 240;
|
||||
actor->_nextFrame = 2;
|
||||
} else {
|
||||
if (overlap(x1 + 2, y1 + 2, x1 + 14, y1 + 14, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
actor->_x = x1;
|
||||
actor->_y = y1;
|
||||
}
|
||||
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 1)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Angle throw Loki-2
|
||||
int shotMovementThirteen(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp5) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp5 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->_temp4)
|
||||
actor->_temp4--;
|
||||
|
||||
if (!actor->_temp4) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
_G(appleDropCounter++);
|
||||
if (_G(appleDropCounter) > 4) {
|
||||
if (dropObject(actor, 5))
|
||||
_G(appleDropCounter) = 0;
|
||||
else
|
||||
_G(appleDropCounter) = 4;
|
||||
} else
|
||||
dropObject(actor, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x1 < 16 || x1 > 287 || y1 < 16 || y1 > 159) {
|
||||
if (x1 < 16 || x1 > 287)
|
||||
XA = 0 - XA;
|
||||
else
|
||||
YA = 0 - YA;
|
||||
} else {
|
||||
if (overlap(x1 + 4, y1 + 4, x1 + 12, y1 + 12, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
actor->_x = x1;
|
||||
actor->_y = y1;
|
||||
}
|
||||
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 2;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
33
engines/got/game/shot_movement.h
Normal file
33
engines/got/game/shot_movement.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_SHOT_MOVEMENT_H
|
||||
#define GOT_GAME_SHOT_MOVEMENT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const shotMovementFunc[]) (Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
222
engines/got/game/shot_pattern.cpp
Normal file
222
engines/got/game/shot_pattern.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
/* 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/shot_pattern.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int shotPatternNone(Actor *actor);
|
||||
int shotPatternOne(Actor *actor);
|
||||
int shotPatternTwo(Actor *actor);
|
||||
int shotPatternThree(Actor *actor);
|
||||
int shotPatternFour(Actor *actor);
|
||||
int shotPatternFive(Actor *actor);
|
||||
int shotPatternSix(Actor *actor);
|
||||
int shotPatternSeven(Actor *actor);
|
||||
int shotPatternEight(Actor *actor);
|
||||
|
||||
int (*const shotPatternFunc[])(Actor *actor) = {
|
||||
shotPatternNone,
|
||||
shotPatternOne,
|
||||
shotPatternTwo,
|
||||
shotPatternThree,
|
||||
shotPatternFour,
|
||||
shotPatternFive,
|
||||
shotPatternSix,
|
||||
shotPatternSeven,
|
||||
shotPatternEight,
|
||||
};
|
||||
|
||||
// No shooting
|
||||
int shotPatternNone(Actor *actor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Uni-directional seek
|
||||
int shotPatternOne(Actor *actor) {
|
||||
switch (actor->_lastDir) {
|
||||
case 0:
|
||||
if (ABS(_G(thorX1) - actor->_x) < 8) {
|
||||
if (actor->_y > _G(thorRealY1)) { //r
|
||||
if (actorShoots(actor, 0))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (ABS(_G(thorX1) - actor->_x) < 8) {
|
||||
if (actor->_y < _G(thorRealY1)) { //r
|
||||
if (actorShoots(actor, 1))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (ABS(_G(thorRealY1) - actor->_y) < 8) { //r
|
||||
if (actor->_x > _G(thorX1)) {
|
||||
if (actorShoots(actor, 2))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (ABS(_G(thorRealY1) - actor->_y) < 8) { //r
|
||||
if (actor->_x < _G(thorX1)) {
|
||||
if (actorShoots(actor, 3))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Omni directional
|
||||
int shotPatternTwo(Actor *actor) {
|
||||
if (ABS(_G(thor)->_x - actor->_x) < 8) {
|
||||
if (_G(thor)->_y > actor->_y)
|
||||
actorShoots(actor, 1);
|
||||
else if (_G(thor)->_y < actor->_y)
|
||||
actorShoots(actor, 0);
|
||||
else
|
||||
return 0;
|
||||
} else if (ABS(_G(thor)->_y - actor->_y) < 8) {
|
||||
if (_G(thor)->_x > actor->_x)
|
||||
actorShoots(actor, 3);
|
||||
else if (_G(thor)->_x < actor->_x)
|
||||
actorShoots(actor, 2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Uni directional (backwards)
|
||||
int shotPatternThree(Actor *actor) {
|
||||
const int oldDir = actor->_lastDir;
|
||||
if (shotPatternOne(actor)) {
|
||||
actor->_lastDir = reverseDirection(actor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
actor->_lastDir = reverseDirection(actor);
|
||||
shotPatternOne(actor);
|
||||
actor->_lastDir = oldDir;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Omni-directional not solid shot
|
||||
int shotPatternFour(Actor *actor) {
|
||||
if (ABS(_G(thor)->_x - actor->_x) < 8) {
|
||||
if (_G(thor)->_y > actor->_y)
|
||||
actorAlwaysShoots(actor, 1);
|
||||
else if (_G(thor)->_y < actor->_y)
|
||||
actorAlwaysShoots(actor, 0);
|
||||
else
|
||||
return 0;
|
||||
} else if (ABS(_G(thor)->_y - actor->_y) < 8) {
|
||||
if (_G(thor)->_x > actor->_x)
|
||||
actorAlwaysShoots(actor, 3);
|
||||
else if (_G(thor)->_x < actor->_x)
|
||||
actorAlwaysShoots(actor, 2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Boss - snake
|
||||
int shotPatternFive(Actor *actor) {
|
||||
if (_G(rand1) < 15 && (actor->_temp1 == 0) && (actor->_temp2 == 0)) {
|
||||
actor->_y += 16;
|
||||
actor->_numShotsAllowed = 3 + _G(setup)._difficultyLevel;
|
||||
actorShoots(actor, 2);
|
||||
playSound(BOSS12, false);
|
||||
|
||||
const int num = actor->_shotActor;
|
||||
actor->_shotCountdown = 50;
|
||||
_G(actor[num])._temp3 = 120;
|
||||
_G(actor[num])._temp4 = 5 + (_G(rand2) % 17);
|
||||
_G(actor[num])._temp5 = _G(actor[num])._temp4;
|
||||
actor->_y -= 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4 surrounding squares
|
||||
int shotPatternSix(Actor *actor) {
|
||||
const int pos = ((actor->_x) / 16) + (((actor->_y) / 16) * 20);
|
||||
|
||||
if (_G(thorPos) == pos - 20)
|
||||
actorShoots(actor, 0);
|
||||
else if (_G(thorPos) == pos + 20)
|
||||
actorShoots(actor, 1);
|
||||
else if (_G(thorPos) == pos - 1)
|
||||
actorShoots(actor, 2);
|
||||
else if (_G(thorPos) == pos + 1)
|
||||
actorShoots(actor, 3);
|
||||
else
|
||||
return 0;
|
||||
|
||||
actor->_frameSequence[3] = 3;
|
||||
actor->_nextFrame = 3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// none
|
||||
int shotPatternSeven(Actor *actor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// random
|
||||
int shotPatternEight(Actor *actor) {
|
||||
if (!actor->_i2) {
|
||||
actor->_i1 = actor->_funcPass;
|
||||
actor->_i2 = 1;
|
||||
}
|
||||
|
||||
if (actor->_i1) {
|
||||
actor->_i1--;
|
||||
} else if (_G(rand1) < 10) {
|
||||
actor->_i1 = actor->_funcPass;
|
||||
actor->_i2 = _G(thorRealY1);
|
||||
actorShoots(actor, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
33
engines/got/game/shot_pattern.h
Normal file
33
engines/got/game/shot_pattern.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_SHOT_PATTERN_H
|
||||
#define GOT_GAME_SHOT_PATTERN_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const shotPatternFunc[])(Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
290
engines/got/game/special_tile.cpp
Normal file
290
engines/got/game/special_tile.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/* 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/special_tile.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/object.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int openDoor1(int y, int x);
|
||||
int cashDoor1(int y, int x, int amount);
|
||||
void eraseDoor(int x, int y);
|
||||
|
||||
int specialTileThor(const int x, const int y, const int icon) {
|
||||
int cx, cy;
|
||||
|
||||
int f = 0;
|
||||
switch (icon) {
|
||||
case 201:
|
||||
return openDoor1(x, y);
|
||||
case 202:
|
||||
if (GAME3) {
|
||||
if (_G(thorInfo)._inventory & 64) {
|
||||
if (_G(thorInfo)._object == 4) {
|
||||
eraseDoor(y, x);
|
||||
deleteObject();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_G(thor)->_x > 300)
|
||||
// Ending bridge
|
||||
_G(endTile) = true;
|
||||
return 1;
|
||||
case 203:
|
||||
if (!GAME1) {
|
||||
if ((_G(thorInfo)._inventory & 64) && _G(thorInfo)._object == 5) {
|
||||
odinSpeaks(2012, 0);
|
||||
deleteObject();
|
||||
_G(setup).f10 = true;
|
||||
} else if (!_G(setup).f10) {
|
||||
odinSpeaks(2011, 0);
|
||||
_G(setup).f10 = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 204:
|
||||
if (GAME2) {
|
||||
if (!_G(setup).f19)
|
||||
_G(slipFlag) = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GAME3) {
|
||||
if (_G(thor)->_x < 4)
|
||||
_G(endTile) = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 205:
|
||||
if (!_G(diag) && _G(thor)->_dir != 1)
|
||||
return 1;
|
||||
break;
|
||||
case 206:
|
||||
if (!_G(diag) && _G(thor)->_dir != 0)
|
||||
return 1;
|
||||
break;
|
||||
case 207:
|
||||
if (!_G(diag) && _G(thor)->_dir != 3)
|
||||
return 1;
|
||||
break;
|
||||
case 208:
|
||||
if (!_G(diag) && _G(thor)->_dir != 2)
|
||||
return 1;
|
||||
break;
|
||||
case 209:
|
||||
return cashDoor1(x, y, 10);
|
||||
case 210:
|
||||
return cashDoor1(x, y, 100);
|
||||
case 211:
|
||||
if (GAME1) {
|
||||
placeTile(y, x, 79);
|
||||
_G(exitFlag) = 2;
|
||||
} else if (GAME2) {
|
||||
if (_G(thor)->_dir == 0 && _G(setup).f29 && _G(setup).f21 && !_G(setup).f22) {
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
actorVisible(3);
|
||||
actorVisible(4);
|
||||
actorVisible(5);
|
||||
Common::fill(_G(scrn)._actorInvis, _G(scrn)._actorInvis + 16, 0);
|
||||
_G(thunderSnakeCounter) = 60;
|
||||
playSound(THUNDER, true);
|
||||
_G(setup).f22 = true;
|
||||
}
|
||||
} else {
|
||||
// Game 3
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
case 212:
|
||||
case 213:
|
||||
return 0;
|
||||
case 214: // Teleport tiles
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
if ((GAME2 && icon == 217) || GAME3) {
|
||||
cx = (_G(thorX1) + 7) / 16;
|
||||
cy = (_G(thorRealY1) + 8) / 16;
|
||||
if (_G(scrn)._iconGrid[cy][cx] == icon) {
|
||||
_G(thor)->_vulnerableCountdown = STAMINA;
|
||||
playSound(WOOP, false);
|
||||
|
||||
const int nt = _G(scrn)._newLevelLocation[icon - 214];
|
||||
const int displayPage = _G(pge);
|
||||
const int drawPage = _G(pge) ^ 1;
|
||||
|
||||
_G(thor)->_lastX[displayPage] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[displayPage] = _G(thor)->_y;
|
||||
_G(thor)->_x = (nt % 20) * 16;
|
||||
_G(thor)->_y = ((nt / 20) * 16) - 2;
|
||||
_G(thor)->_lastX[drawPage] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[drawPage] = _G(thor)->_y;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 218:
|
||||
case 219:
|
||||
// Hole tiles
|
||||
f = 1;
|
||||
// fall through
|
||||
case 220:
|
||||
case 221:
|
||||
case 222:
|
||||
case 223:
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
case 228:
|
||||
case 229:
|
||||
// Hole tiles
|
||||
cx = (_G(thorX1) + 7) / 16;
|
||||
cy = (_G(thorRealY1) + 8) / 16;
|
||||
if (_G(scrn)._iconGrid[cy][cx] == icon) {
|
||||
_G(thor)->_vulnerableCountdown = STAMINA;
|
||||
if (icon < 224 && icon > 219)
|
||||
playSound(FALL, false);
|
||||
|
||||
_G(newLevel) = _G(scrn)._newLevel[icon - 220 + (f * 6)];
|
||||
_G(warpScroll) = false;
|
||||
if (_G(newLevel) > 119) {
|
||||
_G(warpScroll) = true;
|
||||
_G(newLevel) -= 128;
|
||||
}
|
||||
|
||||
_G(newLevelTile) = _G(scrn)._newLevelLocation[icon - 220 + (f * 6)];
|
||||
_G(warpFlag) = true;
|
||||
|
||||
if (_G(warpScroll)) {
|
||||
if (_G(thor)->_dir == 0)
|
||||
_G(thor)->_y = 175;
|
||||
else if (_G(thor)->_dir == 1)
|
||||
_G(thor)->_y = 0;
|
||||
else if (_G(thor)->_dir == 2)
|
||||
_G(thor)->_x = 304;
|
||||
else if (_G(thor)->_dir == 3)
|
||||
_G(thor)->_x = 0;
|
||||
} else {
|
||||
_G(thor)->_x = (_G(newLevelTile) % 20) * 16;
|
||||
_G(thor)->_y = ((_G(newLevelTile) / 20) * 16) - 2;
|
||||
}
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int specialTile(const Actor *actor, int x, int y, const int icon) {
|
||||
switch (icon) {
|
||||
case 201:
|
||||
case 202:
|
||||
case 203:
|
||||
case 204:
|
||||
break;
|
||||
case 205:
|
||||
case 206:
|
||||
case 207:
|
||||
case 208:
|
||||
return 1;
|
||||
case 209:
|
||||
case 210:
|
||||
case 214:
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
return 0;
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
if (!actor->_flying)
|
||||
return 0;
|
||||
return 1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eraseDoor(const int x, const int y) {
|
||||
playSound(DOOR, false);
|
||||
_G(scrn)._iconGrid[y][x] = _G(scrn)._backgroundColor;
|
||||
}
|
||||
|
||||
int openDoor1(const int y, const int x) {
|
||||
if (_G(thorInfo)._keys > 0) {
|
||||
eraseDoor(x, y);
|
||||
_G(thorInfo)._keys--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_G(keyDoorInform)) {
|
||||
odinSpeaks(2003, 0);
|
||||
_G(keyDoorInform) = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashDoor1(const int y, const int x, const int amount) {
|
||||
if (_G(thorInfo)._jewels >= amount) {
|
||||
eraseDoor(x, y);
|
||||
_G(thorInfo)._jewels -= amount;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (amount == 10 && !_G(cashDoor1Inform)) {
|
||||
odinSpeaks(2005, 0);
|
||||
_G(cashDoor1Inform) = true;
|
||||
}
|
||||
|
||||
if (amount == 100 && !_G(cashDoor2Inform)) {
|
||||
odinSpeaks(2004, 0);
|
||||
_G(cashDoor2Inform) = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
34
engines/got/game/special_tile.h
Normal file
34
engines/got/game/special_tile.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_SPECIAL_TILE_H
|
||||
#define GOT_GAME_SPECIAL_TILE_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int specialTileThor(int x, int y, int icon);
|
||||
extern int specialTile(const Actor *actor, int x, int y, int icon);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
67
engines/got/game/status.cpp
Normal file
67
engines/got/game/status.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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/status.h"
|
||||
#include "got/events.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void addJewels(int num) {
|
||||
_G(thorInfo)._jewels = CLIP(_G(thorInfo)._jewels + num, 0, 999);
|
||||
}
|
||||
|
||||
void addScore(int num) {
|
||||
_G(thorInfo)._score = CLIP(_G(thorInfo)._score + num, 0l, 999999l);
|
||||
}
|
||||
|
||||
void addMagic(int num) {
|
||||
_G(thorInfo)._magic = CLIP(_G(thorInfo)._magic + num, 0, 150);
|
||||
}
|
||||
|
||||
void addHealth(int num) {
|
||||
_G(thor)->_health = CLIP(_G(thor)->_health + num, 0, 150);
|
||||
|
||||
if (_G(thor)->_health < 1)
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
}
|
||||
|
||||
void addKeys(int num) {
|
||||
_G(thorInfo)._keys = CLIP(_G(thorInfo)._keys + num, 0, 99);
|
||||
}
|
||||
|
||||
void fillHealth() {
|
||||
addHealth(150);
|
||||
}
|
||||
|
||||
void fillMagic() {
|
||||
addMagic(150);
|
||||
}
|
||||
|
||||
void fillScore(int num, const char *endMessage) {
|
||||
GameMessage msg("FILL_SCORE");
|
||||
if (endMessage)
|
||||
msg._stringValue = endMessage;
|
||||
msg._value = num;
|
||||
g_events->send("GameStatus", msg);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
38
engines/got/game/status.h
Normal file
38
engines/got/game/status.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_GAME_STATUS_H
|
||||
#define GOT_GAME_STATUS_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void addJewels(int num);
|
||||
extern void addScore(int num);
|
||||
extern void addMagic(int num);
|
||||
extern void addHealth(int num);
|
||||
extern void addKeys(int num);
|
||||
extern void fillHealth();
|
||||
extern void fillMagic();
|
||||
extern void fillScore(int num, const char *endMessage = nullptr);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user