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 #include "bladerunner/vector.h"
25 
26 namespace BladeRunner {
27 
28 enum kMaggieStates {
29 	kMaggieStateIdle         = 0,
30 	kMaggieStateWalking      = 1,
31 	kMaggieStateJumping      = 2,
32 	kMaggieStateHappyA       = 3,
33 	kMaggieStateHappyB       = 4,
34 	kMaggieStateLayingDown   = 5,
35 	kMaggieStateLayingIdle   = 6,
36 	kMaggieStateStandingUp   = 7,
37 	kMaggieStateGoingToSleep = 8,
38 	kMaggieStateSleeping     = 9,
39 	kMaggieStateWakingUp     = 10,
40 	kMaggieStateBombIdle     = 11,
41 	kMaggieStateBombWalk     = 12,
42 	kMaggieStateBombJumping  = 13,
43 	kMaggieStateExploding    = 14,
44 	kMaggieStateDeadExploded = 15,
45 	kMaggieStateDead         = 16
46 };
47 
AIScriptMaggie(BladeRunnerEngine * vm)48 AIScriptMaggie::AIScriptMaggie(BladeRunnerEngine *vm) : AIScriptBase(vm) {
49 	var_45F3F8 = 0;
50 	var_45F3FC = 0;
51 	var_45F400 = 0;
52 	var_45F404 = 0;
53 	var_45F408 = 0;
54 }
55 
Initialize()56 void AIScriptMaggie::Initialize() {
57 	_animationState = kMaggieStateIdle;
58 	_animationFrame = 0;
59 	_animationStateNext = 0;
60 	_animationNext = 0;
61 	var_45F3F8 = 0;
62 	var_45F3FC = 0;
63 	var_45F400 = 0;
64 	var_45F404 = 0;
65 	var_45F408 = 0;
66 	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Default);
67 }
68 
Update()69 bool AIScriptMaggie::Update() {
70 	int goal = Actor_Query_Goal_Number(kActorMaggie);
71 
72 	if (Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04
73 	 && Global_Variable_Query(kVariableChapter) == 4
74 	) {
75 		Actor_Put_In_Set(kActorMaggie, kSetFreeSlotG);
76 		Actor_Set_At_Waypoint(kActorMaggie, 39, 0);
77 	}
78 
79 	if (goal == kGoalMaggieKP05WillExplode) {
80 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Explode);
81 	} else if (goal == kGoalMaggieKP05WalkToMcCoy
82 	        && Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorMaggie) < 60
83 	) {
84 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Explode);
85 	}
86 
87 	if (Global_Variable_Query(kVariableChapter) == 5) {
88 		if (Actor_Query_Goal_Number(kActorMaggie) < 400) {
89 			Actor_Set_Goal_Number(kActorMaggie, 400);
90 		}
91 		return true;
92 	}
93 	return false;
94 }
95 
TimerExpired(int timer)96 void AIScriptMaggie::TimerExpired(int timer) {
97 	if (timer == kActorTimerAIScriptCustomTask0) {
98 		int goal = Actor_Query_Goal_Number(kActorMaggie);
99 		if (goal == kGoalMaggieMA02Wait) {
100 			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
101 			if (Random_Query(0, 4)) {
102 				AI_Movement_Track_Flush(kActorMaggie);
103 				AI_Movement_Track_Append(kActorMaggie, randomWaypointMA02(), 0);
104 				AI_Movement_Track_Repeat(kActorMaggie);
105 			} else {
106 				Actor_Change_Animation_Mode(kActorMaggie, 54);
107 			}
108 			return; //true
109 		}
110 
111 		if (goal == kGoalMaggieMA02SitDown) {
112 			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
113 			Actor_Change_Animation_Mode(kActorMaggie, 55);
114 			return; //true
115 		}
116 	}
117 	return; //false
118 }
119 
CompletedMovementTrack()120 void AIScriptMaggie::CompletedMovementTrack() {
121 	int goal = Actor_Query_Goal_Number(kActorMaggie);
122 	if (goal == 0 || goal > 9) {
123 		if (goal == kGoalMaggieKP05WalkToMcCoy) {
124 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WillExplode);
125 			return; //true
126 		}
127 	} else {
128 		if (goal == kGoalMaggieMA02WalkToEntrance) {
129 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
130 			return; //true
131 		}
132 
133 		if (goal == kGoalMaggieMA02Wait) {
134 			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
135 			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
136 			AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(1, 5));
137 			return; //true
138 		}
139 
140 		if (goal == 9) {
141 			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
142 			Actor_Change_Animation_Mode(kActorMaggie, 54);
143 			return; //true
144 		}
145 	}
146 	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
147 	return; //true
148 }
149 
ReceivedClue(int clueId,int fromActorId)150 void AIScriptMaggie::ReceivedClue(int clueId, int fromActorId) {
151 }
152 
ClickedByPlayer()153 void AIScriptMaggie::ClickedByPlayer() {
154 	if (!Game_Flag_Query(kFlagMcCoyIsHelpingReplicants)
155 	 &&  Global_Variable_Query(kVariableChapter) == 5
156 	) {
157 		if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieKP05WalkToMcCoy) {
158 			Actor_Set_Targetable(kActorMaggie, true);
159 			AI_Movement_Track_Flush(kActorMaggie);
160 			Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
161 			Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
162 		}
163 		return; // true
164 	}
165 
166 	if (_animationState == kMaggieStateDead) {
167 		return; // false
168 	}
169 
170 	Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
171 
172 	float mccoy_x, mccoy_y, mccoy_z;
173 	Actor_Query_XYZ(kActorMcCoy, &mccoy_x, &mccoy_y, &mccoy_z);
174 	if (distanceToActor(kActorMaggie, mccoy_x, mccoy_y, mccoy_z) > 60.0f) {
175 		Actor_Says(0, 2430, 18);
176 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
177 		return; // true
178 	}
179 
180 	int v6 = Random_Query(0, 4);
181 	if (v6 == 1) {
182 		Actor_Says(kActorMcCoy, 2440, 18);
183 	}
184 	if (v6 == 0) {
185 		Actor_Says(kActorMcCoy, 2435, 13);
186 	}
187 
188 	int goal = Actor_Query_Goal_Number(kActorMaggie);
189 	if (goal == kGoalMaggieMA02Wait) {
190 		if (Random_Query(0, 1)) {
191 			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
192 			Actor_Change_Animation_Mode(kActorMaggie, 57);
193 		} else {
194 			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
195 			Actor_Change_Animation_Mode(kActorMaggie, 56);
196 		}
197 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
198 		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(3, 9));
199 		return; // true
200 	}
201 
202 	if (goal == 10) {
203 		Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
204 		return; // true
205 	}
206 
207 	if (goal == 11) {
208 		Actor_Change_Animation_Mode(kActorMaggie, 54);
209 		return; // true
210 	}
211 
212 	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
213 	return; // true
214 }
215 
EnteredScene(int sceneId)216 void AIScriptMaggie::EnteredScene(int sceneId) {
217 }
218 
OtherAgentEnteredThisScene(int otherActorId)219 void AIScriptMaggie::OtherAgentEnteredThisScene(int otherActorId) {
220 }
221 
OtherAgentExitedThisScene(int otherActorId)222 void AIScriptMaggie::OtherAgentExitedThisScene(int otherActorId) {
223 	if (otherActorId == kActorMcCoy
224 	 && Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04
225 	 && Global_Variable_Query(kVariableChapter) < 4
226 	) {
227 		AI_Movement_Track_Flush(kActorMaggie);
228 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Default);
229 	}
230 }
231 
OtherAgentEnteredCombatMode(int otherActorId,int combatMode)232 void AIScriptMaggie::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
233 }
234 
ShotAtAndMissed()235 void AIScriptMaggie::ShotAtAndMissed() {
236 }
237 
ShotAtAndHit()238 bool AIScriptMaggie::ShotAtAndHit() {
239 	AI_Movement_Track_Flush(kActorMaggie);
240 	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WillExplode);
241 	Actor_Set_Targetable(kActorMaggie, false);
242 	return false;
243 }
244 
Retired(int byActorId)245 void AIScriptMaggie::Retired(int byActorId) {
246 }
247 
GetFriendlinessModifierIfGetsClue(int otherActorId,int clueId)248 int AIScriptMaggie::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
249 	return 0;
250 }
251 
GoalChanged(int currentGoalNumber,int newGoalNumber)252 bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
253 	if (currentGoalNumber == kGoalMaggieDead) {
254 		return true;
255 	}
256 
257 	switch (newGoalNumber) {
258 	case kGoalMaggieMA02Default:
259 		Actor_Put_In_Set(kActorMaggie, kSetMA02_MA04);
260 		Actor_Set_At_Waypoint(kActorMaggie, 265, 780);
261 		return true;
262 
263 	case kGoalMaggieMA02WalkToEntrance:
264 		Actor_Put_In_Set(kActorMaggie, kSetMA02_MA04);
265 		Actor_Set_At_Waypoint(kActorMaggie, randomWaypointMA02(), 512);
266 		AI_Movement_Track_Flush(kActorMaggie);
267 		AI_Movement_Track_Append(kActorMaggie, 264, 0);
268 		AI_Movement_Track_Repeat(kActorMaggie);
269 		return true;
270 
271 	case kGoalMaggieMA02GetFed:
272 		Player_Loses_Control();
273 		AI_Movement_Track_Flush(kActorMaggie);
274 #if BLADERUNNER_ORIGINAL_BUGS
275 #else
276 		// Allows McCoy to perform both animated turns (first towards the BAR-MAIN and then towards Maggie)
277 		// when Maggie is already too close
278 		// original bug: When Maggie is close McCoy would alternate between
279 		// - turning to Maggie and throw food at her
280 		// - only performing the turn toward the BAR-MAIN and "throw" food to wrong direction
281 		if (Actor_Query_Inch_Distance_From_Actor(kActorMaggie, kActorMcCoy) <= 85) {
282 			Delay(500);
283 		}
284 #endif // BLADERUNNER_ORIGINAL_BUGS
285 		Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 48, false, false);
286 		Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
287 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, false);
288 		Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
289 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
290 		Player_Gains_Control();
291 		return true;
292 
293 	case kGoalMaggieMA02WalkToMcCoy:
294 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
295 		AI_Movement_Track_Flush(kActorMaggie);
296 		Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 30, false, false);
297 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
298 		Actor_Change_Animation_Mode(kActorMaggie, 56);
299 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
300 		return true;
301 
302 	case kGoalMaggieMA02Wait:
303 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
304 		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(3, 9));
305 		return true;
306 
307 	case 9:
308 		if (Random_Query(0, 2) <= 0) {
309 			Actor_Face_Actor(kActorMaggie, kActorMcCoy, false);
310 			Actor_Change_Animation_Mode(kActorMaggie, 54);
311 		} else {
312 			AI_Movement_Track_Flush(kActorMaggie);
313 			if (Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04) {
314 				AI_Movement_Track_Append(kActorMaggie, randomWaypointMA02(), 486);
315 			}
316 			AI_Movement_Track_Repeat(kActorMaggie);
317 		}
318 		return true;
319 
320 	case kGoalMaggieMA02SitDown:
321 		Actor_Change_Animation_Mode(kActorMaggie, 54);
322 		_animationState = kMaggieStateLayingIdle;
323 		_animationFrame = 0;
324 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
325 		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(2, 9));
326 		return true;
327 
328 	case kGoalMaggieMA02Sleep:
329 		Actor_Change_Animation_Mode(kActorMaggie, 55);
330 		_animationState = kMaggieStateSleeping;
331 		_animationFrame = 0;
332 		return true;
333 
334 	case 400:
335 		Actor_Set_Goal_Number(kActorMaggie, 410);
336 		break;
337 
338 	case kGoalMaggieKP05Wait:
339 		AI_Movement_Track_Flush(kActorMaggie);
340 		Game_Flag_Set(kFlagMaggieHasBomb);
341 		Actor_Put_In_Set(kActorMaggie, kSetKP05_KP06);
342 		Actor_Set_At_XYZ(kActorMaggie, -672.0, 0.0, -428.0, 653);
343 		Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
344 		break;
345 
346 	case kGoalMaggieKP05McCoyEntred:
347 		Scene_Exits_Disable();
348 		Loop_Actor_Walk_To_XYZ(kActorMaggie, -734.0, 0.0, -432.0, 0, false, false, false);
349 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
350 		Actor_Change_Animation_Mode(kActorMaggie, 56);
351 		Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
352 		Actor_Says(kActorMcCoy, 2225, kAnimationModeTalk);
353 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WalkToMcCoy);
354 		break;
355 
356 	case kGoalMaggieKP05WalkToMcCoy:
357 		if (Actor_Query_Is_In_Current_Set(kActorSteele)) {
358 			Actor_Says(kActorSteele, 3270, 59);
359 		}
360 		AI_Movement_Track_Flush(kActorMaggie);
361 		AI_Movement_Track_Append(kActorMaggie, 540, 0);
362 		AI_Movement_Track_Repeat(kActorMaggie);
363 		break;
364 
365 	case kGoalMaggieKP05Explode:
366 		AI_Movement_Track_Flush(kActorMaggie);
367 		Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
368 		Sound_Play(kSfxDOGEXPL1, 50, 0, 0, 100);
369 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieDead);
370 		Actor_Change_Animation_Mode(kActorMaggie, 51);
371 		if (Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorMaggie) < 144) {
372 			Player_Loses_Control();
373 			Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
374 			Actor_Retired_Here(kActorMcCoy, 6, 6, 1, -1);
375 		} else {
376 			Delay(3000);
377 			Scene_Exits_Disable();
378 			Actor_Says(kActorMcCoy, 2235, 12);
379 			if (Actor_Query_Is_In_Current_Set(kActorSteele)) {
380 				Actor_Says(kActorSteele, 1530, 58);
381 				Actor_Set_Goal_Number(kActorSteele, kGoalSteeleKP05Leave);
382 			}
383 			Delay(2000);
384 			Actor_Says(kActorMcCoy, 2390, 13);
385 			if (Actor_Query_Goal_Number(kActorSadik) == 411) {
386 				Actor_Set_Goal_Number(kActorSadik, 412);
387 			} else { // there is no way how Maggie can explode and Sadik's goal is not 411
388 				Actor_Set_Goal_Number(kActorClovis, kGoalClovisKP06TalkToMcCoy);
389 			}
390 		}
391 		break;
392 
393 	}
394 	return false;
395 }
396 
UpdateAnimation(int * animation,int * frame)397 bool AIScriptMaggie::UpdateAnimation(int *animation, int *frame) {
398 	int goal;
399 	switch (_animationState) {
400 	case kMaggieStateDead:
401 		*animation = 871;
402 		_animationFrame = 0;
403 		break;
404 
405 	case kMaggieStateDeadExploded:
406 		*animation = 874;
407 		_animationFrame = Slice_Animation_Query_Number_Of_Frames(874) - 1;
408 		break;
409 
410 	case kMaggieStateExploding:
411 		*animation = 874;
412 		_animationFrame++;
413 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(874) - 1) {
414 			_animationState = kMaggieStateDeadExploded;
415 			_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
416 			Actor_Put_In_Set(kActorMaggie, kSetFreeSlotI);
417 			Actor_Set_At_Waypoint(kActorMaggie, 41, 0);
418 		}
419 		break;
420 
421 	case kMaggieStateBombJumping:
422 		*animation = 873;
423 		_animationFrame++;
424 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(873)) {
425 			_animationState = kMaggieStateBombIdle;
426 			_animationFrame = 0;
427 			*animation = 875;
428 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WillExplode);
429 		}
430 		break;
431 
432 	case kMaggieStateBombWalk:
433 		*animation = 872;
434 		_animationFrame++;
435 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(872)) {
436 			_animationFrame = 0;
437 		}
438 		break;
439 
440 	case kMaggieStateBombIdle:
441 		*animation = 875;
442 		_animationFrame++;
443 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(875)) {
444 			_animationFrame = 0;
445 		}
446 		break;
447 
448 	case kMaggieStateWakingUp:
449 		*animation = 876;
450 		_animationFrame--;
451 		if (_animationFrame > 0) {
452 			break;
453 		}
454 		_animationState = kMaggieStateLayingIdle;
455 		_animationFrame = 0;
456 		*animation = 867;
457 		goal = Actor_Query_Goal_Number(kActorMaggie);
458 		if (goal == kGoalMaggieMA02GetFed) {
459 			_animationState = kMaggieStateStandingUp;
460 			_animationFrame = 0;
461 			*animation = 868;
462 		} else if (goal == kGoalMaggieMA02WalkToMcCoy) {
463 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
464 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
465 		} else {
466 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
467 		}
468 		break;
469 
470 	case kMaggieStateSleeping:
471 		*animation = 876;
472 		_animationFrame = Slice_Animation_Query_Number_Of_Frames(876) - 1;
473 		break;
474 
475 	case kMaggieStateGoingToSleep:
476 		*animation = 876;
477 		_animationFrame++;
478 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(876) - 1) {
479 			_animationState = kMaggieStateSleeping;
480 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Sleep);
481 		}
482 		break;
483 
484 	case kMaggieStateStandingUp:
485 		*animation = 868;
486 		_animationFrame++;
487 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(868)) {
488 			*animation = 864;
489 			_animationState = kMaggieStateIdle;
490 			_animationFrame = 0;
491 			if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDown) {
492 				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
493 			} else if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02WalkToMcCoy) {
494 				Actor_Set_Goal_Number(kActorMaggie, 12); // this is never used
495 				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
496 			}
497 		}
498 		break;
499 
500 	case kMaggieStateLayingIdle:
501 		*animation = 867;
502 		_animationFrame++;
503 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(867)) {
504 			_animationFrame = 0;
505 		}
506 		break;
507 
508 	case kMaggieStateLayingDown:
509 		*animation = 866;
510 		_animationFrame++;
511 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(866)) {
512 			_animationState = kMaggieStateLayingIdle;
513 			_animationFrame = 0;
514 			*animation = 867;
515 			if (Actor_Query_Goal_Number(kActorMaggie) == 9) {
516 				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
517 			}
518 		}
519 		break;
520 
521 	case kMaggieStateHappyB:
522 		*animation = 865;
523 		_animationFrame++;
524 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(865)) {
525 			_animationFrame = 0;
526 			var_45F3F8--;
527 			if (var_45F3F8 <= 0) {
528 				Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
529 				*animation = 864;
530 			}
531 		}
532 		break;
533 
534 	case kMaggieStateHappyA:
535 		*animation = 870;
536 		if (_animationFrame == 1) {
537 			// one of kSfxDOGBARK1, kSfxDOGBARK3
538 			Sound_Play(Random_Query(kSfxDOGBARK1, kSfxDOGBARK3), 50, 0, 0, 50);
539 		}
540 		_animationFrame++;
541 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
542 			var_45F3FC--;
543 			if (var_45F3FC <= 0) {
544 				Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
545 				*animation = 864;
546 				_animationState = kMaggieStateIdle;
547 			}
548 			_animationFrame = 0;
549 		}
550 		break;
551 
552 	case kMaggieStateJumping:
553 		*animation = 869;
554 		_animationFrame++;
555 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(869)) {
556 			Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
557 			*animation = 864;
558 			_animationState = kMaggieStateIdle;
559 			_animationFrame = 0;
560 		}
561 		break;
562 
563 	case kMaggieStateWalking:
564 		*animation = 863;
565 		_animationFrame++;
566 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(863)) {
567 			_animationFrame = 0;
568 		}
569 		break;
570 
571 	case kMaggieStateIdle:
572 		*animation = 864;
573 		_animationFrame++;
574 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(864)) {
575 			_animationFrame = 0;
576 		}
577 		break;
578 	}
579 	*frame = _animationFrame;
580 	return true;
581 }
582 
ChangeAnimationMode(int mode)583 bool AIScriptMaggie::ChangeAnimationMode(int mode) {
584 	if (mode == kAnimationModeWalk) {
585 		if (Game_Flag_Query(kFlagMaggieHasBomb)) {
586 			_animationState = kMaggieStateBombWalk;
587 			_animationFrame = 0;
588 		} else {
589 			_animationState = kMaggieStateWalking;
590 			_animationFrame = 0;
591 		}
592 		return true;
593 	}
594 	if (mode == kAnimationModeIdle) {
595 		if (Game_Flag_Query(kFlagMaggieHasBomb)) {
596 			_animationState = kMaggieStateBombIdle;
597 			_animationFrame = kMaggieStateIdle;
598 		} else {
599 			switch (_animationState) {
600 			case kMaggieStateGoingToSleep:
601 			case kMaggieStateSleeping:
602 				_animationState = kMaggieStateWakingUp;
603 				break;
604 			case kMaggieStateIdle:
605 				_animationState = kMaggieStateStandingUp;
606 				_animationFrame = 0;
607 				break;
608 			case kMaggieStateLayingDown:
609 				_animationState = kMaggieStateStandingUp;
610 				_animationFrame = 0;
611 				break;
612 			case kMaggieStateJumping:
613 			case kMaggieStateStandingUp:
614 			case kMaggieStateWakingUp:
615 				break;
616 			default:
617 				_animationState = kMaggieStateIdle;
618 				_animationFrame = 0;
619 				break;
620 			}
621 		}
622 		return true;
623 	}
624 
625 	switch (mode) {
626 	case 51:
627 		_animationState = kMaggieStateExploding;
628 		_animationFrame = 0;
629 		Sound_Play(kSfxDOGHURT1, 50, 0, 0, 50);
630 		break;
631 
632 	case kAnimationModeFeeding:
633 		if (Game_Flag_Query(kFlagMaggieHasBomb)) {
634 			_animationState = kMaggieStateBombJumping;
635 			_animationFrame = 0;
636 		} else {
637 			_animationState = kMaggieStateJumping;
638 			_animationFrame = 0;
639 		}
640 		break;
641 
642 	case 54:
643 		if (_animationState <= kMaggieStateSleeping) {
644 			if (_animationState > 0) {
645 				if (_animationState == kMaggieStateSleeping) {
646 					_animationState = kMaggieStateWakingUp;
647 					_animationFrame = 0;
648 				}
649 			} else {
650 				_animationState = kMaggieStateLayingDown;
651 				_animationFrame = 0;
652 			}
653 		}
654 		break;
655 
656 	case 55:
657 		if (_animationState == kMaggieStateLayingIdle) {
658 			_animationState = kMaggieStateGoingToSleep;
659 			_animationFrame = 0;
660 		}
661 		break;
662 
663 	case 56:
664 		if (_animationState != 3) {
665 			_animationFrame = 0;
666 			_animationState = kMaggieStateHappyA;
667 		}
668 		var_45F3FC = Random_Query(2, 6);
669 		break;
670 
671 	case 57:
672 		if (_animationState != kMaggieStateHappyB) {
673 			_animationFrame = 0;
674 			_animationState = kMaggieStateHappyB;
675 		}
676 		var_45F3F8 = Random_Query(2, 6);
677 		Sound_Play(kSfxDOGTAIL1, 50, 0, 0, 50);
678 		break;
679 
680 	case 88:
681 		_animationState = kMaggieStateDead;
682 		_animationFrame = 0;
683 		break;
684 
685 	}
686 	return true;
687 }
688 
QueryAnimationState(int * animationState,int * animationFrame,int * animationStateNext,int * animationNext)689 void AIScriptMaggie::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
690 	*animationState     = _animationState;
691 	*animationFrame     = _animationFrame;
692 	*animationStateNext = _animationStateNext;
693 	*animationNext      = _animationNext;
694 }
695 
SetAnimationState(int animationState,int animationFrame,int animationStateNext,int animationNext)696 void AIScriptMaggie::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
697 	_animationState     = animationState;
698 	_animationFrame     = animationFrame;
699 	_animationStateNext = animationStateNext;
700 	_animationNext      = animationNext;
701 }
702 
ReachedMovementTrackWaypoint(int waypointId)703 bool AIScriptMaggie::ReachedMovementTrackWaypoint(int waypointId) {
704 	return true;
705 }
706 
FledCombat()707 void AIScriptMaggie::FledCombat() {
708 }
709 
randomWaypointMA02()710 int AIScriptMaggie::randomWaypointMA02() {
711 	switch (Random_Query(0, 3)) {
712 	case 0:
713 		return 264;
714 
715 	case 1:
716 		return 265;
717 
718 	case 2:
719 		return 266;
720 
721 	default:
722 		return 267;
723 	}
724 }
725 
distanceToActor(int actorId,float x,float y,float z)726 float AIScriptMaggie::distanceToActor(int actorId, float x, float y, float z) {
727 	float actorX, actorY, actorZ;
728 	Actor_Query_XYZ(actorId, &actorX, &actorY, &actorZ);
729 	return sqrt(static_cast<float>((z - actorZ) * (z - actorZ) + (y - actorY) * (y - actorY) + (x - actorX) * (x - actorX)));
730 }
731 
732 } // End of namespace BladeRunner
733