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/ai_script.h"
24 
25 namespace BladeRunner {
26 
AIScriptSadik(BladeRunnerEngine * vm)27 AIScriptSadik::AIScriptSadik(BladeRunnerEngine *vm) : AIScriptBase(vm) {
28 	_resumeIdleAfterFramesetCompletesFlag = false;
29 	_nextSoundId = -1; // changed from original (0) to be more clear that this is an invalid sfx id
30 	// _varChooseIdleAnimation can have valid values: 0, 1
31 	_varChooseIdleAnimation = 0;
32 	_varNumOfTimesToHoldCurrentFrame = 0;
33 	_var4 = 1;
34 }
35 
Initialize()36 void AIScriptSadik::Initialize() {
37 	_animationFrame = 0;
38 	_animationState = 0;
39 	_animationStateNext = 0;
40 	_animationNext = 0;
41 
42 	_resumeIdleAfterFramesetCompletesFlag = false;
43 	_nextSoundId = -1; // changed from original (0) to be more clear that this is an invalid sfx id
44 	_varChooseIdleAnimation = 0;
45 	_varNumOfTimesToHoldCurrentFrame = 0;
46 	_var4 = 1;
47 
48 	Actor_Put_In_Set(kActorSadik, kSetFreeSlotA);
49 	Actor_Set_At_Waypoint(kActorSadik, 33, 0);
50 	Actor_Set_Goal_Number(kActorSadik, kGoalSadikDefault);
51 }
52 
Update()53 bool AIScriptSadik::Update() {
54 	if ( Global_Variable_Query(kVariableChapter) == 2
55 	 &&  Player_Query_Current_Scene() == kSceneBB09
56 	 && !Game_Flag_Query(kFlagBB09SadikRun)
57 	) {
58 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikRunFromBB09);
59 		Actor_Set_Targetable(kActorSadik, true);
60 		Game_Flag_Set(kFlagBB09SadikRun);
61 		Game_Flag_Set(kFlagUnused406);
62 		return true;
63 	}
64 
65 	if (_nextSoundId != -1) { // changed from original (0) to be more clear that this is an invalid sfx id
66 		Sound_Play(_nextSoundId, 100, 0, 0, 50);
67 		_nextSoundId = -1;   // changed from original (0) to be more clear that this is an invalid sfx id
68 	}
69 
70 	if (Global_Variable_Query(kVariableChapter) == 3
71 	 && Actor_Query_Goal_Number(kActorSadik) < 200
72 	) {
73 		Actor_Set_Goal_Number(kActorSadik, 200);
74 	}
75 
76 	if (Global_Variable_Query(kVariableChapter) == 5
77 	 && Actor_Query_Goal_Number(kActorSadik) < 400
78 	) {
79 		Actor_Set_Goal_Number(kActorSadik, 400);
80 	}
81 
82 	if (Actor_Query_Goal_Number(kActorSadik) == 411) {
83 		if (Game_Flag_Query(kFlagNotUsed657)) {
84 			Actor_Set_Goal_Number(kActorSadik, 412);
85 		}
86 	}
87 	return false;
88 }
89 
TimerExpired(int timer)90 void AIScriptSadik::TimerExpired(int timer) {
91 	if (timer == kActorTimerAIScriptCustomTask0) {
92 		AI_Countdown_Timer_Reset(kActorSadik, kActorTimerAIScriptCustomTask0);
93 
94 		// goals 303, 304 and 305 are never set,  cut out part of game?
95 		switch (Actor_Query_Goal_Number(kActorSadik)) {
96 		case kGoalSadikUG18Decide:
97 			Actor_Set_Goal_Number(kActorSadik, 305);
98 			break;
99 
100 		case 303:
101 			Actor_Set_Goal_Number(kActorSadik, 305);
102 			break;
103 
104 		case kGoalSadikUG18PrepareShootMcCoy:
105 			Actor_Set_Goal_Number(kActorSadik, kGoalSadikUG18ShootMcCoy);
106 			break;
107 		}
108 	}
109 }
110 
CompletedMovementTrack()111 void AIScriptSadik::CompletedMovementTrack() {
112 	switch (Actor_Query_Goal_Number(kActorSadik)) {
113 	case kGoalSadikRunFromBB09:
114 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikBB11Wait);
115 		break;
116 
117 	case kGoalSadikBB11CatchMcCoy:
118 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikBB11KnockOutMcCoy);
119 		break;
120 
121 	case kGoalSadikBB11KnockOutMcCoy:
122 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikBB11KickMcCoy);
123 		break;
124 
125 	case kGoalSadikUG18Move:
126 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikUG18Decide);
127 		break;
128 
129 	default:
130 		return; //false;
131 	}
132 
133 	return; //true;
134 }
135 
ReceivedClue(int clueId,int fromActorId)136 void AIScriptSadik::ReceivedClue(int clueId, int fromActorId) {
137 	//return false;
138 }
139 
ClickedByPlayer()140 void AIScriptSadik::ClickedByPlayer() {
141 	if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikGone) {
142 		Actor_Face_Actor(kActorMcCoy, kActorSadik, true);
143 		Actor_Says(kActorMcCoy, 8580, 16);
144 	}
145 }
146 
EnteredSet(int setId)147 void AIScriptSadik::EnteredSet(int setId) {
148 	// return false;
149 }
150 
OtherAgentEnteredThisSet(int otherActorId)151 void AIScriptSadik::OtherAgentEnteredThisSet(int otherActorId) {
152 	// return false;
153 }
154 
OtherAgentExitedThisSet(int otherActorId)155 void AIScriptSadik::OtherAgentExitedThisSet(int otherActorId) {
156 	// return false;
157 }
158 
OtherAgentEnteredCombatMode(int otherActorId,int combatMode)159 void AIScriptSadik::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
160 	// return false;
161 }
162 
ShotAtAndMissed()163 void AIScriptSadik::ShotAtAndMissed() {
164 	if (Actor_Query_Goal_Number(kActorSadik) == 414
165 	 || Actor_Query_Goal_Number(kActorSadik) == kGoalSadikKP06NeedsReactorCoreFromMcCoy
166 	) {
167 		Game_Flag_Set(kFlagMcCoyAttackedReplicants);
168 		if (Actor_Query_Which_Set_In(kActorSadik) != kSetKP07) {
169 			Actor_Set_Goal_Number(kActorSadik, 418);
170 			Scene_Exits_Disable();
171 		}
172 	}
173 }
174 
ShotAtAndHit()175 bool AIScriptSadik::ShotAtAndHit() {
176 #if BLADERUNNER_ORIGINAL_BUGS // Sadik killed in BB09 dead end bug fix
177 #else
178 	if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikRunFromBB09) {
179 		// Like Izo's ShotAtAndHit() and the code below for kGoalSadikUG18Move
180 		// this will keep resetting Sadik's health to avoid killing him
181 		// Still, this is lowering Sadik's health from 80 (when Replicant) and 50 (when Human)
182 		if (Game_Flag_Query(kFlagSadikIsReplicant)) {
183 			Actor_Set_Health(kActorSadik, 60, 60);
184 		} else {
185 			Actor_Set_Health(kActorSadik, 40, 40);
186 		}
187 		return true;
188 	}
189 #endif // BLADERUNNER_ORIGINAL_BUGS
190 	if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikUG18Move) {
191 		// this lowers Sadik's original health but makes it impossible to kill him here (UG18)
192 		if (Game_Flag_Query(kFlagSadikIsReplicant)) {
193 #if BLADERUNNER_ORIGINAL_BUGS
194 			Actor_Set_Health(kActorSadik, 60, 60);
195 #else
196 			// Sadik killed in BB09 dead end bug fix
197 			if (Actor_Query_Current_HP(kActorSadik) == 60) { // shot also at Bradbury, so lower his health further
198 				Actor_Set_Health(kActorSadik, 50, 50);
199 			} else {
200 				Actor_Set_Health(kActorSadik, 60, 60);
201 			}
202 #endif
203 		} else {
204 #if BLADERUNNER_ORIGINAL_BUGS
205 			Actor_Set_Health(kActorSadik, 40, 40);
206 #else
207 			// Sadik killed in BB09 dead end bug fix
208 			if (Actor_Query_Current_HP(kActorSadik) == 40) { // shot also at Bradbury, so lower his health further
209 				Actor_Set_Health(kActorSadik, 30, 30);
210 			} else {
211 				Actor_Set_Health(kActorSadik, 40, 40);
212 			}
213 #endif
214 		}
215 		return true;
216 	}
217 
218 	if (Actor_Query_Goal_Number(kActorSadik) == 414
219 	 || Actor_Query_Goal_Number(kActorSadik) == kGoalSadikKP06NeedsReactorCoreFromMcCoy
220 	) {
221 		Game_Flag_Set(kFlagMcCoyAttackedReplicants);
222 		if (Actor_Query_Which_Set_In(kActorSadik) != kSetKP07) {
223 			Actor_Set_Goal_Number(kActorSadik, 418);
224 			Scene_Exits_Disable();
225 		}
226 	}
227 	return false;
228 }
229 
Retired(int byActorId)230 void AIScriptSadik::Retired(int byActorId) {
231 	if ((Actor_Query_Goal_Number(kActorSadik) == 418
232 	  || Actor_Query_Goal_Number(kActorSadik) == 450
233 	 )
234 	 && Actor_Query_Which_Set_In(kActorSadik) != kSetKP07
235 	) {
236 		Scene_Exits_Enable();
237 	}
238 
239 	if (Actor_Query_In_Set(kActorSadik, kSetKP07)) {
240 		Global_Variable_Decrement(kVariableReplicantsSurvivorsAtMoonbus, 1); // can't Sadik still be human (Rep-sympathiser here? A bug?
241 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikGone);
242 
243 		if (Global_Variable_Query(kVariableReplicantsSurvivorsAtMoonbus) == 0) {
244 			Player_Loses_Control();
245 			Delay(2000);
246 			Player_Set_Combat_Mode(false);
247 			Loop_Actor_Walk_To_XYZ(kActorMcCoy, -12.0f, -41.58f, 72.0f, 0, true, false, false);
248 			Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
249 			Ambient_Sounds_Remove_All_Looping_Sounds(1u);
250 			Game_Flag_Set(kFlagKP07toKP06);
251 			Game_Flag_Reset(kFlagMcCoyIsHelpingReplicants);
252 			Set_Enter(kSetKP05_KP06, kSceneKP06);
253 			return; //true;
254 		}
255 	}
256 
257 	Actor_Set_Goal_Number(kActorSadik, kGoalSadikGone);
258 
259 	return; //false;
260 }
261 
GetFriendlinessModifierIfGetsClue(int otherActorId,int clueId)262 int AIScriptSadik::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
263 	return 0;
264 }
265 
GoalChanged(int currentGoalNumber,int newGoalNumber)266 bool AIScriptSadik::GoalChanged(int currentGoalNumber, int newGoalNumber) {
267 	switch (newGoalNumber) {
268 	case kGoalSadikDefault:
269 		AI_Movement_Track_Flush(kActorSadik);
270 		AI_Movement_Track_Append(kActorSadik, 33, 0);
271 		AI_Movement_Track_Repeat(kActorSadik);
272 		return true;
273 
274 	case kGoalSadikRunFromBB09:
275 		AI_Movement_Track_Flush(kActorSadik);
276 		AI_Movement_Track_Append_Run(kActorSadik, 131, 0);
277 		AI_Movement_Track_Append_Run(kActorSadik, 132, 0);
278 		AI_Movement_Track_Append_Run(kActorSadik, 133, 0);
279 		AI_Movement_Track_Repeat(kActorSadik);
280 		return true;
281 
282 	case kGoalSadikBB11Wait:
283 		AI_Movement_Track_Flush(kActorSadik);
284 		AI_Movement_Track_Append(kActorSadik, 313, 0);
285 		AI_Movement_Track_Repeat(kActorSadik);
286 		Game_Flag_Set(kFlagBB11SadikFight);
287 		return true;
288 
289 	case kGoalSadikBB11ThrowMcCoy:
290 		Actor_Set_Immunity_To_Obstacles(kActorSadik, true);
291 		Actor_Face_Heading(kActorSadik, kActorMcCoy, kActorMcCoy);
292 		_animationState = 32;
293 		_animationFrame = -1;
294 		Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
295 		return true;
296 
297 	case kGoalSadikBB11CatchMcCoy:
298 		Actor_Set_Goal_Number(kActorMcCoy, kGoalMcCoyBB11GetUp);
299 		AI_Movement_Track_Flush(kActorSadik);
300 		AI_Movement_Track_Append(kActorSadik, 314, 0);
301 		AI_Movement_Track_Append_Run(kActorSadik, 317, 0);
302 		AI_Movement_Track_Repeat(kActorSadik);
303 		return true;
304 
305 	case kGoalSadikBB11KnockOutMcCoy:
306 		Actor_Change_Animation_Mode(kActorSadik, 62);
307 		return true;
308 
309 	case kGoalSadikBB11KickMcCoy:
310 		Actor_Face_Heading(kActorSadik, 100, false);
311 		Actor_Change_Animation_Mode(kActorSadik, 63);
312 		Actor_Set_Goal_Number(kActorClovis, kGoalClovisBB11WalkToMcCoy);
313 		Actor_Set_Immunity_To_Obstacles(kActorSadik, false);
314 		return true;
315 
316 	case kGoalSadikBB11TalkWithClovis:
317 		_nextSoundId = -1; // changed from original (0) to be more clear that this is an invalid sfx id
318 		return false;
319 
320 	case 200:
321 		Actor_Put_In_Set(kActorSadik, kSetFreeSlotA);
322 		Actor_Set_At_Waypoint(kActorSadik, 33, 0);
323 		Actor_Set_Goal_Number(kActorMcCoy, 199);
324 		return true;
325 
326 	case kGoalSadikUG18Wait:
327 		Actor_Put_In_Set(kActorSadik, kSetUG18);
328 		Actor_Set_At_XYZ(kActorSadik, 111.89f, 0.0f, 408.42f, 0);
329 		Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
330 		return true;
331 
332 	case kGoalSadikUG18Move:
333 		Actor_Set_Targetable(kActorSadik, true);
334 		World_Waypoint_Set(436, kSetUG18, -356.11f, 0.0f, 652.42f);
335 		AI_Movement_Track_Flush(kActorSadik);
336 		AI_Movement_Track_Append_Run(kActorSadik, 436, 0);
337 		AI_Movement_Track_Repeat(kActorSadik);
338 		return true;
339 
340 	case kGoalSadikUG18Decide:
341 		// This is called first and then the scene script SceneScriptUG18::ActorChangedGoal
342 		Actor_Set_Targetable(kActorSadik, false);
343 		return true;
344 
345 	// goals 303, 304 and 305 are never set,  cut out part of game?
346 	case 303:
347 		AI_Countdown_Timer_Reset(kActorSadik, kActorTimerAIScriptCustomTask0);
348 		AI_Countdown_Timer_Start(kActorSadik, kActorTimerAIScriptCustomTask0, 5);
349 		return true;
350 
351 	case 304:
352 		Actor_Set_Targetable(kActorSadik, false);
353 		AI_Countdown_Timer_Reset(kActorSadik, kActorTimerAIScriptCustomTask0);
354 		return true;
355 
356 	case 305:
357 		// fall through
358 	case kGoalSadikUG18WillShootMcCoy:
359 		// fall through
360 	case kGoalSadikUG18Leave:
361 		return true;
362 
363 	case kGoalSadikUG18PrepareShootMcCoy:
364 		Sound_Play(kSfxLGCAL1, 100, 0, 0, 50);
365 		AI_Countdown_Timer_Start(kActorSadik, kActorTimerAIScriptCustomTask0, 2);
366 		return true;
367 
368 	case kGoalSadikUG18ShootMcCoy:
369 		if (Player_Query_Current_Scene() == kSceneUG18) {
370 #if BLADERUNNER_ORIGINAL_BUGS
371 			Actor_Force_Stop_Walking(kActorMcCoy);
372 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatAttack);
373 			Sound_Play(kSfxLGCAL1, 100, 0, 0, 50);
374 			Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
375 			Actor_Retired_Here(kActorMcCoy, 6, 6, true, -1);
376 #else
377 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatAttack);
378 			Sound_Play(kSfxLGCAL1, 100, 0, 0, 50);
379 			Player_Loses_Control();
380 			Actor_Force_Stop_Walking(kActorMcCoy);
381 			Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
382 			Actor_Retired_Here(kActorMcCoy, 6, 6, true, kActorSadik);
383 #endif // BLADERUNNER_ORIGINAL_BUGS
384 		}
385 		return true;
386 
387 	case 309:
388 		AI_Countdown_Timer_Reset(kActorSadik, kActorTimerAIScriptCustomTask0);
389 		return true;
390 
391 	case 400:
392 		Actor_Set_Goal_Number(kActorSadik, 410);
393 		return true;
394 
395 	case 410:
396 		if (Game_Flag_Query(kFlagMcCoyIsHelpingReplicants) == 1) {
397 			Actor_Set_Goal_Number(kActorSadik, 414);
398 		} else {
399 			Actor_Set_Goal_Number(kActorSadik, 411);
400 		}
401 		return true;
402 
403 	case 411:
404 		Actor_Put_In_Set(kActorSadik, kSetKP05_KP06);
405 		Actor_Set_At_XYZ(kActorSadik, -1134.0f, 0.0f, 73.45f, 398);
406 		Actor_Set_Goal_Number(kActorClovis, kGoalClovisKP07Wait);
407 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Wait);
408 		return true;
409 
410 	case 412:
411 		Actor_Says(kActorSadik, 60, 3);
412 		Actor_Says(kActorMcCoy, 2240, 3);
413 		Actor_Says(kActorSadik, 70, 3);
414 		Actor_Says(kActorSadik, 80, 3);
415 		Actor_Says(kActorMcCoy, 2245, 3);
416 		Actor_Says(kActorSadik, 90, 3);
417 		Actor_Says(kActorSadik, 100, 3);
418 		Actor_Says(kActorMcCoy, 2250, 3);
419 		Actor_Set_Goal_Number(kActorSadik, 413);
420 		return true;
421 
422 	case 413:
423 		Loop_Actor_Walk_To_XYZ(kActorSadik, -1062.0f, 0.0f, 219.0f, 0, false, true, false);
424 		Actor_Set_Targetable(kActorSadik, true);
425 		Non_Player_Actor_Combat_Mode_On(kActorSadik, kActorCombatStateIdle, true, kActorMcCoy, 9, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 15, 300, false);
426 		Actor_Set_Goal_Number(kActorSadik, 450);
427 		return true;
428 
429 	case 414:
430 		Actor_Put_In_Set(kActorSadik, kSetKP05_KP06);
431 		Actor_Set_At_XYZ(kActorSadik, -961.0f, 0.0f, -778.0f, 150);
432 		Actor_Set_Targetable(kActorSadik, true);
433 		return true;
434 
435 	case 415:
436 		Actor_Says(kActorSadik, 110, kAnimationModeTalk);
437 		Actor_Says(kActorMcCoy, 2290, kAnimationModeTalk);
438 		Actor_Says(kActorSadik, 310, kAnimationModeTalk);
439 		Actor_Says(kActorMcCoy, 2300, kAnimationModeTalk);
440 		if (Game_Flag_Query(kFlagSadikIsReplicant)) {
441 			Actor_Says(kActorSadik, 180, kAnimationModeTalk);
442 			Actor_Says(kActorSadik, 190, kAnimationModeTalk);
443 			Actor_Says(kActorMcCoy, 2310, kAnimationModeTalk);
444 			Actor_Says(kActorSadik, 200, kAnimationModeTalk);
445 		} else {
446 			Actor_Says(kActorSadik, 140, kAnimationModeTalk);
447 			Actor_Says(kActorSadik, 150, kAnimationModeTalk);
448 			Actor_Says(kActorMcCoy, 2305, kAnimationModeTalk);
449 			Actor_Says(kActorSadik, 160, kAnimationModeTalk);
450 			Actor_Says(kActorSadik, 170, kAnimationModeTalk);
451 		}
452 		Actor_Says(kActorMcCoy, 2315, kAnimationModeTalk);
453 		Actor_Says(kActorSadik, 210, kAnimationModeTalk);
454 		Actor_Says(kActorSadik, 220, kAnimationModeTalk);
455 		Actor_Says(kActorSadik, 230, kAnimationModeTalk);
456 		Actor_Says(kActorSadik, 240, kAnimationModeTalk);
457 		Actor_Says(kActorSadik, 250, kAnimationModeTalk);
458 		Actor_Says(kActorSadik, 260, kAnimationModeTalk);
459 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikKP06NeedsReactorCoreFromMcCoy);
460 		return true;
461 
462 	case kGoalSadikKP06NeedsReactorCoreFromMcCoy:
463 		Loop_Actor_Walk_To_XYZ(kActorSadik, -961.0f, 0.0f, -778.0f, 0, false, false, false);
464 		Actor_Face_Heading(kActorSadik, 150, false);
465 		return true;
466 
467 	case 417:
468 		Actor_Face_Actor(kActorSadik, kActorMcCoy, true);
469 		Actor_Says(kActorSadik, 320, kAnimationModeTalk);
470 		Loop_Actor_Walk_To_XYZ(kActorSadik, -857.0f, 0.0f, -703.0f, 0, false, true, false);
471 		Actor_Says(kActorMcCoy, 2330, kAnimationModeTalk);
472 		Actor_Says(kActorSadik, 330, kAnimationModeTalk);
473 		Actor_Says(kActorMcCoy, 2335, kAnimationModeTalk);
474 		Actor_Says(kActorSadik, 340, kAnimationModeTalk);
475 		Actor_Set_Goal_Number(kActorSadik, kGoalSadikKP06NeedsReactorCoreFromMcCoy);
476 		return true;
477 
478 	case 418:
479 		Game_Flag_Reset(kFlagMcCoyIsHelpingReplicants);
480 		Actor_Set_Goal_Number(kActorClovis, kGoalClovisKP07LayDown);
481 		Non_Player_Actor_Combat_Mode_On(kActorSadik, kActorCombatStateIdle, true, kActorMcCoy, 9, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 15, 300, false);
482 		return true;
483 
484 	case 419:
485 		Actor_Put_In_Set(kActorSadik, kSetKP07);
486 		Actor_Set_At_XYZ(kActorSadik, -12.0f, -41.58f, 72.0f, 0);
487 		return true;
488 
489 	case 420:
490 		// fall through
491 	case 450:
492 		return true;
493 	}
494 	return false;
495 }
496 
UpdateAnimation(int * animation,int * frame)497 bool AIScriptSadik::UpdateAnimation(int *animation, int *frame) {
498 	switch (_animationState) {
499 	case 0:
500 		if (_varChooseIdleAnimation == 1) {
501 			*animation = kModelAnimationSadikShiftsShoulders;
502 			++_animationFrame;
503 			if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikShiftsShoulders)) {
504 				*animation = kModelAnimationSadikIdle;
505 				_animationFrame = 0;
506 				_varChooseIdleAnimation = 0;
507 			}
508 		} else if (_varChooseIdleAnimation == 0) {
509 			*animation = kModelAnimationSadikIdle;
510 			if (_varNumOfTimesToHoldCurrentFrame > 0) {
511 				--_varNumOfTimesToHoldCurrentFrame;
512 				if (!Random_Query(0, 6)) {
513 					_var4 = -_var4;
514 				}
515 			} else {
516 				_animationFrame += _var4;
517 				if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikIdle)) {
518 					_animationFrame = 0;
519 				}
520 				if (_animationFrame < 0) {
521 					_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikIdle) - 1;
522 				}
523 				if (!Random_Query(0, 4)) {
524 					_varNumOfTimesToHoldCurrentFrame = 1;
525 				}
526 				if (_animationFrame == 0 || _animationFrame == 8) {
527 					_varNumOfTimesToHoldCurrentFrame = Random_Query(2, 8);
528 				}
529 				if (!Random_Query(0, 2)) {
530 					if (_animationFrame == 0) {
531 						_varChooseIdleAnimation = 1;
532 						_varNumOfTimesToHoldCurrentFrame = 0;
533 						*animation = kModelAnimationSadikShiftsShoulders;
534 					}
535 				}
536 			}
537 		}
538 		break;
539 
540 	case 1:
541 		// fall through
542 	case 2:
543 		// fall through
544 	case 3:
545 		// fall through
546 	case 4:
547 		// fall through
548 	case 5:
549 		// fall through
550 	case 6:
551 		switch (_animationState) {
552 		case 1:
553 			*animation = kModelAnimationSadikWalking;
554 			break;
555 
556 		case 2:
557 			*animation = kModelAnimationSadikRunning;
558 			break;
559 
560 		case 3:
561 			*animation = kModelAnimationSadikCombatWalking;
562 			break;
563 
564 		case 4:
565 			*animation = kModelAnimationSadikCombatRunning;
566 			break;
567 
568 		case 6:
569 			*animation = kModelAnimationSadikClimbLadderUp;
570 			break;
571 
572 		case 5:
573 			*animation = kModelAnimationSadikClimbLadderDown;
574 			break;
575 		}
576 		++_animationFrame;
577 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
578 			_animationFrame = 0;
579 		}
580 		break;
581 
582 	case 7:
583 		*animation = kModelAnimationSadikCombatIdle;
584 		++_animationFrame;
585 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatIdle)) {
586 			_animationFrame = 0;
587 		}
588 		break;
589 
590 	case 8:
591 		*animation = kModelAnimationSadikCombatTurnRight;
592 		++_animationFrame;
593 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatTurnRight)) {
594 			_animationFrame = 0;
595 			_animationState = 7;
596 			*animation = kModelAnimationSadikCombatIdle;
597 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
598 		}
599 		break;
600 
601 	case 9:
602 		*animation = kModelAnimationSadikCombatTurnLeft;
603 		++_animationFrame;
604 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatTurnLeft)) {
605 			_animationFrame = 0;
606 			_animationState = 7;
607 			*animation = kModelAnimationSadikCombatIdle;
608 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
609 		}
610 		break;
611 
612 	case 10:
613 		*animation = kModelAnimationSadikGotHitFront;
614 		++_animationFrame;
615 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikGotHitFront)) {
616 			*animation = kModelAnimationSadikIdle;
617 			_animationFrame = 0;
618 			_animationState = 0;
619 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
620 		}
621 		break;
622 
623 	case 11:
624 		*animation = kModelAnimationSadikGotHitMore;
625 		++_animationFrame;
626 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikGotHitMore)) {
627 			*animation = kModelAnimationSadikIdle;
628 			_animationFrame = 0;
629 			_animationState = 0;
630 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
631 		}
632 		break;
633 
634 	case 12:
635 		*animation = kModelAnimationSadikCombatGotHitFront;
636 		++_animationFrame;
637 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatGotHitFront)) {
638 			_animationFrame = 0;
639 			_animationState = 7;
640 			*animation = kModelAnimationSadikCombatIdle;
641 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
642 		}
643 		break;
644 
645 	case 13:
646 		*animation = kModelAnimationSadikCombatGotHitMore;
647 		++_animationFrame;
648 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatGotHitMore)) {
649 			_animationFrame = 0;
650 			_animationState = 7;
651 			*animation = kModelAnimationSadikCombatIdle;
652 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
653 		}
654 		break;
655 
656 	case 14:
657 		*animation = kModelAnimationSadikShotDead;
658 		if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikShotDead) - 1) {
659 			++_animationFrame;
660 		}
661 		break;
662 
663 	case 15:
664 		// A bug? This is identical to case 14. Maybe make case 14 fall through?
665 		*animation = kModelAnimationSadikShotDead;
666 		if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikShotDead) - 1) {
667 			++_animationFrame;
668 		}
669 		break;
670 
671 	case 16:
672 		*animation = kModelAnimationSadikCombatUnholsterGun;
673 		++_animationFrame;
674 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatUnholsterGun)) {
675 			_animationFrame = 0;
676 			_animationState = 7;
677 			*animation = kModelAnimationSadikCombatIdle;
678 		}
679 		break;
680 
681 	case 17:
682 		*animation = kModelAnimationSadikCombatHolsterGun;
683 		++_animationFrame;
684 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatHolsterGun)) {
685 			*animation = kModelAnimationSadikIdle;
686 			_animationFrame = 0;
687 			_animationState = 0;
688 		}
689 		break;
690 
691 	case 18:
692 		*animation = kModelAnimationSadikCombatFireGunAndReturnToPoseIdle;
693 		++_animationFrame;
694 		if (_animationFrame == 5) {
695 			int snd;
696 			if (Random_Query(1, 2) == 1) {
697 				snd = 9010;
698 			} else {
699 				snd = 9015;
700 			}
701 			Sound_Play_Speech_Line(kActorSadik, snd, 75, 0, 99);
702 		}
703 		if (_animationFrame == 7) {
704 			Actor_Combat_AI_Hit_Attempt(kActorSadik);
705 		}
706 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCombatFireGunAndReturnToPoseIdle)) {
707 			_animationFrame = 0;
708 			_animationState = 7;
709 			*animation = kModelAnimationSadikCombatIdle;
710 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeCombatIdle);
711 		}
712 		break;
713 
714 	case 19:
715 		*animation = kModelAnimationSadikCalmTalk;
716 		if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
717 			*animation = kModelAnimationSadikIdle;
718 			_animationState = 0;
719 			_resumeIdleAfterFramesetCompletesFlag = false;
720 		} else {
721 			++_animationFrame;
722 			if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikCalmTalk)) {
723 				_animationFrame = 0;
724 			}
725 		}
726 		break;
727 
728 	case 20:
729 		// fall through
730 	case 21:
731 		// fall through
732 	case 22:
733 		// fall through
734 	case 23:
735 		// fall through
736 	case 24:
737 		// fall through
738 	case 25:
739 		// fall through
740 	case 26:
741 		switch (_animationState) {
742 		case 20:
743 			*animation = kModelAnimationSadikMoreCalmTalk;
744 			break;
745 
746 		case 21:
747 			*animation = kModelAnimationSadikSuggestTalk;
748 			break;
749 
750 		case 22:
751 			*animation = kModelAnimationSadikUrgeTalk;
752 			break;
753 
754 		case 23:
755 			*animation = kModelAnimationSadikAccuseTalk;
756 			break;
757 
758 		case 24:
759 			*animation = kModelAnimationSadikProtestTalk;
760 			break;
761 
762 		case 25:
763 			*animation = kModelAnimationSadikMockTalk;
764 			break;
765 
766 		default:
767 			*animation = kModelAnimationSadikThisAndThatTalk;
768 			break;
769 		}
770 		++_animationFrame;
771 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
772 			_animationFrame = 0;
773 			_animationState = 19;
774 			*animation = kModelAnimationSadikCalmTalk;
775 		}
776 		break;
777 
778 	case 27:
779 		*animation = kModelAnimationSadikGesturePointOrGive;
780 		++_animationFrame;
781 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikGesturePointOrGive)) {
782 			*animation = kModelAnimationSadikIdle;
783 			_animationFrame = 0;
784 			_animationState = 0;
785 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
786 		}
787 		break;
788 
789 	case 28:
790 		*animation = kModelAnimationSadikJumpAcross;
791 		++_animationFrame;
792 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikJumpAcross)) {
793 			*animation = kModelAnimationSadikIdle;
794 			_animationFrame = 0;
795 			_animationState = 0;
796 		}
797 		break;
798 
799 	case 29:
800 		*animation = kModelAnimationSadikHangingDropsDown;
801 		++_animationFrame;
802 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikHangingDropsDown)) {
803 			*animation = kModelAnimationSadikIdle;
804 			_animationFrame = 0;
805 			_animationState = 0;
806 		}
807 		break;
808 
809 	case 30:
810 		*animation = kModelAnimationSadikKicksSomeoneWhoIsDown;
811 		++_animationFrame;
812 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikKicksSomeoneWhoIsDown)) {
813 			*animation = kModelAnimationSadikIdle;
814 			_animationFrame = 0;
815 			_animationState = 0;
816 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
817 		}
818 		break;
819 
820 	case 31:
821 		*animation = kModelAnimationSadikHoldsSomeoneAndPunches;
822 		++_animationFrame;
823 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSadikHoldsSomeoneAndPunches)) {
824 			*animation = kModelAnimationSadikIdle;
825 			_animationFrame = 0;
826 			_animationState = 0;
827 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
828 		}
829 		break;
830 
831 	case 32:
832 		*animation = kModelAnimationSadikPicksUpAndThrowsMcCoy;
833 		++_animationFrame;
834 		if (_animationFrame == 23) {
835 			_nextSoundId = kSfxMTLDOOR2;
836 		}
837 		if (_animationFrame >= 25) {
838 			// TODO last frames 27-30 are empty
839 			//      but maybe we could still accept frames 25 and 26!
840 			_animationFrame = 0;
841 			_animationState = 0;
842 			*animation = kModelAnimationSadikIdle;
843 			Actor_Set_Goal_Number(kActorSadik, kGoalSadikBB11CatchMcCoy);
844 		}
845 		break;
846 
847 	case 33:
848 		*animation = kModelAnimationSadikHoldsSomeoneAndPunches;
849 		++_animationFrame;
850 		if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikBB11KnockOutMcCoy) {
851 			if (_animationFrame == 4) {
852 				_nextSoundId = kSfxPUNCH1;
853 			}
854 			if (_animationFrame == 6) {
855 				Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeHit);
856 			}
857 		}
858 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
859 			*animation = kModelAnimationSadikIdle;
860 			_animationFrame = 0;
861 			_animationState = 0;
862 
863 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
864 			if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikBB11KnockOutMcCoy) {
865 				Actor_Change_Animation_Mode(kActorSadik, 63);
866 			}
867 		}
868 		break;
869 
870 	case 34:
871 		*animation = kModelAnimationSadikKicksSomeoneWhoIsDown;
872 		++_animationFrame;
873 		if (_animationFrame == 4) {
874 			if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikBB11KnockOutMcCoy) {
875 				Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
876 				_nextSoundId = kSfxKICK1;
877 			} else {
878 				Actor_Change_Animation_Mode(kActorMcCoy, 68);
879 				_nextSoundId = kSfxKICK2;
880 			}
881 		}
882 
883 		if (_animationFrame >= 15) {
884 			*animation = kModelAnimationSadikIdle;
885 			_animationFrame = 0;
886 			_animationState = 0;
887 			Actor_Change_Animation_Mode(kActorSadik, kAnimationModeIdle);
888 			if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikBB11KnockOutMcCoy) {
889 				AI_Movement_Track_Flush(kActorSadik);
890 				AI_Movement_Track_Append(kActorSadik, 318, 0);
891 				AI_Movement_Track_Repeat(kActorSadik);
892 			} else {
893 				if (Actor_Query_Goal_Number(kActorSadik) == kGoalSadikBB11KickMcCoy) {
894 					Actor_Change_Animation_Mode(kActorSadik, 63);
895 				}
896 			}
897 		}
898 		break;
899 
900 	default:
901 		// Dummy placeholder, kModelAnimationZubenIdle (406) is a Zuben animation
902 		*animation = kModelAnimationZubenIdle;
903 		_animationFrame = 0;
904 		break;
905 	}
906 
907 	*frame = _animationFrame;
908 
909 	return true;
910 }
911 
ChangeAnimationMode(int mode)912 bool AIScriptSadik::ChangeAnimationMode(int mode) {
913 	Actor_Set_Frame_Rate_FPS(kActorSadik, -2);
914 
915 	switch (mode) {
916 	case kAnimationModeIdle:
917 		switch (_animationState) {
918 		case 19:
919 			// fall through
920 		case 20:
921 			// fall through
922 		case 21:
923 			// fall through
924 		case 22:
925 			// fall through
926 		case 23:
927 			// fall through
928 		case 24:
929 			// fall through
930 		case 25:
931 			// fall through
932 		case 26:
933 			_resumeIdleAfterFramesetCompletesFlag = true;
934 			break;
935 
936 		case 30:
937 			// fall through
938 		case 31:
939 			return 1;
940 
941 		default:
942 			_animationState = 0;
943 			_animationFrame = 0;
944 			_varNumOfTimesToHoldCurrentFrame = 0;
945 			break;
946 		}
947 		break;
948 
949 	case kAnimationModeWalk:
950 		_animationFrame = 0;
951 		_animationState = 1;
952 		break;
953 
954 	case kAnimationModeRun:
955 		_animationFrame = 0;
956 		_animationState = 2;
957 		break;
958 
959 	case kAnimationModeTalk:
960 		_animationState = 20;
961 		_animationFrame = 0;
962 		break;
963 
964 	case kAnimationModeCombatIdle:
965 		switch (_animationState) {
966 		case 0:
967 			_animationFrame = 0;
968 			_animationState = 16;
969 			break;
970 
971 		case 3:
972 			// fall through
973 		case 4:
974 			_animationState = 7;
975 			_animationFrame = 0;
976 			break;
977 
978 		case 7:
979 			// fall through
980 		case 16:
981 			// fall through
982 		case 18:
983 			return true;
984 
985 		case 17:
986 			_animationFrame = 0;
987 			_animationState = 7;
988 			break;
989 		default:
990 			_animationFrame = 0;
991 			_animationState = 16;
992 			break;
993 		}
994 		break;
995 
996 	case 5:
997 		// fall through
998 	case 9:
999 		// fall through
1000 	case 10:
1001 		// fall through
1002 	case 11:
1003 		// fall through
1004 	case 19:
1005 		// fall through
1006 	case 20:
1007 		return true;
1008 
1009 	case kAnimationModeCombatAttack:
1010 		_animationFrame = 0;
1011 		_animationState = 18;
1012 		break;
1013 
1014 	case kAnimationModeCombatWalk:
1015 		_animationFrame = 0;
1016 		_animationState = 3;
1017 		break;
1018 
1019 	case kAnimationModeCombatRun:
1020 		_animationFrame = 0;
1021 		_animationState = 4;
1022 		break;
1023 
1024 	case 12:
1025 		_animationState = 20;
1026 		_animationFrame = 0;
1027 		break;
1028 
1029 	case 13:
1030 		_animationState = 21;
1031 		_animationFrame = 0;
1032 		break;
1033 
1034 	case 14:
1035 		_animationState = 22;
1036 		_animationFrame = 0;
1037 		break;
1038 
1039 	case 15:
1040 		_animationState = 23;
1041 		_animationFrame = 0;
1042 		break;
1043 
1044 	case 16:
1045 		_animationState = 24;
1046 		_animationFrame = 0;
1047 		break;
1048 
1049 	case 17:
1050 		_animationState = 25;
1051 		_animationFrame = 0;
1052 		break;
1053 
1054 	case 18:
1055 		_animationState = 26;
1056 		_animationFrame = 0;
1057 		break;
1058 
1059 	case kAnimationModeHit:
1060 		switch (_animationState) {
1061 		case 7:
1062 			// fall through
1063 		case 8:
1064 			// fall through
1065 		case 9:
1066 			// fall through
1067 		case 16:
1068 			// fall through
1069 		case 17:
1070 			// fall through
1071 		case 18:
1072 			if (Random_Query(0, 1)) {
1073 				_animationState = 13;
1074 			} else {
1075 				_animationState = 12;
1076 			}
1077 			break;
1078 
1079 		case 10:
1080 			// fall through
1081 		case 11:
1082 			// fall through
1083 		case 12:
1084 			// fall through
1085 		case 13:
1086 			// fall through
1087 		case 14:
1088 			// fall through
1089 		case 15:
1090 			if (Random_Query(0, 1)) {
1091 				_animationState = 11;
1092 			} else {
1093 				_animationState = 10;
1094 			}
1095 			break;
1096 		}
1097 		_animationFrame = 0;
1098 		break;
1099 
1100 	case kAnimationModeCombatHit:
1101 		if (Random_Query(0, 1)) {
1102 			_animationState = 12;
1103 		} else {
1104 			_animationState = 13;
1105 		}
1106 		_animationFrame = 0;
1107 		break;
1108 
1109 	case 23:
1110 		_animationState = 27;
1111 		_animationFrame = 0;
1112 		break;
1113 
1114 	case kAnimationModeDie:
1115 		_animationState = 14;
1116 		_animationFrame = 0;
1117 		break;
1118 
1119 	case 62:
1120 		if (Actor_Query_Goal_Number(kActorSadik) != kGoalSadikBB11KnockOutMcCoy
1121 		 && Actor_Query_Goal_Number(kActorSadik) != kGoalSadikBB11KickMcCoy
1122 		) {
1123 			_animationState = 31;
1124 			_animationFrame = 0;
1125 		} else {
1126 			_animationState = 33;
1127 			_animationFrame = 0;
1128 		}
1129 		break;
1130 
1131 	case 63:
1132 		if (Actor_Query_Goal_Number(kActorSadik) != kGoalSadikBB11KnockOutMcCoy
1133 		 && Actor_Query_Goal_Number(kActorSadik) != kGoalSadikBB11KickMcCoy
1134 		) {
1135 			_animationState = 30;
1136 			_animationFrame = 2;
1137 		} else {
1138 			_animationState = 34;
1139 			_animationFrame = 2;
1140 		}
1141 		break;
1142 	}
1143 	return true;
1144 }
1145 
QueryAnimationState(int * animationState,int * animationFrame,int * animationStateNext,int * animationNext)1146 void AIScriptSadik::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
1147 	*animationState     = _animationState;
1148 	*animationFrame     = _animationFrame;
1149 	*animationStateNext = _animationStateNext;
1150 	*animationNext      = _animationNext;
1151 }
1152 
SetAnimationState(int animationState,int animationFrame,int animationStateNext,int animationNext)1153 void AIScriptSadik::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
1154 	_animationState     = animationState;
1155 	_animationFrame     = animationFrame;
1156 	_animationStateNext = animationStateNext;
1157 	_animationNext      = animationNext;
1158 }
1159 
ReachedMovementTrackWaypoint(int waypointId)1160 bool AIScriptSadik::ReachedMovementTrackWaypoint(int waypointId) {
1161 	return true;
1162 }
1163 
FledCombat()1164 void AIScriptSadik::FledCombat() {
1165 	// return false;
1166 }
1167 
1168 } // End of namespace BladeRunner
1169