1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "bladerunner/script/scene_script.h"
24 #include "common/debug.h"
25 
26 namespace BladeRunner {
27 
28 // Appears that names for "open" and "close" are switched
29 enum kMA06Loops {
30 	kMA06LoopDoorOpen  = 0,
31 	kMA06LoopMainLoop  = 1,
32 	kMA06LoopDoorClose = 3
33 };
34 
InitializeScene()35 void SceneScriptMA06::InitializeScene() {
36 	Setup_Scene_Information(40.0f, 1.0f, -20.0f, 400);
37 
38 #if BLADERUNNER_ORIGINAL_BUGS
39 #else
40 	Ambient_Sounds_Remove_All_Looping_Sounds(1);
41 	Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
42 #endif // BLADERUNNER_ORIGINAL_BUGS
43 
44 	Ambient_Sounds_Add_Looping_Sound(kSfxELEAMB3,  50, 0, 1);
45 	Ambient_Sounds_Add_Looping_Sound(kSfxAPRTFAN1, 33, 0, 1);
46 
47 	Scene_Loop_Start_Special(kSceneLoopModeLoseControl, kMA06LoopDoorOpen, false);
48 	Scene_Loop_Set_Default(kMA06LoopMainLoop);
49 
50 	Sound_Play(kSfxELDOORC1, 100, 50, 50, 100);
51 }
52 
SceneLoaded()53 void SceneScriptMA06::SceneLoaded() {
54 	Obstacle_Object("PANEL", true);
55 	Clickable_Object("PANEL");
56 #if BLADERUNNER_ORIGINAL_BUGS
57 #else
58 	Unclickable_Object("PANEL");
59 #endif // BLADERUNNER_ORIGINAL_BUGS
60 	if (_vm->_cutContent) {
61 		if (Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelShouldBeInElevatorMcCoysAct3) {
62 			// Put Rachael in set for her first cut scene (Act 3) when it plays out in the elevator
63 			Actor_Put_In_Set(kActorRachael, kSetMA06);
64 			Actor_Set_At_XYZ(kActorRachael, 30.15f, 0.0f, 45.16f, 350);
65 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsInsideMcCoysElevatorAct3);
66 		} else if (Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelAtEndOfAct3IfMetWithMcCoy
67 			&& Game_Flag_Query(kFlagMA02RajifTalk)) {
68 			// Put Rachael in set for her second cut scene (Act 4)
69 			Actor_Put_In_Set(kActorRachael, kSetMA06);
70 			Actor_Set_At_XYZ(kActorRachael, 30.15f, 0.0f, 50.16f, 170); // different rotation and slightly different placement
71 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsInsideMcCoysElevatorAct4);
72 		}
73 	}
74 	Player_Loses_Control();
75 }
76 
MouseClick(int x,int y)77 bool SceneScriptMA06::MouseClick(int x, int y) {
78 	return false;
79 }
80 
ClickedOn3DObject(const char * objectName,bool a2)81 bool SceneScriptMA06::ClickedOn3DObject(const char *objectName, bool a2) {
82 	return false;
83 }
84 
ClickedOnActor(int actorId)85 bool SceneScriptMA06::ClickedOnActor(int actorId) {
86 	return false;
87 }
88 
ClickedOnItem(int itemId,bool a2)89 bool SceneScriptMA06::ClickedOnItem(int itemId, bool a2) {
90 	return false;
91 }
92 
ClickedOnExit(int exitId)93 bool SceneScriptMA06::ClickedOnExit(int exitId) {
94 	return false;
95 }
96 
ClickedOn2DRegion(int region)97 bool SceneScriptMA06::ClickedOn2DRegion(int region) {
98 	return false;
99 }
100 
SceneFrameAdvanced(int frame)101 void SceneScriptMA06::SceneFrameAdvanced(int frame) {
102 }
103 
ActorChangedGoal(int actorId,int newGoal,int oldGoal,bool currentSet)104 void SceneScriptMA06::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bool currentSet) {
105 }
106 
PlayerWalkedIn()107 void SceneScriptMA06::PlayerWalkedIn() {
108 	Loop_Actor_Walk_To_XYZ(kActorMcCoy, 40.0f, 1.35f, 0.0f, 0, false, false, false);
109 	Actor_Face_Object(kActorMcCoy, "panel", true);
110 	Delay(500);
111 	bool normalElevatorBusiness = true;
112 	if (_vm->_cutContent) {
113 		//
114 		// McCoy + Rachael meetings
115 		//
116 		if ((Game_Flag_Query(kFlagMA07toMA06) || Game_Flag_Query(kFlagMA01toMA06))
117 		     && Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelIsInsideMcCoysElevatorAct3
118 		) {
119 			normalElevatorBusiness = false;
120 			// Act 3 Deleted scene (can happen within the elevator or outside the building)
121 			// Skip floor panel selection - force go to MCCOY 88F
122 			Game_Flag_Reset(kFlagMA06toMA01);
123 			Game_Flag_Reset(kFlagMA06ToMA02);
124 			Game_Flag_Reset(kFlagMA06toMA07);
125 			Ambient_Sounds_Adjust_Looping_Sound(kSfxELEAMB3, 10, 0, 1);
126 			Ambient_Sounds_Adjust_Looping_Sound(kSfxAPRTFAN1, 10, 0, 1);
127 
128 			Actor_Says(kActorAnsweringMachine, 80, 3);     // your floor number please
129 			Actor_Says(kActorMcCoy, 2940, 18);             // McCoy: McCoy 88F
130 			Game_Flag_Set(kFlagMA06ToMA02);                // to McCoy's Apartment
131 			Actor_Says(kActorAnsweringMachine, 90, 3);     // 88 thank you
132 			Actor_Face_Actor(kActorMcCoy, kActorRachael, true);
133 			Actor_Says(kActorMcCoy, 2710, 14);             // Excuse me
134 
135 			Actor_Says(kActorMcCoy, 2730, 12);             // RachaelRight
136 			AI_Movement_Track_Pause(kActorRachael);
137 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsInsideElevatorStartTalkAct3);
138 
139 			Game_Flag_Reset(kFlagMA01toMA06);
140 			Game_Flag_Reset(kFlagMA02toMA06);
141 			Game_Flag_Reset(kFlagMA07toMA06);
142 			Ambient_Sounds_Adjust_Looping_Sound(kSfxSPINUP1,  0, 0, 1);
143 			Ambient_Sounds_Adjust_Looping_Sound(kSfxAPRTFAN1, 0, 0, 1);
144 			Ambient_Sounds_Adjust_Looping_Sound(kSfxELEAMB3,  0, 0, 1);
145 			Ambient_Sounds_Remove_Looping_Sound(kSfxSPINUP1,  1);         // stop elev moving sound
146 			Ambient_Sounds_Remove_Looping_Sound(kSfxAPRTFAN1, 1);         // stop other ambient
147 			Ambient_Sounds_Remove_Looping_Sound(kSfxELEAMB3,  1);         // stop other ambient
148 			Actor_Says_With_Pause(kActorRachael, 300, 1.0f, 14);  // GoodbyeMcCoy
149 			Actor_Says(kActorRachael, 310, 14);                   // Isnt ThisYourFloor --
150 			Actor_Says(kActorMcCoy, 2860, 14);                    // YouTakeCareOfYoursel
151 
152 			Set_Enter(kSetMA02_MA04, kSceneMA02);
153 			Scene_Loop_Start_Special(kSceneLoopModeChangeSet, kMA06LoopDoorClose, true);
154 			Sound_Play(kSfxELDOORO2, 100, 50, 50, 50);
155 		} else if (Game_Flag_Query(kFlagMA02toMA06)
156 			&& Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelIsInsideMcCoysElevatorAct4
157 		) {
158 			normalElevatorBusiness = false;
159 			// Act 4 deleted scene case with Rachael
160 			//
161 			// TODO fix animations - Do an Optimization pass
162 			// TODO Test - Skip panel selection but actually set the target floor and "MOVE elevator" to LOBBY (Floor > 1)
163 			//
164 			Game_Flag_Reset(kFlagMA06toMA01);
165 			Game_Flag_Reset(kFlagMA06ToMA02);
166 			Game_Flag_Reset(kFlagMA06toMA07);
167 			Ambient_Sounds_Adjust_Looping_Sound(kSfxELEAMB3, 10, 0, 1);
168 			Ambient_Sounds_Adjust_Looping_Sound(kSfxAPRTFAN1, 10, 0, 1);
169 
170 			Actor_Says(kActorAnsweringMachine, 80, 3);      // your floor number please
171 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsInsideElevatorStartTalkAct4);
172 			//
173 			Delay(500);
174 			Game_Flag_Reset(kFlagMA01toMA06);
175 			Game_Flag_Reset(kFlagMA02toMA06);
176 			Game_Flag_Reset(kFlagMA07toMA06);
177 			Ambient_Sounds_Adjust_Looping_Sound(kSfxSPINUP1,  0, 0, 1);
178 			Ambient_Sounds_Adjust_Looping_Sound(kSfxAPRTFAN1, 0, 0, 1);
179 			Ambient_Sounds_Adjust_Looping_Sound(kSfxELEAMB3,  0, 0, 1);
180 			Ambient_Sounds_Remove_Looping_Sound(kSfxSPINUP1,  1);         // stop elev moving sound
181 			Ambient_Sounds_Remove_Looping_Sound(kSfxAPRTFAN1, 1);         // stop other ambient
182 			Ambient_Sounds_Remove_Looping_Sound(kSfxELEAMB3,  1);         // stop other ambient
183 
184 //			Player_Gains_Control();
185 			Set_Enter(kSetMA07, kSceneMA07);
186 			Scene_Loop_Start_Special(kSceneLoopModeChangeSet, kMA06LoopDoorClose, true);
187 			Sound_Play(kSfxELDOORO2, 100, 50, 50, 50);
188 		} else {
189 			// normal elevator business
190 			normalElevatorBusiness = true;
191 		}
192 	} // end of cut content
193 	if (normalElevatorBusiness) {
194 		// normal elevator business
195 		activateElevator();
196 
197 		if (isElevatorOnDifferentFloor()) {
198 			Sound_Play(kSfxSPINUP1, 25, 0, 0, 50);
199 			Delay(4000);
200 		}
201 
202 		Game_Flag_Reset(kFlagMA01toMA06);
203 		Game_Flag_Reset(kFlagMA02toMA06);
204 		Game_Flag_Reset(kFlagMA07toMA06);
205 
206 		if (Game_Flag_Query(kFlagMA06toMA01)) {
207 			Set_Enter(kSetMA01, kSceneMA01);
208 		} else if (Game_Flag_Query(kFlagMA06ToMA02)) {
209 			Set_Enter(kSetMA02_MA04, kSceneMA02);
210 		} else {
211 			Set_Enter(kSetMA07, kSceneMA07);
212 		}
213 
214 		Scene_Loop_Start_Special(kSceneLoopModeChangeSet, kMA06LoopDoorClose, true);
215 		Sound_Play(kSfxELDOORO2, 100, 50, 50, 50);
216 	}
217 }
218 
PlayerWalkedOut()219 void SceneScriptMA06::PlayerWalkedOut() {
220 	Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
221 	Ambient_Sounds_Remove_All_Looping_Sounds(1);
222 	Player_Gains_Control();
223 	if (_vm->_cutContent) {
224 		if (Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelIsInsideElevatorStartTalkAct3) {
225 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelAtEndOfAct3IfMetWithMcCoy);
226 		}
227 		else if (Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelIsInsideElevatorStartTalkAct4) {
228 			Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsOutsideMcCoysBuildingAct4);
229 		}
230 	}
231 }
232 
DialogueQueueFlushed(int a1)233 void SceneScriptMA06::DialogueQueueFlushed(int a1) {
234 }
235 
isElevatorOnDifferentFloor()236 bool SceneScriptMA06::isElevatorOnDifferentFloor() {
237 	return (Game_Flag_Query(kFlagMA01toMA06) && !Game_Flag_Query(kFlagMA06toMA01))
238 		|| (Game_Flag_Query(kFlagMA02toMA06) && !Game_Flag_Query(kFlagMA06ToMA02))
239 		|| (Game_Flag_Query(kFlagMA07toMA06) && !Game_Flag_Query(kFlagMA06toMA07));
240 }
241 
activateElevator()242 void SceneScriptMA06::activateElevator() {
243 	Game_Flag_Reset(kFlagMA06toMA01);
244 	Game_Flag_Reset(kFlagMA06ToMA02);
245 	Game_Flag_Reset(kFlagMA06toMA07);
246 
247 	while (true) {
248 		if (Game_Flag_Query(kFlagMA06ToMA02)) {
249 			break;
250 		}
251 		if (Game_Flag_Query(kFlagMA06toMA01)) {
252 			break;
253 		}
254 		if (Game_Flag_Query(kFlagMA06toMA07)) {
255 			break;
256 		}
257 
258 		Actor_Says(kActorAnsweringMachine, 80, kAnimationModeTalk);
259 		Player_Gains_Control();
260 		int floorLevel = Elevator_Activate(kElevatorMA);
261 #if BLADERUNNER_ORIGINAL_BUGS
262 #else
263 		// Fix for a crash/ freeze bug;
264 		//  To reproduce original issue: in Act 4, visit Rajiff, then exit to ground floor. Re-enter elevator and press Alt+F4
265 		if (floorLevel < 0) {
266 			break;
267 		}
268 #endif // BLADERUNNER_ORIGINAL_BUGS
269 		Player_Loses_Control();
270 
271 		Scene_Loop_Start_Special(kSceneLoopModeOnce, kMA06LoopMainLoop, true);
272 
273 		if (floorLevel > 1) {
274 			Game_Flag_Set(kFlagMA06toMA07);
275 		} else if (floorLevel == 1) {
276 			if (Game_Flag_Query(kFlagSpinnerAtMA01)) {
277 				Game_Flag_Set(kFlagMA06toMA01);
278 			} else {
279 				Sound_Play(kSfxELEBAD1, 100, 0, 0, 50);
280 				Delay(500);
281 				Actor_Says(kActorAnsweringMachine, 610, 3);
282 			}
283 		} else { // floorLevel == 0
284 			Actor_Says(kActorMcCoy, 2940, 18);
285 			if (Global_Variable_Query(kVariableChapter) == 4
286 			 && Game_Flag_Query(kFlagMA02RajifTalk)
287 			) {
288 				Sound_Play(kSfxELEBAD1, 100, 0, 0, 50);
289 				Delay(500);
290 				Actor_Says(kActorAnsweringMachine, 610, kAnimationModeTalk);
291 				Delay(500);
292 				Actor_Says(kActorMcCoy, 8527, kAnimationModeTalk);
293 			} else {
294 				Game_Flag_Set(kFlagMA06ToMA02);
295 				Actor_Says(kActorAnsweringMachine, 90, 3);
296 			}
297 		}
298 	}
299 }
300 
301 } // End of namespace BladeRunner
302