/* 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 . * */ #include "glk/comprehend/comprehend.h" #include "glk/comprehend/game_data.h" #include "glk/comprehend/game_tr1.h" #include "glk/comprehend/pics.h" namespace Glk { namespace Comprehend { enum RoomId { ROOM_CLAY_HUT = 7, ROOM_FIELD = 26 }; enum RoomFlag { ROOMFLAG_FOREST = 1 << 0, ROOMFLAG_WEREWOLF = 1 << 6, ROOMFLAG_VAMPIRE = 1 << 7 }; enum ItemId { ITEM_GOBLIN = 9, ITEM_SILVER_BULLET = 21, ITEM_BLACK_CAT = 23, ITEM_WEREWOLF = 33, ITEM_VAMPIRE = 38 }; struct TransylvaniaMonster { uint8 _object; uint8 _deadFlag; uint _roomAllowFlag; uint _minTurnsBefore; uint _randomness; }; const TransylvaniaMonster TransylvaniaGame1::WEREWOLF = { ITEM_WEREWOLF, 7, ROOMFLAG_WEREWOLF, 10, 190 }; const TransylvaniaMonster TransylvaniaGame1::VAMPIRE = { ITEM_VAMPIRE, 5, ROOMFLAG_VAMPIRE, 0, 200 }; static const GameStrings TR_STRINGS = { EXTRA_STRING_TABLE(0x8a) }; TransylvaniaGame1::TransylvaniaGame1() : ComprehendGameV1(), _miceReleased(false) { _gameDataFile = "tr.gda"; _stringFiles.push_back("MA.MS1"); _stringFiles.push_back("MB.MS1"); _stringFiles.push_back("MC.MS1"); _stringFiles.push_back("MD.MS1"); _stringFiles.push_back("ME.MS1"); _locationGraphicFiles.push_back("RA.MS1"); _locationGraphicFiles.push_back("RB.MS1"); _locationGraphicFiles.push_back("RC.MS1"); _itemGraphicFiles.push_back("OA.MS1"); _itemGraphicFiles.push_back("OB.MS1"); _itemGraphicFiles.push_back("OC.MS1"); _titleGraphicFile = "trtitle.ms1"; _gameStrings = &TR_STRINGS; } bool TransylvaniaGame1::updateMonster(const TransylvaniaMonster *monsterInfo) { Item *monster; Room *room; uint16 turn_count; room = &_rooms[_currentRoom]; if (!(room->_flags & monsterInfo->_roomAllowFlag)) return false; turn_count = _variables[VAR_TURN_COUNT]; monster = get_item(monsterInfo->_object); if (monster->_room == _currentRoom) { // The monster is in the current room - leave it there return true; } if (!_flags[monsterInfo->_deadFlag] && turn_count > monsterInfo->_minTurnsBefore) { /* * The monster is alive and allowed to move to the current * room. Randomly decide whether on not to. If not, move * it back to limbo. */ if (getRandomNumber(255) > monsterInfo->_randomness) { move_object(monster, _currentRoom); _variables[15] = turn_count + 1; } else { move_object(monster, ROOM_NOWHERE); } } return true; } bool TransylvaniaGame1::isMonsterInRoom(const TransylvaniaMonster *monsterInfo) { Item *monster = get_item(monsterInfo->_object); return monster->_room == _currentRoom; } int TransylvaniaGame1::roomIsSpecial(uint room_index, uint *roomDescString) { Room *room = &_rooms[room_index]; if (room_index == 0x28) { if (roomDescString) *roomDescString = room->_stringDesc; return ROOM_IS_DARK; } return ROOM_IS_NORMAL; } void TransylvaniaGame1::beforeTurn() { Room *room; if (!isMonsterInRoom(&WEREWOLF) && !isMonsterInRoom(&VAMPIRE)) { if (_currentRoom == ROOM_CLAY_HUT) { Item *blackCat = get_item(ITEM_BLACK_CAT); if (blackCat->_room == _currentRoom && getRandomNumber(255) >= 128) console_println(_strings[109].c_str()); goto done; } else if (_currentRoom == ROOM_FIELD) { Item *goblin = get_item(ITEM_GOBLIN); if (goblin->_room == _currentRoom) console_println(_strings[94 + getRandomNumber(3)].c_str()); goto done; } } if (updateMonster(&WEREWOLF) || updateMonster(&VAMPIRE)) goto done; room = &_rooms[_currentRoom]; if ((room->_flags & ROOMFLAG_FOREST) && (_variables[VAR_TURN_COUNT] % 255) >= 4 && getRandomNumber(255) < 40) { int stringNum = _miceReleased ? 108 : 107; console_println(_strings[stringNum].c_str()); // Until the mice are released, an eagle moves player to a random room if (!_miceReleased) { // Get new room to get moved to int roomNum = getRandomNumber(3) + 1; if (roomNum == _currentRoom) roomNum += 15; move_to(roomNum); // Make sure Werwolf and Vampire aren't present get_item(ITEM_WEREWOLF)->_room = 0xff; get_item(ITEM_VAMPIRE)->_room = 0xff; } } done: ComprehendGameV1::beforeTurn(); } void TransylvaniaGame1::synchronizeSave(Common::Serializer &s) { ComprehendGame::synchronizeSave(s); s.syncAsByte(_miceReleased); // As a post-step, ensure the vampire and werewolf aren't present get_item(ITEM_WEREWOLF)->_room = 0xff; get_item(ITEM_VAMPIRE)->_room = 0xff; } void TransylvaniaGame1::handleSpecialOpcode() { switch (_specialOpcode) { case 1: // Mice have been released _miceReleased = true; break; case 2: // Gun is fired. Drop the bullet in a random room get_item(ITEM_SILVER_BULLET)->_room = getRandomNumber(7) + 1; _updateFlags |= UPDATE_GRAPHICS; break; case 3: case 4: // Game over - failure console_println(_strings2[138].c_str()); game_restart(); break; case 5: // Won the game g_comprehend->showGraphics(); g_comprehend->drawLocationPicture(40); game_restart(); break; case 6: game_save(); break; case 7: game_restore(); break; case 8: // Restart game game_restart(); break; case 9: // Show the Zin screen in response to doing // 'sing some enchanted evening' in his cabin. g_comprehend->showGraphics(); g_comprehend->drawLocationPicture(41); console_get_key(); _updateFlags |= UPDATE_GRAPHICS; break; default: break; } } #define READ_LINE do { \ g_comprehend->readLine(buffer, sizeof(buffer)); \ if (g_comprehend->shouldQuit()) return; \ } while (strlen(buffer) == 0) void TransylvaniaGame1::beforeGame() { char buffer[128]; g_comprehend->setDisableSaves(true); // Draw the title g_comprehend->drawPicture(TITLE_IMAGE); // Print game information console_println("Story and graphics by Antonio Antiochia."); console_println("IBM version by Jeffrey A. Jay. Copyright 1987 POLARWARE, Inc."); g_comprehend->readChar(); // Welcome to Transylvania - sign your name console_println(_strings[0x20].c_str()); READ_LINE; // The player's name is stored in word 0 _replaceWords[0] = Common::String(buffer); // And your next of kin - This isn't stored by the game console_println(_strings[0x21].c_str()); READ_LINE; g_comprehend->setDisableSaves(false); } } // namespace Comprehend } // namespace Glk