aboutsummaryrefslogtreecommitdiff
path: root/engines/startrek/rooms
diff options
context:
space:
mode:
authorMatthew Stewart2018-06-14 02:19:14 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commit6e322ebfc5279ee16076b07b82a1dc2c44122b26 (patch)
tree2203059dba594b0871082f063730c0fc1b87db69 /engines/startrek/rooms
parent3d27a9a92cc7bcf88f58aa8f4b2639573bb5e697 (diff)
downloadscummvm-rg350-6e322ebfc5279ee16076b07b82a1dc2c44122b26.tar.gz
scummvm-rg350-6e322ebfc5279ee16076b07b82a1dc2c44122b26.tar.bz2
scummvm-rg350-6e322ebfc5279ee16076b07b82a1dc2c44122b26.zip
STARTREK: TUG3 (mission 2 finished)
Diffstat (limited to 'engines/startrek/rooms')
-rw-r--r--engines/startrek/rooms/function_map.h39
-rw-r--r--engines/startrek/rooms/tug0.cpp21
-rw-r--r--engines/startrek/rooms/tug2.cpp30
-rw-r--r--engines/startrek/rooms/tug3.cpp504
4 files changed, 570 insertions, 24 deletions
diff --git a/engines/startrek/rooms/function_map.h b/engines/startrek/rooms/function_map.h
index a88214cdfa..0eb8d97afa 100644
--- a/engines/startrek/rooms/function_map.h
+++ b/engines/startrek/rooms/function_map.h
@@ -650,7 +650,6 @@ RoomAction tug1ActionList[] = {
{ Action(ACTION_USE, OBJECT_IMEDKIT, 0x20, 0), &Room::tug1UseMedkitOnBridgeDoor },
{ Action(ACTION_USE, OBJECT_IMEDKIT, 0x21, 0), &Room::tug1UseMedkitOnBridgeDoor },
{ Action(ACTION_USE, OBJECT_IMEDKIT, 0x22, 0), &Room::tug1UseMedkitOnBridgeDoor },
-
};
@@ -745,6 +744,44 @@ RoomAction tug2ActionList[] = {
{ Action(ACTION_USE, OBJECT_IPHASERK, -1, 0), &Room::tug2UsePhaserAnywhere },
};
+
+RoomAction tug3ActionList[] = {
+ { Action(ACTION_TICK, 1, 0, 0), &Room::tug3Tick1 },
+ { Action(ACTION_TICK, 40, 0, 0), &Room::tug3Tick40 },
+ { Action(ACTION_LOOK, -1, 0, 0), &Room::tug3LookAnywhere },
+ { Action(ACTION_USE, OBJECT_IPHASERS, -1, 0), &Room::tug3UsePhaserAnywhere },
+ { Action(ACTION_USE, OBJECT_IPHASERK, -1, 0), &Room::tug3UsePhaserAnywhere },
+ { Action(ACTION_USE, OBJECT_IPHASERS, 8, 0), &Room::tug3UseStunPhaserOnElasi1 },
+ { Action(ACTION_USE, OBJECT_IPHASERS, 9, 0), &Room::tug3UseStunPhaserOnElasi2 },
+ { Action(ACTION_USE, OBJECT_IPHASERS, 10, 0), &Room::tug3UseStunPhaserOnElasi3 },
+ { Action(ACTION_USE, OBJECT_IPHASERS, 11, 0), &Room::tug3UseStunPhaserOnElasi4 },
+ { Action(ACTION_USE, OBJECT_IPHASERK, 8, 0), &Room::tug3UseKillPhaserOnElasi1 },
+ { Action(ACTION_USE, OBJECT_IPHASERK, 9, 0), &Room::tug3UseKillPhaserOnElasi2 },
+ { Action(ACTION_USE, OBJECT_IPHASERK, 10, 0), &Room::tug3UseKillPhaserOnElasi3 },
+ { Action(ACTION_USE, OBJECT_IPHASERK, 11, 0), &Room::tug3UseKillPhaserOnElasi4 },
+ { Action(ACTION_FINISHED_ANIMATION, 12, 0, 0), &Room::tug3ElasiStunnedOrKilled },
+ { Action(ACTION_TALK, 8, 0, 0), &Room::tug3TalkToElasi1 },
+ { Action(ACTION_FINISHED_ANIMATION, 3, 0, 0), &Room::tug3Elasi1DrewPhaser },
+ { Action(ACTION_FINISHED_ANIMATION, 4, 0, 0), &Room::tug3Elasi1ShotConsole },
+ { Action(ACTION_FINISHED_ANIMATION, 5, 0, 0), &Room::tug3Elasi1DrewPhaser2 },
+ { Action(ACTION_FINISHED_ANIMATION, 6, 0, 0), &Room::tug3Elasi1ShotConsoleAndSurrenders },
+ { Action(ACTION_LOOK, OBJECT_MCCOY, 0, 0), &Room::tug3LookAtMccoy },
+ { Action(ACTION_LOOK, OBJECT_SPOCK, 0, 0), &Room::tug3LookAtSpock },
+ { Action(ACTION_LOOK, OBJECT_REDSHIRT, 0, 0), &Room::tug3LookAtRedshirt },
+ { Action(ACTION_LOOK, 8, 0, 0), &Room::tug3LookAtElasi1 },
+ { Action(ACTION_LOOK, 9, 0, 0), &Room::tug3LookAtElasi2 },
+ { Action(ACTION_LOOK, 10, 0, 0), &Room::tug3LookAtElasi3 },
+ { Action(ACTION_LOOK, 11, 0, 0), &Room::tug3LookAtElasi4 },
+ { Action(ACTION_TALK, OBJECT_MCCOY, 0, 0), &Room::tug3TalkToMccoy },
+ { Action(ACTION_TALK, OBJECT_SPOCK, 0, 0), &Room::tug3TalkToSpock },
+ { Action(ACTION_TALK, OBJECT_REDSHIRT, 0, 0), &Room::tug3TalkToRedshirt },
+ { Action(ACTION_USE, OBJECT_ICOMM, -1, 0), &Room::tug3UseCommunicator },
+ { Action(ACTION_TIMER_EXPIRED, 0, 0, 0), &Room::tug3Timer0Expired },
+ { Action(ACTION_FINISHED_ANIMATION, 13, 0, 0), &Room::tug3AllCrewmenDead },
+ { Action(ACTION_TIMER_EXPIRED, 1, 0, 0), &Room::tug3Timer1Expired },
+ { Action(ACTION_FINISHED_ANIMATION, 7, 0, 0), &Room::tug3SecurityTeamBeamedIn },
+};
+
}
#endif
diff --git a/engines/startrek/rooms/tug0.cpp b/engines/startrek/rooms/tug0.cpp
index e90544d57e..4461b226d5 100644
--- a/engines/startrek/rooms/tug0.cpp
+++ b/engines/startrek/rooms/tug0.cpp
@@ -142,14 +142,19 @@ void Room::tug0SpockFinishedUsingWire() {
showText(TX_SPEAKER_KIRK, TX_TUG0_010);
showText(TX_SPEAKER_MCCOY, TX_TUG0_022);
- showText(TX_SPEAKER_KIRK, TX_TUG0_002);
- showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L009);
- showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L008);
-
- if (_vm->_awayMission.tug.haveBomb) {
- showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L010);
- showText(TX_SPEAKER_MCCOY, TX_TUG0_021);
- showText(TX_SPEAKER_SPOCK, TX_TUG0_041);
+
+ // BUGFIX: check if the redshirt is dead.
+ if (!_vm->_awayMission.redshirtDead) {
+ showText(TX_SPEAKER_KIRK, TX_TUG0_002);
+
+ showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L009);
+ showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L008);
+
+ if (_vm->_awayMission.tug.haveBomb) {
+ showText(TX_SPEAKER_CHRISTENSEN, TX_TUG0L010);
+ showText(TX_SPEAKER_MCCOY, TX_TUG0_021);
+ showText(TX_SPEAKER_SPOCK, TX_TUG0_041);
+ }
}
}
diff --git a/engines/startrek/rooms/tug2.cpp b/engines/startrek/rooms/tug2.cpp
index e89aff79fd..3c6aad2ed5 100644
--- a/engines/startrek/rooms/tug2.cpp
+++ b/engines/startrek/rooms/tug2.cpp
@@ -481,7 +481,7 @@ void Room::tug2UseKillPhaserOnGuard1() {
else {
loadActorAnim2(OBJECT_KIRK, "kdrawe", -1, -1, 24);
_vm->_awayMission.tug.kirkPhaserDrawn = true;
- _vm->_awayMission.tug.field4a = true;
+ _vm->_awayMission.tug.brigElasiPhasersOnKill = true;
}
}
}
@@ -509,7 +509,7 @@ void Room::tug2UseKillPhaserOnGuard2() {
else {
loadActorAnim2(OBJECT_KIRK, "kdrawe", -1, -1, 25);
_vm->_awayMission.tug.kirkPhaserDrawn = true;
- _vm->_awayMission.tug.field4a = true;
+ _vm->_awayMission.tug.brigElasiPhasersOnKill = true;
}
}
}
@@ -624,7 +624,7 @@ void Room::tug2Timer0Expired() {
return;
_roomVar.tug2.elasiPhaserOnKill = 0;
- if (_vm->_awayMission.tug.field4a)
+ if (_vm->_awayMission.tug.brigElasiPhasersOnKill)
_roomVar.tug2.elasiPhaserOnKill = 1;
switch (_vm->_awayMission.tug.field4b) {
@@ -659,14 +659,14 @@ void Room::tug2Timer0Expired() {
case 2:
// Guard shoots spock (or kirk)
_vm->_awayMission.tug.field4b++;
- _roomVar.tug2._1ec4 = 0;
- if (_vm->_awayMission.tug.field4a)
- _roomVar.tug2._1ec4 = 1;
+ _roomVar.tug2.shootKirkOverride = false;
+ if (_vm->_awayMission.tug.brigElasiPhasersOnKill)
+ _roomVar.tug2.shootKirkOverride = true;
tug2DetermineElasiShooter();
- if (_roomVar.tug2._1ec4 == 0)
- _roomVar.tug2.shootingTarget = OBJECT_SPOCK;
- else
+ if (_roomVar.tug2.shootKirkOverride)
_roomVar.tug2.shootingTarget = OBJECT_KIRK;
+ else
+ _roomVar.tug2.shootingTarget = OBJECT_SPOCK;
_vm->_awayMission.timers[0] = 60;
tug2GuardShootsCrewman();
break;
@@ -683,16 +683,16 @@ void Room::tug2Timer0Expired() {
case 4:
_vm->_awayMission.tug.field4b++;
- if (_roomVar.tug2._1ec4 == 0) {
+ if (_roomVar.tug2.shootKirkOverride) {
tug2DetermineElasiShooter();
- _roomVar.tug2.shootingTarget = OBJECT_KIRK;
- _vm->_awayMission.timers[2] = 40; // TODO
+ _roomVar.tug2.shootingTarget = OBJECT_SPOCK;
+ _vm->_awayMission.timers[2] = 40;
tug2GuardShootsCrewman();
}
- else if (_roomVar.tug2._1ec4 == 1) {
+ else if (_roomVar.tug2.shootKirkOverride) {
tug2DetermineElasiShooter();
- _roomVar.tug2.shootingTarget = OBJECT_SPOCK;
- _vm->_awayMission.timers[2] = 40;
+ _roomVar.tug2.shootingTarget = OBJECT_KIRK;
+ _vm->_awayMission.timers[2] = 40; // TODO
tug2GuardShootsCrewman();
}
break;
diff --git a/engines/startrek/rooms/tug3.cpp b/engines/startrek/rooms/tug3.cpp
new file mode 100644
index 0000000000..6c1b67409d
--- /dev/null
+++ b/engines/startrek/rooms/tug3.cpp
@@ -0,0 +1,504 @@
+/* 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 {
+
+#define OBJECT_ELASI_1 8
+#define OBJECT_ELASI_2 9
+#define OBJECT_ELASI_3 10
+#define OBJECT_ELASI_4 11
+#define OBJECT_12 12
+#define OBJECT_13 13
+#define OBJECT_14 14
+#define OBJECT_15 15
+
+#define GUARDSTAT_UP 0
+#define GUARDSTAT_STUNNED 1
+#define GUARDSTAT_DEAD 2
+#define GUARDSTAT_SURRENDERED 4
+#define GUARDSTAT_TIED 8
+
+void Room::tug3Tick1() {
+ playVoc("TUG3LOOP");
+
+ _vm->_awayMission.disableWalking = true;
+ loadActorAnim2(OBJECT_ELASI_1, "p1turn", 0xa4, 0x98, 0);
+ loadActorAnim2(OBJECT_ELASI_2, "p2turn", 0xd1, 0x88, 0);
+ loadActorAnim2(OBJECT_ELASI_3, "p3turn", 0xfb, 0xc4, 0);
+ loadActorAnim2(OBJECT_ELASI_4, "p4turn", 0x5a, 0x9e, 0);
+}
+
+void Room::tug3Tick40() {
+ loadActorAnim2(OBJECT_KIRK, "kdraws", -1, -1, 0); // Draw phaser
+}
+
+void Room::tug3LookAnywhere() {
+ showText(TX_TUG3N007);
+}
+
+void Room::tug3ElasiSurrendered() {
+ // BUGFIX: the original game had the condition below. However, this would cause
+ // problems if you start shooting, then get them to surrender; if timed correctly,
+ // they could shoot Kirk as he's beaming out and the mission is "successful". To
+ // prevent that, the below condition is removed in ScummVM.
+ /*
+ if (_vm->_awayMission.tug.bridgeElasiDrewPhasers)
+ return;
+ */
+
+ // Also part of the bugfix (stop shooting)
+ _vm->_awayMission.timers[0] = 0;
+
+ _vm->_awayMission.tug.elasiSurrendered = true;
+ loadActorAnim2(OBJECT_ELASI_1, "p1surr", -1, -1, 0);
+ _vm->_awayMission.tug.bridgeElasi1Status = GUARDSTAT_SURRENDERED;
+
+ if (_vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_UP) {
+ loadActorAnim2(OBJECT_ELASI_2, "p2surr", -1, -1, 0);
+ _vm->_awayMission.tug.bridgeElasi2Status = GUARDSTAT_SURRENDERED;
+ }
+ if (_vm->_awayMission.tug.bridgeElasi3Status == GUARDSTAT_UP) {
+ loadActorAnim2(OBJECT_ELASI_3, "p3surr", -1, -1, 0);
+ _vm->_awayMission.tug.bridgeElasi3Status = GUARDSTAT_SURRENDERED;
+ }
+ if (_vm->_awayMission.tug.bridgeElasi4Status == GUARDSTAT_UP) {
+ loadActorAnim2(OBJECT_ELASI_4, "p4surr", -1, -1, 0);
+ _vm->_awayMission.tug.bridgeElasi4Status = GUARDSTAT_SURRENDERED;
+ }
+
+ _vm->_awayMission.tug.missionScore += 4;
+}
+
+void Room::tug3UsePhaserAnywhere() {
+ // Stub function to suppress "you can't do that" messages
+}
+
+void Room::tug3ElasiDrawPhasers() {
+ if (_vm->_awayMission.tug.bridgeElasiDrewPhasers)
+ return;
+
+ _vm->_awayMission.tug.bridgeElasiDrewPhasers = true;
+
+ // If brig guards are alive & untied, kill the hostages
+ if (_vm->_awayMission.tug.guard1Status == 0 || _vm->_awayMission.tug.guard2Status == 0) {
+ showText(TX_SPEAKER_ELASI_CLANSMAN, TX_TUG3L081);
+ _vm->_awayMission.tug.missionScore = 0;
+ }
+
+ if (_vm->_awayMission.timers[0] == 0)
+ _vm->_awayMission.timers[0] = 10;
+
+ // Make all elasi draw their phasers
+ if (_vm->_awayMission.tug.bridgeElasi1Status == 0)
+ loadActorAnim2(OBJECT_ELASI_1, "p1draw", -1, -1, 0);
+ if (_vm->_awayMission.tug.bridgeElasi2Status == 0)
+ loadActorAnim2(OBJECT_ELASI_2, "p2draw", -1, -1, 0);
+ if (_vm->_awayMission.tug.bridgeElasi3Status == 0)
+ loadActorAnim2(OBJECT_ELASI_3, "p3draw", -1, -1, 0);
+ if (_vm->_awayMission.tug.bridgeElasi4Status == 0)
+ loadActorAnim2(OBJECT_ELASI_4, "p4draw", -1, -1, 0);
+}
+
+void Room::tug3UseStunPhaserOnElasi1() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi1Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_1, "p1stun", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem05", 5);
+ _vm->_awayMission.tug.bridgeElasi1Status = GUARDSTAT_STUNNED;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseStunPhaserOnElasi2() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi2Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_2, "p2stun", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem06", 5);
+ _vm->_awayMission.tug.bridgeElasi2Status = GUARDSTAT_STUNNED;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseStunPhaserOnElasi3() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi3Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_3, "p3stun", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem07", 5);
+ _vm->_awayMission.tug.bridgeElasi3Status = GUARDSTAT_STUNNED;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseStunPhaserOnElasi4() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi4Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_4, "p4stun", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem04", 5);
+ _vm->_awayMission.tug.bridgeElasi4Status = GUARDSTAT_STUNNED;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseKillPhaserOnElasi1() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi1Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_1, "p1Kill", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem25", 5);
+ _vm->_awayMission.tug.bridgeElasi1Status = GUARDSTAT_DEAD;
+ _vm->_awayMission.tug.missionScore -= 2;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseKillPhaserOnElasi2() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi2Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_2, "p2Kill", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem27", 5);
+ _vm->_awayMission.tug.bridgeElasi2Status = GUARDSTAT_DEAD;
+ _vm->_awayMission.tug.missionScore -= 2;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseKillPhaserOnElasi3() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi3Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_3, "p3Kill", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem26", 5);
+ _vm->_awayMission.tug.bridgeElasi3Status = GUARDSTAT_DEAD;
+ _vm->_awayMission.tug.missionScore -= 2;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3UseKillPhaserOnElasi4() {
+ if (_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] || _vm->_awayMission.tug.bridgeElasi4Status != GUARDSTAT_UP)
+ return;
+ loadActorAnim2(OBJECT_ELASI_4, "p4Kill", -1, -1, 12);
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem24", 5);
+ _vm->_awayMission.tug.bridgeElasi4Status = GUARDSTAT_DEAD;
+ _vm->_awayMission.tug.missionScore -= 2;
+ tug3ElasiDrawPhasers();
+}
+
+void Room::tug3ElasiStunnedOrKilled() {
+ if (_vm->_awayMission.tug.bridgeWinMethod == 1)
+ return;
+ if (_vm->_awayMission.tug.bridgeElasi1Status == GUARDSTAT_UP || _vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_UP
+ || _vm->_awayMission.tug.bridgeElasi3Status == GUARDSTAT_UP || _vm->_awayMission.tug.bridgeElasi4Status == GUARDSTAT_UP)
+ return;
+
+ // BUGFIX: if the ship is deorbiting, the mission isn't won yet.
+ if (_vm->_awayMission.tug.orbitalDecayCounter != 0)
+ return;
+
+ _vm->_awayMission.tug.bridgeWinMethod = 1;
+ tug3EndMission();
+}
+
+void Room::tug3TalkToElasi1() {
+ if (_vm->_awayMission.tug.bridgeElasi1Status != GUARDSTAT_UP || _vm->_awayMission.tug.talkedToCereth)
+ return;
+ _vm->_awayMission.tug.talkedToCereth = true;
+
+ const int choices[] = {
+ TX_SPEAKER_KIRK,
+ TX_TUG3_004,
+ TX_TUG3_003,
+ TX_TUG3_002,
+ TX_BLANK
+ };
+ int choice = showText(choices);
+
+ switch (choice) {
+ case 0: // They surrender
+ showText(TX_SPEAKER_ELASI_CERETH, TX_TUG3L084);
+ _vm->_awayMission.tug.bridgeElasi1Status = GUARDSTAT_SURRENDERED;
+ loadActorAnim2(OBJECT_ELASI_1, "p1surr", -1, -1, 0);
+ tug3ElasiSurrendered();
+ _vm->_awayMission.tug.bridgeWinMethod = 2;
+ _vm->_awayMission.tug.missionScore += 8;
+ tug3EndMission();
+ break;
+
+ case 1: // Cereth shoots console, doesn't surrender
+ _vm->_awayMission.disableInput = true;
+ showText(TX_SPEAKER_ELASI_CERETH, TX_TUG3_F27);
+ loadActorAnim2(OBJECT_ELASI_1, "p1draw", -1, -1, 3);
+ break;
+
+ case 2: // Cereth shoots console and surrenders
+ _vm->_awayMission.disableInput = true;
+ showText(TX_SPEAKER_ELASI_CERETH, TX_TUG3L083);
+ loadActorAnim2(OBJECT_ELASI_1, "p1draw", -1, -1, 5);
+
+ // BUGFIX: they're going to surrender, so stop the firefight.
+ _vm->_awayMission.timers[0] = 0;
+ break;
+ }
+}
+
+void Room::tug3Elasi1DrewPhaser() {
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem41", 13);
+ playSoundEffectIndex(SND_BLANK_16);
+ loadActorAnim2(OBJECT_12, "sparks", 0xa0, 0xad, 4);
+}
+
+void Room::tug3Elasi1ShotConsole() {
+ tug3ElasiDrawPhasers();
+ _vm->_awayMission.disableInput = false;
+ _vm->_awayMission.tug.bridgeWinMethod = 3;
+ _vm->_awayMission.timers[1] = 10;
+}
+
+void Room::tug3Elasi1DrewPhaser2() {
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks("t3beem41", 13);
+ loadActorAnim2(OBJECT_12, "sparks", 0xa0, 0xad, 6);
+}
+
+void Room::tug3Elasi1ShotConsoleAndSurrenders() {
+ showText(TX_SPEAKER_ELASI_CERETH, TX_TUG3L080);
+ tug3ElasiSurrendered();
+ _vm->_awayMission.disableInput = false;
+ _vm->_awayMission.tug.bridgeWinMethod = 3;
+ _vm->_awayMission.timers[1] = 10;
+}
+
+void Room::tug3LookAtMccoy() {
+ showText(TX_TUG3N000);
+}
+
+void Room::tug3LookAtSpock() {
+ showText(TX_TUG3N002);
+}
+
+void Room::tug3LookAtRedshirt() {
+ showText(TX_TUG3N001);
+}
+
+void Room::tug3LookAtElasi1() {
+ // BUGFIX: there were two implementations of this function; the first was the same as
+ // the other 3 elasi, the second was specific to the captain. The second was never
+ // called in the original game, but it's used here instead for more variety.
+ // The function itself is changed by checking both if he's stunned or if he's dead,
+ // instead of just checking if he's stunned.
+
+ if (_vm->_awayMission.tug.bridgeElasi1Status == GUARDSTAT_STUNNED || _vm->_awayMission.tug.bridgeElasi1Status == GUARDSTAT_DEAD)
+ showText(TX_TUG3N003);
+ else
+ showText(TX_TUG3N008);
+}
+
+void Room::tug3LookAtElasi2() {
+ // BUGFIX: also check if stunned. They can't "glare at the crewmembers" if they're
+ // unconscious. (applies to below functions too.)
+ if (_vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_DEAD || _vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_STUNNED)
+ showText(TX_TUG3N004);
+ else
+ showText(TX_TUG3N005);
+}
+
+void Room::tug3LookAtElasi3() {
+ if (_vm->_awayMission.tug.bridgeElasi3Status == GUARDSTAT_DEAD || _vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_STUNNED)
+ showText(TX_TUG3N004);
+ else
+ showText(TX_TUG3N005);
+}
+
+void Room::tug3LookAtElasi4() {
+ if (_vm->_awayMission.tug.bridgeElasi4Status == GUARDSTAT_DEAD || _vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_STUNNED)
+ showText(TX_TUG3N004);
+ else
+ showText(TX_TUG3N005);
+}
+
+void Room::tug3TalkToMccoy() {
+ if (_vm->_awayMission.tug.orbitalDecayCounter != 0 || _vm->_awayMission.tug.bridgeElasi1Status != GUARDSTAT_UP) {
+ if (_vm->_awayMission.tug.orbitalDecayCounter >= 10) {
+ if (_vm->_awayMission.tug.orbitalDecayCounter < 16)
+ showText(TX_SPEAKER_MCCOY, TX_TUG3_011);
+ }
+ else if (_vm->_awayMission.tug.orbitalDecayCounter != 0) {
+ // BUGFIX: original game displays a blank textbox. An appropriate audio file
+ // exists, but the corresponding text was written from scratch for ScummVM.
+ // TODO: check if original floppy version has text for this.
+ showText(TX_SPEAKER_MCCOY, TX_TUG3_012);
+ }
+ }
+ else
+ showText(TX_SPEAKER_MCCOY, TX_TUG3_013);
+}
+
+void Room::tug3TalkToSpock() {
+ if (_vm->_awayMission.tug.orbitalDecayCounter != 0) {
+ if (_vm->_awayMission.tug.orbitalDecayCounter >= 10) {
+ if (_vm->_awayMission.tug.orbitalDecayCounter < 16)
+ showText(TX_SPEAKER_SPOCK, TX_TUG3_008);
+ }
+ else
+ showText(TX_SPEAKER_SPOCK, TX_TUG3_009);
+ }
+}
+
+void Room::tug3TalkToRedshirt() {
+ showText(TX_SPEAKER_CHRISTENSEN, TX_TUG3L003);
+}
+
+void Room::tug3UseCommunicator() {
+ if (_vm->_awayMission.tug.orbitalDecayCounter == 0)
+ return;
+
+ if (_vm->_awayMission.tug.orbitalDecayCounter < 10) {
+ showText(TX_SPEAKER_KIRK, TX_TUG3_007);
+ showText(TX_SPEAKER_SULU, TX_TUG3_015);
+ showText(TX_SPEAKER_SHIPS_COMPUTER, TX_COMPA180);
+ _vm->_awayMission.timers[1] = 0;
+
+ // BUGFIX: if still fighting the elasi, the mission isn't done yet.
+ _vm->_awayMission.tug.orbitalDecayCounter = 0;
+ if (!_vm->_awayMission.tug.elasiSurrendered &&
+ (_vm->_awayMission.tug.bridgeElasi1Status == GUARDSTAT_UP
+ || _vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_UP
+ || _vm->_awayMission.tug.bridgeElasi3Status == GUARDSTAT_UP
+ || _vm->_awayMission.tug.bridgeElasi4Status == GUARDSTAT_UP))
+ return;
+
+ tug3EndMission();
+ }
+ else {
+ if (_vm->_awayMission.tug.orbitalDecayCounter < 16) {
+ showText(TX_SPEAKER_KIRK, TX_TUG3_006);
+ showText(TX_SPEAKER_SCOTT, TX_TUG3_S07);
+
+ playMidiMusicTracks(-1, -1);
+
+ _vm->_awayMission.disableInput = true;
+ if (_vm->_awayMission.tug.missionScore < 0)
+ _vm->_awayMission.tug.missionScore = 0;
+ endMission(_vm->_awayMission.tug.missionScore, _vm->_awayMission.tug.field2b, _vm->_awayMission.tug.field2d);
+ }
+ }
+}
+
+// One of the elasi shoots one of the crewmen
+void Room::tug3Timer0Expired() {
+ const char *beamAnims[][4] = {
+ { "t3beem33", "t3beem35", "t3beem34", "t3beem32" },
+ { "t3beem37", "t3beem39", "t3beem38", "t3beem36" },
+ { "t3beem29", "t3beem31", "t3beem30", "t3beem28" },
+ };
+
+ int elasiShooter, elasiTarget;
+
+ if (_vm->_awayMission.tug.bridgeElasi2Status == GUARDSTAT_UP)
+ elasiShooter = 0;
+ else if (_vm->_awayMission.tug.bridgeElasi3Status == GUARDSTAT_UP)
+ elasiShooter = 1;
+ else if (_vm->_awayMission.tug.bridgeElasi4Status == GUARDSTAT_UP)
+ elasiShooter = 2;
+ else
+ return;
+
+ if (!_vm->_awayMission.tug.crewmanKilled[OBJECT_REDSHIRT]) {
+ _vm->_awayMission.tug.crewmanKilled[OBJECT_REDSHIRT] = 2;
+ _vm->_awayMission.redshirtDead = true;
+ loadActorAnim2(OBJECT_REDSHIRT, "rkills", -1, -1, 0);
+ elasiTarget = OBJECT_REDSHIRT;
+ }
+ else if (!_vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK]) {
+ _vm->_awayMission.tug.crewmanKilled[OBJECT_KIRK] = 2;
+ _vm->_awayMission.disableInput = true;
+ loadActorAnim2(OBJECT_KIRK, "kkills", -1, -1, 0);
+ elasiTarget = OBJECT_KIRK;
+ }
+ else if (!_vm->_awayMission.tug.crewmanKilled[OBJECT_SPOCK]) {
+ _vm->_awayMission.tug.crewmanKilled[OBJECT_SPOCK] = 2;
+ loadActorAnim2(OBJECT_SPOCK, "skills", -1, -1, 0);
+ elasiTarget = OBJECT_SPOCK;
+ }
+ else if (!_vm->_awayMission.tug.crewmanKilled[OBJECT_MCCOY]) {
+ _vm->_awayMission.tug.crewmanKilled[OBJECT_MCCOY] = 2;
+ loadActorAnim2(OBJECT_MCCOY, "mkills", -1, -1, 13);
+ elasiTarget = OBJECT_MCCOY;
+ }
+ else
+ return;
+
+ playSoundEffectIndex(SND_PHASSHOT);
+ showBitmapFor5Ticks(beamAnims[elasiShooter][elasiTarget], 5);
+ _vm->_awayMission.timers[0] = 50;
+}
+
+void Room::tug3AllCrewmenDead() {
+ playMidiMusicTracks(2, -1);
+ showGameOverMenu();
+}
+
+// "Orbital decay" countdown timer
+void Room::tug3Timer1Expired() {
+ if (_vm->_awayMission.tug.orbitalDecayCounter < 10) { // Decay still preventable
+ showText(TX_SPEAKER_SHIPS_COMPUTER, TX_COMPU182);
+ _vm->_awayMission.timers[1] = 100;
+ _vm->_awayMission.tug.orbitalDecayCounter++;
+ }
+ else if (_vm->_awayMission.tug.orbitalDecayCounter < 16) { // Decay now unavoidable
+ showText(TX_SPEAKER_SHIPS_COMPUTER, TX_COMPU181);
+ _vm->_awayMission.timers[1] = 100;
+ _vm->_awayMission.tug.orbitalDecayCounter++;
+ }
+ else { // Game over
+ showText(TX_TUG3N006);
+ showGameOverMenu();
+ }
+}
+
+void Room::tug3EndMission() {
+ playMidiMusicTracks(28, -1);
+ showText(TX_SPEAKER_KIRK, TX_TUG3_001);
+ playSoundEffectIndex(SND_TRANSMAT);
+ loadActorAnim2(OBJECT_13, "rteleb", 0x14, 0xa0, 7);
+ loadActorAnim2(OBJECT_14, "rteleb", 0x118, 0xa0, 0);
+ loadActorAnim2(OBJECT_15, "rteleb", 0x96, 0xbe, 0);
+}
+
+void Room::tug3SecurityTeamBeamedIn() {
+ loadActorAnim2(OBJECT_13, "rdrawe", -1, -1, 8);
+ loadActorAnim2(OBJECT_14, "rdraws", -1, -1, 9);
+ loadActorAnim2(OBJECT_15, "rfiren", -1, -1, 10);
+
+ showText(TX_SPEAKER_KIRK, TX_TUG3_005);
+ showText(TX_SPEAKER_SCOTT, TX_TUG3_S08);
+
+ playMidiMusicTracks(-1, -1);
+ _vm->_awayMission.disableInput = true;
+ if (_vm->_awayMission.tug.missionScore < 0)
+ _vm->_awayMission.tug.missionScore = 0;
+ endMission(_vm->_awayMission.tug.missionScore, _vm->_awayMission.tug.field2b, _vm->_awayMission.tug.field2d);
+}
+
+}