mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-21 19:51:49 +00:00
556 lines
14 KiB
C++
556 lines
14 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 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"
|
|
|
|
namespace StarTrek {
|
|
|
|
// BUG: under certain circumstances, the klingons just stop firing?
|
|
|
|
void Room::demon1Tick1() {
|
|
playVoc("DEM1LOOP");
|
|
|
|
if (!_awayMission->demon.beatKlingons)
|
|
playMidiMusicTracks(1, -1);
|
|
|
|
if (_awayMission->demon.enteredFrom == 1) { // Entered from south
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_N;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_N;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_N;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_N;
|
|
} else if (_awayMission->demon.enteredFrom == 2) { // Entered from north?
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_S;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_S;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_S;
|
|
_awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_S;
|
|
}
|
|
|
|
if (!_awayMission->demon.beatKlingons) {
|
|
_awayMission->disableWalking = true;
|
|
_awayMission->timers[2] = 50;
|
|
} else {
|
|
loadActorAnim(8, "klg1d2", 0x120, 0x82, 0);
|
|
if (!_awayMission->demon.tookKlingonHand)
|
|
loadActorAnim(13, "klghnd", 0x10b, 0x8e, 0);
|
|
loadActorAnim(9, "klg2d2", 0xaa, 0x7c, 0);
|
|
loadActorAnim(10, "klg3d2", 0, 0, 0);
|
|
|
|
_roomVar.demon.klingonShot[0] = true;
|
|
_roomVar.demon.klingonShot[1] = true;
|
|
_roomVar.demon.klingonShot[2] = true;
|
|
_roomVar.demon.numKlingonsKilled = 3;
|
|
}
|
|
}
|
|
|
|
void Room::demon1WalkToCave() {
|
|
if (_roomVar.demon.numKlingonsKilled != 3)
|
|
return;
|
|
walkCrewman(OBJECT_KIRK, 0xa3, 0x56, 2);
|
|
}
|
|
|
|
void Room::demon1TouchedTopWarp() {
|
|
if (_awayMission->demon.warpsDisabled)
|
|
return;
|
|
loadRoomIndex(2, 1);
|
|
}
|
|
|
|
void Room::demon1TouchedBottomWarp() {
|
|
if (_awayMission->demon.warpsDisabled)
|
|
return;
|
|
loadRoomIndex(0, 0);
|
|
}
|
|
|
|
void Room::demon1Timer2Expired() {
|
|
if (_awayMission->demon.beatKlingons)
|
|
return;
|
|
_awayMission->demon.field37 = 1;
|
|
_awayMission->demon.beatKlingons = true;
|
|
_awayMission->demon.warpsDisabled = true;
|
|
_awayMission->timers[0] = 5;
|
|
_awayMission->timers[3] = 2;
|
|
_awayMission->timers[1] = 100;
|
|
loadActorAnim(8, "klg1u", 0x120, 0x82, 0);
|
|
}
|
|
|
|
void Room::demon1Timer0Expired() {
|
|
loadActorAnim(9, "klg2u", 0xaa, 0x7c, 0);
|
|
}
|
|
|
|
void Room::demon1Timer3Expired() {
|
|
loadActorAnim(10, "klg3u", 0xdb, 0x6d, 0);
|
|
}
|
|
|
|
void Room::demon1Timer1Expired() {
|
|
int shooter;
|
|
Common::String anim;
|
|
|
|
if (!_roomVar.demon.klingonShot[0]) {
|
|
anim = "klg1f";
|
|
shooter = 8;
|
|
|
|
switch (_roomVar.demon.attackIndex) {
|
|
case 0:
|
|
strcpy(_roomVar.demon.d6, "klg1fr");
|
|
break;
|
|
case 1:
|
|
strcpy(_roomVar.demon.d6, "klg1fm");
|
|
break;
|
|
case 2:
|
|
strcpy(_roomVar.demon.d6, "klg1fs");
|
|
break;
|
|
case 3:
|
|
strcpy(_roomVar.demon.d6, "klg1fk");
|
|
break;
|
|
default:
|
|
// TODO
|
|
return;
|
|
}
|
|
} else if (!_roomVar.demon.klingonShot[1]) {
|
|
anim = "klg2f";
|
|
shooter = 9;
|
|
switch (_roomVar.demon.attackIndex) {
|
|
case 0:
|
|
strcpy(_roomVar.demon.d6, "klg2fr");
|
|
break;
|
|
case 1:
|
|
strcpy(_roomVar.demon.d6, "klg2fm");
|
|
break;
|
|
case 2:
|
|
strcpy(_roomVar.demon.d6, "klg2fs");
|
|
break;
|
|
case 3:
|
|
strcpy(_roomVar.demon.d6, "klg2fk");
|
|
break;
|
|
default:
|
|
// TODO
|
|
return;
|
|
}
|
|
} else {
|
|
anim = "klg3f";
|
|
shooter = 10;
|
|
switch (_roomVar.demon.attackIndex) {
|
|
case 0:
|
|
strcpy(_roomVar.demon.d6, "klg3fr");
|
|
break;
|
|
case 1:
|
|
strcpy(_roomVar.demon.d6, "klg3fm");
|
|
break;
|
|
case 2:
|
|
strcpy(_roomVar.demon.d6, "klg3fs");
|
|
break;
|
|
case 3:
|
|
strcpy(_roomVar.demon.d6, "klg3fk");
|
|
break;
|
|
default:
|
|
// TODO
|
|
return;
|
|
}
|
|
}
|
|
|
|
loadActorAnim2(shooter, anim, -1, -1, 2);
|
|
}
|
|
|
|
void Room::demon1KlingonFinishedAimingWeapon() {
|
|
loadActorAnim(11, _roomVar.demon.d6, 0, 0, 0);
|
|
playSoundEffectIndex(0x06);
|
|
|
|
_roomVar.demon.attackIndex++;
|
|
int crewman = OBJECT_REDSHIRT;
|
|
if (_roomVar.demon.attackIndex == 1) {
|
|
loadActorAnim2(OBJECT_REDSHIRT, "rstunn", -1, -1, 0);
|
|
crewman = OBJECT_REDSHIRT;
|
|
} else if (_roomVar.demon.attackIndex == 2) {
|
|
loadActorAnim2(OBJECT_SPOCK, "sstunn", -1, -1, 0);
|
|
crewman = OBJECT_SPOCK;
|
|
} else if (_roomVar.demon.attackIndex == 3) {
|
|
loadActorAnim2(OBJECT_MCCOY, "mstune", -1, -1, 0);
|
|
crewman = OBJECT_MCCOY;
|
|
} else if (_roomVar.demon.attackIndex == 4) {
|
|
loadActorAnim2(OBJECT_KIRK, "kstunn", -1, -1, 1);
|
|
crewman = OBJECT_KIRK;
|
|
}
|
|
|
|
_awayMission->crewDirectionsAfterWalk[crewman] = DIR_N;
|
|
_awayMission->crewGetupTimers[crewman] = 650;
|
|
_awayMission->crewDownBitset |= (1 << crewman);
|
|
|
|
_awayMission->timers[1] = 100;
|
|
}
|
|
|
|
void Room::demon1KirkShot() {
|
|
showDescription(0, true);
|
|
showGameOverMenu();
|
|
}
|
|
|
|
void Room::demon1UsePhaserOnAnything() {
|
|
if (_roomVar.demon.numKlingonsKilled == 3)
|
|
showText(TX_SPEAKER_MCCOY, 11, true);
|
|
}
|
|
|
|
void Room::demon1UsePhaserOnKlingon1() {
|
|
if (_roomVar.demon.klingonShot[0])
|
|
return;
|
|
_awayMission->disableInput = 1;
|
|
_roomVar.demon.klingonShot[0] = true;
|
|
|
|
if (_roomVar.demon.kirkShooting) {
|
|
demon1ShootKlingon1();
|
|
} else {
|
|
loadActorAnim2(OBJECT_KIRK, "kfiren", -1, -1, 3);
|
|
_roomVar.demon.kirkShooting = true;
|
|
}
|
|
}
|
|
|
|
void Room::demon1ShootKlingon1() {
|
|
_roomVar.demon.numKlingonsKilled++;
|
|
if (_roomVar.demon.numKlingonsKilled == 3) {
|
|
_awayMission->timers[1] = 0;
|
|
_awayMission->timers[5] = 180;
|
|
_awayMission->timers[6] = 1;
|
|
_awayMission->demon.warpsDisabled = false;
|
|
_awayMission->disableWalking = false;
|
|
}
|
|
loadActorAnim(12, "s0ks1", 0, 0, 0);
|
|
playSoundEffectIndex(0x06);
|
|
playVoc("EFX19");
|
|
loadActorAnim2(8, "klg1d", 0x120, 0x84, 7);
|
|
}
|
|
|
|
void Room::demon1KlingonDropsHand() {
|
|
loadActorAnim(13, "klghnd", 0x10b, 0x8e, 0);
|
|
_awayMission->disableInput = 0;
|
|
_awayMission->timers[1] = 0;
|
|
showDescription(20, true);
|
|
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_REDSHIRT))
|
|
return;
|
|
|
|
showText(TX_SPEAKER_EVERTS, 25, true);
|
|
|
|
if (_roomVar.demon.numKlingonsKilled == 3)
|
|
return;
|
|
|
|
showText(TX_SPEAKER_KLINGON, 23 + FOLLOWUP_MESSAGE_OFFSET, true);
|
|
|
|
_awayMission->timers[1] = 1;
|
|
}
|
|
|
|
void Room::demon1UsePhaserOnKlingon2() {
|
|
if (_roomVar.demon.klingonShot[1])
|
|
return;
|
|
_awayMission->disableInput = 1;
|
|
_roomVar.demon.klingonShot[1] = true;
|
|
|
|
if (_roomVar.demon.kirkShooting) {
|
|
demon1ShootKlingon2();
|
|
} else {
|
|
loadActorAnim2(OBJECT_KIRK, "kfiren", -1, -1, 4);
|
|
_roomVar.demon.kirkShooting = true;
|
|
}
|
|
}
|
|
|
|
void Room::demon1ShootKlingon2() {
|
|
_roomVar.demon.numKlingonsKilled++;
|
|
if (_roomVar.demon.numKlingonsKilled == 3) {
|
|
_awayMission->timers[1] = 0;
|
|
_awayMission->timers[5] = 180;
|
|
_awayMission->timers[6] = 1;
|
|
_awayMission->demon.warpsDisabled = false;
|
|
_awayMission->disableWalking = false;
|
|
}
|
|
loadActorAnim(12, "s0ks2", 0, 0, 0);
|
|
playSoundEffectIndex(0x06);
|
|
loadActorAnim2(9, "klg2d", 0xaa, 0x7c, 0);
|
|
_awayMission->disableInput = 0;
|
|
}
|
|
|
|
void Room::demon1UsePhaserOnKlingon3() {
|
|
if (_roomVar.demon.klingonShot[2])
|
|
return;
|
|
_awayMission->disableInput = 1;
|
|
_roomVar.demon.klingonShot[2] = true;
|
|
|
|
if (_roomVar.demon.kirkShooting) {
|
|
demon1ShootKlingon3();
|
|
} else {
|
|
loadActorAnim2(OBJECT_KIRK, "kfiren", -1, -1, 5);
|
|
_roomVar.demon.kirkShooting = true;
|
|
}
|
|
}
|
|
|
|
void Room::demon1ShootKlingon3() {
|
|
_roomVar.demon.numKlingonsKilled++;
|
|
if (_roomVar.demon.numKlingonsKilled == 3) {
|
|
_awayMission->timers[1] = 0;
|
|
_awayMission->timers[5] = 180;
|
|
_awayMission->timers[6] = 1;
|
|
_awayMission->demon.warpsDisabled = false;
|
|
_awayMission->disableWalking = false;
|
|
}
|
|
loadActorAnim(12, "s0ks3", 0, 0, 0);
|
|
playSoundEffectIndex(0x06);
|
|
loadActorAnim2(10, "klg3d", 0, 0, 0);
|
|
_awayMission->disableInput = 0;
|
|
}
|
|
|
|
// Timer 6 expired
|
|
void Room::demon1AllKlingonsDead() {
|
|
_awayMission->crewGetupTimers[OBJECT_KIRK] = 45;
|
|
_awayMission->crewGetupTimers[OBJECT_SPOCK] = 45;
|
|
_awayMission->crewGetupTimers[OBJECT_MCCOY] = 45;
|
|
_awayMission->crewGetupTimers[OBJECT_REDSHIRT] = 45;
|
|
}
|
|
|
|
void Room::demon1Timer5Expired() {
|
|
if (_awayMission->crewDownBitset != 0)
|
|
return;
|
|
|
|
showText(TX_SPEAKER_UHURA, 77, true);
|
|
showText(TX_SPEAKER_KIRK, 3, true);
|
|
showText(TX_SPEAKER_UHURA, 78, true);
|
|
showText(TX_SPEAKER_KIRK, 2, true);
|
|
showText(TX_SPEAKER_SPOCK, 20, true);
|
|
showText(TX_SPEAKER_KIRK, 4, true);
|
|
showText(TX_SPEAKER_SPOCK, 21, true);
|
|
}
|
|
|
|
|
|
void Room::demon1UseMTricorderOnKlingon() {
|
|
loadActorAnim2(OBJECT_MCCOY, "mscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_MCCOY, 12, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnTulips() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 7, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnPods() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 8, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnCattails() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 5, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnFerns() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 6, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnHand() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 17, true);
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnKlingon1() {
|
|
// BUGFIX: Original game sets up the stack for this function call, but doesn't
|
|
// actually call the function...
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
|
|
playSoundEffectIndex(0x04);
|
|
|
|
if (_roomVar.demon.numKlingonsKilled == 3 && !_awayMission->demon.tookKlingonHand && _rdfData[0xcf] != 1) {
|
|
showText(TX_SPEAKER_SPOCK, 18, true);
|
|
_rdfData[0xcf] = 1;
|
|
} else {
|
|
showText(TX_SPEAKER_SPOCK, 19, true);
|
|
}
|
|
}
|
|
|
|
void Room::demon1UseSTricorderOnKlingon2Or3() {
|
|
loadActorAnim2(OBJECT_SPOCK, "sscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_SPOCK, 19, true);
|
|
}
|
|
|
|
void Room::demon1UseMTricorderOnKirk() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_KIRK))
|
|
demon1UseMTricorderOnCrewman();
|
|
}
|
|
|
|
void Room::demon1UseMTricorderOnSpock() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_SPOCK))
|
|
demon1UseMTricorderOnCrewman();
|
|
}
|
|
|
|
void Room::demon1UseMTricorderOnRedshirt() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_REDSHIRT))
|
|
demon1UseMTricorderOnCrewman();
|
|
}
|
|
|
|
void Room::demon1UseMTricorderOnCrewman() {
|
|
loadActorAnim2(OBJECT_MCCOY, "mscann", -1, -1, 0);
|
|
playSoundEffectIndex(0x04);
|
|
showText(TX_SPEAKER_MCCOY, 9, true);
|
|
}
|
|
|
|
void Room::demon1GetHand() {
|
|
if (_roomVar.demon.numKlingonsKilled != 3)
|
|
return;
|
|
walkCrewman(OBJECT_KIRK, 0x104, 0x8e, 1);
|
|
}
|
|
|
|
void Room::demon1ReachedHand() {
|
|
loadActorAnim2(OBJECT_KIRK, "s5r1kg", -1, -1, 6);
|
|
}
|
|
|
|
void Room::demon1PickedUpHand() {
|
|
loadActorStandAnim(13);
|
|
_awayMission->demon.missionScore += 3;
|
|
loadActorStandAnim(OBJECT_KIRK);
|
|
_awayMission->timers[4] = 2;
|
|
}
|
|
|
|
// Timer 4 expired
|
|
void Room::demon1FinishedGettingHand() {
|
|
|
|
if (_awayMission->demon.tookKlingonHand)
|
|
showDescription(5, true);
|
|
else {
|
|
_awayMission->demon.tookKlingonHand = true;
|
|
giveItem(OBJECT_IHAND);
|
|
showDescription(7, true);
|
|
}
|
|
}
|
|
|
|
void Room::demon1LookAtKlingon() {
|
|
showDescription(4, true);
|
|
}
|
|
|
|
void Room::demon1LookAtCattails() {
|
|
showDescription(18, true);
|
|
}
|
|
|
|
void Room::demon1LookAtTulips() {
|
|
showDescription(10, true);
|
|
}
|
|
|
|
void Room::demon1LookAtPods() {
|
|
showDescription(19, true);
|
|
}
|
|
|
|
void Room::demon1LookAtFerns() {
|
|
showDescription(9, true);
|
|
}
|
|
|
|
void Room::demon1LookAtStream() {
|
|
showDescription(11, true);
|
|
}
|
|
|
|
void Room::demon1LookAtMine() {
|
|
showDescription(21, true);
|
|
}
|
|
|
|
void Room::demon1LookAtMountain() {
|
|
showDescription(16, true);
|
|
}
|
|
|
|
void Room::demon1LookAtHand() {
|
|
showDescription(23, true);
|
|
}
|
|
void Room::demon1LookAnywhere() {
|
|
showDescription(17, true);
|
|
}
|
|
|
|
void Room::demon1LookAtKirk() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_KIRK))
|
|
showDescription(12, true);
|
|
else
|
|
showDescription(3, true);
|
|
}
|
|
|
|
void Room::demon1LookAtSpock() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_SPOCK))
|
|
showDescription(15, true);
|
|
else
|
|
showDescription(8, true);
|
|
}
|
|
|
|
void Room::demon1LookAtMcCoy() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_MCCOY))
|
|
showDescription(13, true);
|
|
else
|
|
showDescription(1, true);
|
|
}
|
|
|
|
void Room::demon1LookAtRedshirt() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_REDSHIRT))
|
|
showDescription(14, true);
|
|
else
|
|
showDescription(2, true);
|
|
}
|
|
|
|
void Room::demon1TalkToKirk() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_KIRK))
|
|
demon1TalkToUnconsciousCrewman();
|
|
else if (_roomVar.demon.numKlingonsKilled == 3)
|
|
showText(TX_SPEAKER_KIRK, 1, true);
|
|
}
|
|
|
|
void Room::demon1TalkToSpock() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_SPOCK))
|
|
demon1TalkToUnconsciousCrewman();
|
|
else {
|
|
showText(TX_SPEAKER_SPOCK, 22, true);
|
|
showText(TX_SPEAKER_MCCOY, 13, true);
|
|
showText(TX_SPEAKER_SPOCK, 24, true);
|
|
showText(TX_SPEAKER_MCCOY, 14, true);
|
|
}
|
|
}
|
|
|
|
void Room::demon1TalkToMcCoy() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_MCCOY))
|
|
demon1TalkToUnconsciousCrewman();
|
|
else {
|
|
showText(TX_SPEAKER_MCCOY, 15, true);
|
|
showText(TX_SPEAKER_SPOCK, 23, true);
|
|
}
|
|
}
|
|
|
|
void Room::demon1TalkToRedshirt() {
|
|
if (_awayMission->crewDownBitset & (1 << OBJECT_REDSHIRT))
|
|
demon1TalkToUnconsciousCrewman();
|
|
else
|
|
showText(TX_SPEAKER_EVERTS, 26, true);
|
|
}
|
|
|
|
// FIXME: this doesn't happen in actual game? (does the event get blocked from higher up?)
|
|
void Room::demon1TalkToUnconsciousCrewman() {
|
|
const char *text[] = {
|
|
nullptr,
|
|
"Zzzzz....",
|
|
""
|
|
};
|
|
showRoomSpecificText(text);
|
|
}
|
|
|
|
}
|