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