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