Files
scummvm-cursorfix/engines/got/game/object.cpp
2026-02-02 04:50:13 +01:00

438 lines
8.7 KiB
C++

/* 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