mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
280 lines
6.7 KiB
C++
280 lines
6.7 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "glk/comprehend/comprehend.h"
|
|
#include "glk/comprehend/game_data.h"
|
|
#include "glk/comprehend/game_tr2.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 TransylvaniaGame2::WEREWOLF = {
|
|
ITEM_WEREWOLF, 7, ROOMFLAG_WEREWOLF, 10, 190
|
|
};
|
|
|
|
const TransylvaniaMonster TransylvaniaGame2::VAMPIRE = {
|
|
ITEM_VAMPIRE, 5, ROOMFLAG_VAMPIRE, 0, 200
|
|
};
|
|
|
|
static const GameStrings TR_STRINGS = {
|
|
EXTRA_STRING_TABLE(0x8a)
|
|
};
|
|
|
|
|
|
TransylvaniaGame2::TransylvaniaGame2() : ComprehendGameV2(),
|
|
_miceReleased(false) {
|
|
_gameDataFile = "g0";
|
|
|
|
_locationGraphicFiles.push_back("RA");
|
|
_locationGraphicFiles.push_back("RB");
|
|
_locationGraphicFiles.push_back("RC");
|
|
_itemGraphicFiles.push_back("OA");
|
|
_itemGraphicFiles.push_back("OB");
|
|
_itemGraphicFiles.push_back("OC");
|
|
|
|
_titleGraphicFile = "t0";
|
|
_gameStrings = &TR_STRINGS;
|
|
}
|
|
|
|
bool TransylvaniaGame2::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 TransylvaniaGame2::isMonsterInRoom(const TransylvaniaMonster *monsterInfo) {
|
|
Item *monster = get_item(monsterInfo->_object);
|
|
return monster->_room == _currentRoom;
|
|
}
|
|
|
|
int TransylvaniaGame2::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 TransylvaniaGame2::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:
|
|
ComprehendGameV2::beforeTurn();
|
|
}
|
|
|
|
void TransylvaniaGame2::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 TransylvaniaGame2::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 TransylvaniaGame2::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
|