/* 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "startrek/room.h" #define OBJECT_MONSTER 8 #define OBJECT_THROWN_FERN 10 // The log in the middle of this room has odd "hitboxes". The top half is hotspot 0x20, // while the bottom half is hotspot 0x22. You need to use the redshirt on the top half to // cross over. Not sure why this is. #define HOTSPOT_LEFT_EXIT 0x20 #define HOTSPOT_FERN 0x21 #define HOTSPOT_LOG 0x22 #define HOTSPOT_WATER 0x23 #define HOTSPOT_INSECTS_1 0x24 #define HOTSPOT_INSECTS_2 0x25 #define HOTSPOT_CAVE 0x26 namespace StarTrek { extern const RoomAction feather5ActionList[] = { { {ACTION_TICK, 1, 0, 0}, &Room::feather5Tick1 }, { {ACTION_TOUCHED_HOTSPOT, 0, 0, 0}, &Room::feather5TouchedHotspot0 }, { {ACTION_USE, OBJECT_SPOCK, HOTSPOT_FERN, 0}, &Room::feather5UseSpockOnFern }, { {ACTION_USE, OBJECT_MCCOY, HOTSPOT_FERN, 0}, &Room::feather5UseMccoyOnFern }, { {ACTION_USE, OBJECT_REDSHIRT, HOTSPOT_FERN, 0}, &Room::feather5UseRedshirtOnFern }, { {ACTION_USE, OBJECT_REDSHIRT, HOTSPOT_LEFT_EXIT, 0}, &Room::feather5UseRedshirtOnLeftExit }, { {ACTION_DONE_WALK, 8, 0, 0}, &Room::feather5RedshirtReachedLog }, { {ACTION_DONE_ANIM, 8, 0, 0}, &Room::feather5RedshirtDeathFinished }, { {ACTION_USE, OBJECT_SPOCK, HOTSPOT_LEFT_EXIT, 0}, &Room::feather5UseSpockOnLeftExit }, { {ACTION_USE, OBJECT_MCCOY, HOTSPOT_LEFT_EXIT, 0}, &Room::feather5UseMccoyOnLeftExit }, { {ACTION_USE, OBJECT_ISNAKE, OBJECT_KIRK, 0}, &Room::feather5UseSnakeOnKirk }, { {ACTION_USE, OBJECT_ISNAKE, OBJECT_SPOCK, 0}, &Room::feather5UseSnakeOnSpock }, { {ACTION_USE, OBJECT_ISNAKE, OBJECT_MCCOY, 0}, &Room::feather5UseSnakeOnMccoy }, { {ACTION_USE, OBJECT_ISNAKE, OBJECT_REDSHIRT, 0}, &Room::feather5UseSnakeOnRedshirt }, { {ACTION_USE, OBJECT_ISNAKE, HOTSPOT_WATER, 0}, &Room::feather5UseSnakeOnWater }, { {ACTION_USE, OBJECT_IKNIFE, OBJECT_KIRK, 0}, &Room::feather5UseKnifeOnKirk }, { {ACTION_USE, OBJECT_IKNIFE, OBJECT_SPOCK, 0}, &Room::feather5UseKnifeOnSpock }, { {ACTION_USE, OBJECT_IKNIFE, OBJECT_MCCOY, 0}, &Room::feather5UseKnifeOnMccoy }, { {ACTION_USE, OBJECT_IKNIFE, OBJECT_REDSHIRT, 0}, &Room::feather5UseKnifeOnRedshirt }, { {ACTION_USE, OBJECT_IKNIFE, HOTSPOT_WATER, 0}, &Room::feather5UseKnifeOnWater }, { {ACTION_USE, OBJECT_IKNIFE, OBJECT_MONSTER, 0}, &Room::feather5UseKnifeOnMonster }, { {ACTION_GET, HOTSPOT_FERN, 0, 0}, &Room::feather5GetFern }, { {ACTION_USE, OBJECT_IKNIFE, HOTSPOT_FERN, 0}, &Room::feather5UseKnifeOnFern }, { {ACTION_DONE_WALK, 1, 0, 0}, &Room::feather5ReachedFern }, { {ACTION_DONE_ANIM, 1, 0, 0}, &Room::feather5PickedUpFern }, { {ACTION_USE, OBJECT_IFERN, OBJECT_MONSTER, 0}, &Room::feather5UseFernOnMonster }, { {ACTION_USE, OBJECT_IFERN, HOTSPOT_WATER, 0}, &Room::feather5UseFernOnMonster }, { {ACTION_DONE_WALK, 2, 0, 0}, &Room::feather5ReachedPositionToUseFern }, { {ACTION_DONE_ANIM, 2, 0, 0}, &Room::feather5DoneThrowingFern }, { {ACTION_DONE_ANIM, 3, 0, 0}, &Room::feather5FernFellIntoWater }, { {ACTION_TIMER_EXPIRED, 1, 0, 0}, &Room::feather5Timer1Expired }, { {ACTION_USE, OBJECT_IROCK, OBJECT_SPOCK, 0}, &Room::feather5UseRockOnSpock }, { {ACTION_USE, OBJECT_IROCK, OBJECT_MCCOY, 0}, &Room::feather5UseRockOnMccoy }, { {ACTION_USE, OBJECT_IROCK, OBJECT_REDSHIRT, 0}, &Room::feather5UseRockOnRedshirt }, { {ACTION_USE, OBJECT_SPOCK, OBJECT_THROWN_FERN, 0}, &Room::feather5UseCrewmanOnThrownFern }, { {ACTION_USE, OBJECT_MCCOY, OBJECT_THROWN_FERN, 0}, &Room::feather5UseCrewmanOnThrownFern }, { {ACTION_USE, OBJECT_REDSHIRT, OBJECT_THROWN_FERN, 0}, &Room::feather5UseCrewmanOnThrownFern }, { {ACTION_USE, OBJECT_SPOCK, OBJECT_MONSTER, 0}, &Room::feather5UseSpockOnMonster }, { {ACTION_USE, OBJECT_MCCOY, OBJECT_MONSTER, 0}, &Room::feather5UseMccoyOnMonster }, { {ACTION_USE, OBJECT_REDSHIRT, OBJECT_MONSTER, 0}, &Room::feather5UseRedshirtOnMonster }, { {ACTION_USE, OBJECT_IPHASERS, 0xff, 0}, &Room::feather5UsePhaser }, { {ACTION_USE, OBJECT_IPHASERK, 0xff, 0}, &Room::feather5UsePhaser }, { {ACTION_LOOK, 0xff, 0, 0}, &Room::feather5LookAnywhere }, { {ACTION_LOOK, HOTSPOT_LOG, 0, 0}, &Room::feather5LookAtLog }, { {ACTION_LOOK, HOTSPOT_WATER, 0, 0}, &Room::feather5LookAtWater }, { {ACTION_LOOK, HOTSPOT_FERN, 0, 0}, &Room::feather5LookAtFern }, { {ACTION_LOOK, HOTSPOT_INSECTS_1, 0, 0}, &Room::feather5LookAtInsects }, { {ACTION_LOOK, HOTSPOT_INSECTS_2, 0, 0}, &Room::feather5LookAtInsects }, { {ACTION_LOOK, HOTSPOT_CAVE, 0, 0}, &Room::feather5LookAtCave }, { {ACTION_LOOK, OBJECT_MONSTER, 0, 0}, &Room::feather5LookAtMonster }, { {ACTION_LOOK, OBJECT_SPOCK, 0, 0}, &Room::feather5LookAtSpock }, { {ACTION_LOOK, OBJECT_KIRK, 0, 0}, &Room::feather5LookAtKirk }, { {ACTION_LOOK, OBJECT_MCCOY, 0, 0}, &Room::feather5LookAtMccoy }, { {ACTION_LOOK, OBJECT_REDSHIRT, 0, 0}, &Room::feather5LookAtRedshirt }, { {ACTION_TALK, OBJECT_MCCOY, 0, 0}, &Room::feather5TalkToMccoy }, { {ACTION_TALK, OBJECT_SPOCK, 0, 0}, &Room::feather5TalkToSpock }, { {ACTION_TALK, OBJECT_REDSHIRT, 0, 0}, &Room::feather5TalkToRedshirt }, { {ACTION_USE, OBJECT_IMTRICOR, HOTSPOT_WATER, 0}, &Room::feather5UseMTricorderOnWater }, { {ACTION_USE, OBJECT_IMTRICOR, OBJECT_MONSTER, 0}, &Room::feather5UseMTricorderOnMonster }, { {ACTION_USE, OBJECT_ISTRICOR, OBJECT_MONSTER, 0}, &Room::feather5UseSTricorderOnMonster }, { {ACTION_USE, OBJECT_ISTRICOR, 0xff, 0}, &Room::feather5UseSTricorderAnywhere }, { {ACTION_USE, OBJECT_ISTRICOR, HOTSPOT_WATER, 0}, &Room::feather5UseSTricorderOnWater }, { {ACTION_USE, OBJECT_ISTRICOR, HOTSPOT_FERN, 0}, &Room::feather5UseSTricorderOnFern }, { {ACTION_USE, OBJECT_IMEDKIT, 0xff, 0}, &Room::feather5UseMedkitAnywhere }, }; extern const int feather5NumActions = ARRAYSIZE(feather5ActionList); void Room::feather5Tick1() { playVoc("FEA5LOOP"); playMidiMusicTracks(29); if (!_awayMission->feather.waterMonsterRetreated) loadActorAnim(OBJECT_MONSTER, "s5r5os", 0x4e, 0xa4); else loadMapFile("feath5b"); } void Room::feather5TouchedHotspot0() { // Approached the log if (!_awayMission->feather.waterMonsterRetreated) { showText(TX_SPEAKER_SPOCK, TX_FEA5_005); if (!_awayMission->redshirtDead) showText(TX_SPEAKER_STRAGEY, TX_FEA5_033); } } void Room::feather5UseSpockOnFern() { showText(TX_SPEAKER_SPOCK, TX_FEA5_004); } void Room::feather5UseMccoyOnFern() { showText(TX_SPEAKER_MCCOY, TX_FEA5_009); } void Room::feather5UseRedshirtOnFern() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_035); } void Room::feather5UseRedshirtOnLeftExit() { if (!_awayMission->feather.waterMonsterRetreated) { showText(TX_SPEAKER_STRAGEY, TX_FEA5_034); _awayMission->disableInput = true; loadMapFile("feath5b"); walkCrewmanC(OBJECT_REDSHIRT, 0x8f, 0x64, &Room::feather5RedshirtReachedLog); } } void Room::feather5RedshirtReachedLog() { playMidiMusicTracks(2); playVoc("TENTICL2"); loadActorAnim(OBJECT_MONSTER, "s5r5oh", 0x4e, 0xa4); loadActorAnimC(OBJECT_REDSHIRT, "s5r5ol", 0x8f, 0x64, &Room::feather5RedshirtDeathFinished); _awayMission->feather.waterMonsterRetreated = true; _awayMission->redshirtDead = true; } void Room::feather5RedshirtDeathFinished() { loadActorStandAnim(OBJECT_REDSHIRT); _awayMission->disableInput = false; } void Room::feather5UseSpockOnLeftExit() { if (!_awayMission->feather.waterMonsterRetreated) showText(TX_SPEAKER_SPOCK, TX_FEA5_002); } void Room::feather5UseMccoyOnLeftExit() { if (!_awayMission->feather.waterMonsterRetreated) showText(TX_SPEAKER_MCCOY, TX_FEA5_015); } void Room::feather5UseSnakeOnKirk() { showText(TX_SPEAKER_KIRK, TX_FEA5N010); } void Room::feather5UseSnakeOnSpock() { showText(TX_SPEAKER_SPOCK, TX_FEA5_032); } void Room::feather5UseSnakeOnMccoy() { showText(TX_SPEAKER_MCCOY, TX_FEA5_020); } void Room::feather5UseSnakeOnRedshirt() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_040); } void Room::feather5UseSnakeOnWater() { showDescription(TX_FEA5N011); loseItem(OBJECT_ISNAKE); } void Room::feather5UseKnifeOnKirk() { // ENHANCEMENT: Originally showed TX_DEM0_020 here ("Jim, are you out of your mind?") // However, there is an unused audio file for text that otherwise only appears in the // mac version. (DOS floppy version has yet another variation for this text.) // We'll use that unused audio file here... showText(TX_SPEAKER_KIRK, TX_FEA5_001); } void Room::feather5UseKnifeOnSpock() { showText(TX_SPEAKER_SPOCK, TX_FEA5_029); } void Room::feather5UseKnifeOnMccoy() { showText(TX_SPEAKER_MCCOY, TX_FEA5_008); } void Room::feather5UseKnifeOnRedshirt() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_039); } void Room::feather5UseKnifeOnWater() { showText(TX_SPEAKER_MCCOY, TX_FEA5_018); } void Room::feather5UseKnifeOnMonster() { showText(TX_SPEAKER_SPOCK, TX_FEA5_006); } void Room::feather5GetFern() { showDescription(TX_FEA5N008); } void Room::feather5UseKnifeOnFern() { if (_awayMission->feather.gotFern) showDescription(TX_FEA5N015); else { walkCrewmanC(OBJECT_KIRK, 0x106, 0x8a, &Room::feather5ReachedFern); _awayMission->disableInput = true; } } void Room::feather5ReachedFern() { loadActorAnimC(OBJECT_KIRK, "s5r5kf", -1, -1, &Room::feather5PickedUpFern); } void Room::feather5PickedUpFern() { _awayMission->disableInput = false; loadActorStandAnim(OBJECT_KIRK); giveItem(OBJECT_IFERN); _awayMission->feather.gotFern = true; } void Room::feather5UseFernOnMonster() { // BUG: Infinite score mechanism. Just keep throwing ferns into the water. _awayMission->feather.missionScore += 2; walkCrewmanC(OBJECT_KIRK, 0x106, 0x8a, &Room::feather5ReachedPositionToUseFern); _awayMission->disableInput = true; } void Room::feather5ReachedPositionToUseFern() { loadActorAnimC(OBJECT_KIRK, "s5r5kt", -1, -1, &Room::feather5DoneThrowingFern); loadActorAnimC(OBJECT_THROWN_FERN, "s5r5pt", 0xe6, 0x52, &Room::feather5FernFellIntoWater); } void Room::feather5DoneThrowingFern() { _awayMission->disableInput = false; loadActorStandAnim(OBJECT_KIRK); loseItem(OBJECT_IFERN); _awayMission->feather.gotFern = false; } void Room::feather5FernFellIntoWater() { if (!_awayMission->feather.waterMonsterRetreated) { _awayMission->feather.waterMonsterRetreated = true; _awayMission->timers[1] = 20; loadActorStandAnim(OBJECT_MONSTER); loadMapFile("feath5b"); } } void Room::feather5Timer1Expired() { // Spock explains that the creature retreated showText(TX_SPEAKER_SPOCK, TX_FEA5_025); } void Room::feather5UseRockOnSpock() { showText(TX_SPEAKER_SPOCK, TX_FEA5_027); } void Room::feather5UseRockOnMccoy() { showText(TX_SPEAKER_MCCOY, TX_FEA5_019); } void Room::feather5UseRockOnRedshirt() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_038); } void Room::feather5UseCrewmanOnThrownFern() { // This might be unused? The object in question (OBJECT_THROWN_FERN) shouldn't be // visible while player control is active. showDescription(TX_FEA5N003); } void Room::feather5UseSpockOnMonster() { showText(TX_SPEAKER_SPOCK, TX_FEA5_003); } void Room::feather5UseMccoyOnMonster() { showText(TX_SPEAKER_MCCOY, TX_FEA5_016); } void Room::feather5UseRedshirtOnMonster() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_037); } void Room::feather5UsePhaser() { showText(TX_SPEAKER_SPOCK, TX_FEA5_028); } void Room::feather5LookAnywhere() { showDescription(TX_FEA5N012); } void Room::feather5LookAtLog() { showDescription(TX_FEA5N007); } void Room::feather5LookAtWater() { showDescription(TX_FEA5N009); } void Room::feather5LookAtFern() { showDescription(TX_FEA5N014); } void Room::feather5LookAtInsects() { showDescription(TX_FEA5N005); } void Room::feather5LookAtCave() { showDescription(TX_FEA5N013); } void Room::feather5LookAtMonster() { showDescription(TX_FEA5N000); } void Room::feather5LookAtSpock() { showDescription(TX_FEA5N006); } void Room::feather5LookAtKirk() { if (!_awayMission->feather.waterMonsterRetreated) showDescription(TX_FEA5N001); else // ENHANCEMENT: Fall back to default behaviour instead of doing nothing _awayMission->rdfStillDoDefaultAction = true; } void Room::feather5LookAtMccoy() { if (!_awayMission->feather.waterMonsterRetreated) showDescription(TX_FEA5N002); else // ENHANCEMENT: Fall back to default behaviour instead of doing nothing _awayMission->rdfStillDoDefaultAction = true; } void Room::feather5LookAtRedshirt() { if (!_awayMission->feather.waterMonsterRetreated) showDescription(TX_FEA5N004); else // ENHANCEMENT: Fall back to default behaviour instead of doing nothing _awayMission->rdfStillDoDefaultAction = true; } void Room::feather5TalkToMccoy() { showText(TX_SPEAKER_MCCOY, TX_FEA5_007); } void Room::feather5TalkToSpock() { showText(TX_SPEAKER_SPOCK, TX_FEA5_022); } void Room::feather5TalkToRedshirt() { showText(TX_SPEAKER_STRAGEY, TX_FEA5_036); } void Room::feather5UseMTricorderOnWater() { if (_awayMission->feather.waterMonsterRetreated) mccoyScan(DIR_W, TX_FEA5_011); else mccoyScan(DIR_W, TX_FEA5_014); } void Room::feather5UseMTricorderOnMonster() { mccoyScan(DIR_W, TX_FEA5_013); } void Room::feather5UseSTricorderOnMonster() { spockScan(DIR_W, TX_FEA5_024); } void Room::feather5UseSTricorderAnywhere() { spockScan(DIR_W, TX_FEA5_026); } void Room::feather5UseSTricorderOnWater() { if (_awayMission->feather.waterMonsterRetreated) spockScan(DIR_W, TX_FEA5_031); else spockScan(DIR_W, TX_FEA5_030); } void Room::feather5UseSTricorderOnFern() { spockScan(DIR_N, TX_FEA5_023); } void Room::feather5UseMedkitAnywhere() { showText(TX_SPEAKER_MCCOY, TX_FEA5_010); } }